找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 2181|回复: 0
打印 上一主题 下一主题

PHPCMS 2008 最新漏洞之通杀注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿
: k3 o$ u* c2 m/ ]
! W( O2 H9 {& o" f      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。+ q! V$ W: _( C

* A2 d( o0 _/ m8 g# D0×02 写在前面的话: }- {  u1 |4 A) i  H  h
' `" l3 G, K  f6 u; e
    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
2 |- U5 U% Q* r& W2 _( H
1 n% [& y: d2 ~" I+ p7 I; ^这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
2 f4 C' w4 O3 T5 Z* ]) ?1 `& q) M
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论
& G! `/ Y3 X. _0 E, j8 ^. W
, {0 T5 m% y1 n4 j2 @& p0×03 路径? ? ?% l$ N# q/ q( \  o1 v8 Z- C5 b6 g
, i0 z$ C/ A& l' J
    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件7 K- {% L. K7 p9 r; r

; R$ j' u4 ]9 @$dbclass = 'db_'.DB_DATABASE; require $dbclass.'.class.php'; $db = new $dbclass; $db->connect(DB_HOST, DB_USER, DB_PW, DB_NAME, DB_PCONNECT, DB_CHARSET); require 'session_'.SESSION_STORAGE.'.class.php'; $session = new session(); session_set_cookie_params(0, COOKIE_PATH, COOKIE_DOMAIN); if($_REQUEST) { if(MAGIC_QUOTES_GPC) { $_REQUEST = new_stripslashes($_REQUEST); if($_COOKIE) $_COOKIE = new_stripslashes($_COOKIE); extract($db->escape($_REQUEST), EXTR_SKIP); } else { $_POST = $db->escape($_POST); $_GET = $db->escape($_GET); $_COOKIE = $db->escape($_COOKIE); @extract($_POST,EXTR_SKIP); @extract($_GET,EXTR_SKIP); @extract($_COOKIE,EXTR_SKIP); } if(!defined('IN_ADMIN')) $_REQUEST = filter_xss($_REQUEST, ALLOWED_HTMLTAGS); if($_COOKIE) $db->escape($_COOKIE); } if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } 3 c0 x& d  Y' I5 S- c
! }+ G3 P: w  t; h- Y; I$ V
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的
3 C) O% v/ ~/ ]8 G$ i
+ d8 l; r0 t) q5 s( \- Q然后就是将我们传进来的参数进行变量化
; m1 L/ M  T% x- h# L' r# _
/ }0 a2 S0 i4 F& ^: }/ V" p这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量( \# H, \* y. J6 ^. v. `/ E! w8 m
6 l+ }& {: E/ M$ i5 e
但是接下来这行呢?
7 a9 ^0 [+ t7 ~6 B
0 u* b7 d7 B% C( I3 Y
* r  }$ r2 T& X) E3 P0 K% ^" ?
% R6 X3 F/ `! w% h. Z) eif(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); }
7 V' m4 e% A5 i( [! s9 R0 o& \: b8 y
- [. C, {5 ^1 H6 g0 E: h

( P2 Z7 e8 S6 T, q7 n2 D看看这里?
3 b7 u' r( z8 t  _& `4 ^3 [/ s* G4 {8 u
这里的QUERY_STRING来自前面
8 y2 T! Q' J& P! w* u2 _2 W4 ?+ T3 w9 Z7 y8 T& [4 V& l8 e, j

6 f1 ]: V+ g2 I" R* N5 O0 ?) |% A3 i5 Z2 {
define('IP', ip()); define('HTTP_REFERER', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''); define('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : preg_replace("/(.*)\.php(.*)/i", "\\1.php", $_SERVER['PHP_SELF'])); define('QUERY_STRING', safe_replace($_SERVER['QUERY_STRING']));6 w; r6 P0 f+ d1 r) L6 Y
这里有个过滤,但是不影响
: T# w: R  N. H2 G
* n5 M6 P, O1 O3 T+ w. ?* @+ q如果我们在这里进行覆盖这个db变量呢
3 ]; l' u6 n! t$ k/ N: F* c
( X4 i. X1 X8 B: c5 h因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));7 }- y6 ^) g$ a2 J4 y3 v
  V  b( _0 f' Y- f+ `& H/ X$ |8 S
可以将我们传进去的/ - 进行替换
' Q- V9 |+ W' v: }8 w2 O( L) F' {3 s! Z" I+ u& @( B- J
所以我们如果提交如下字符0 @9 b0 y3 v9 r  N& Y9 F& g. x

6 x8 W$ V7 ^9 f: Z" [/ W; uhttp://localhost/phpcms/index.php?db-5/gid-xd.html, t- W& B9 Q7 [3 V

0 U% y, e9 b5 {2 Q0 L9 m4 H他由于这个db被覆盖就会出错,所以物理路径就爆出来了
9 p3 s# Y0 u' w3 G0 S. `" Z$ Q0 F  J$ i) V/ G$ s
0×04  SQL注入!!!+ J' [7 i! N3 z6 D
  B0 ~- H2 [3 E8 c
  在c.php中
/ s4 B  n6 u  D+ J/ T4 S) _( O
' p9 g! O* ?- d% B & x) \9 J+ v7 j; E8 z
/ ~' s: j( \( M  j6 t3 P' [- d
<?php require './ads/include/common.inc.php'; $id = intval($id); $ads = $c_ads->get_info($id); if($ads) { $db->query("UPDATE ".DB_PRE."ads SET `clicks`=clicks+1 WHERE adsid=".$ads['adsid']); $info['username'] = $_username; $info['clicktime'] = time(); $info['ip'] = IP; $info['adsid'] = $id; $info['referer'] = HTTP_REFERER; $year = date('ym',TIME); $table = DB_PRE.'ads_'.$year; $table_status = $db->table_status($table); if(!$table_status) { include MOD_ROOT.'include/create.table.php'; } $db->insert($table, $info); $url = strpos($ads['linkurl'], 'http://')===FALSE ? 'http://'.$ads['linkurl'] : $ads['linkurl']; }
* H$ t! e  G) i; G' E  m
3 y6 n- M6 x; H% U. V ' b7 f( H! a# \1 Y

3 `( ^! f: j$ z% ^; j/ k* y7 b6 H注意这里的HTTP_REFERER这个常量
% D$ q* _' X9 Z1 `# \) a; _3 z2 l0 G- D7 P" ^
这里的常量是通过前面的common.inc.php定义好的# K+ g$ v0 V1 b1 Q5 W+ X" ?+ L
5 t. m  Z1 @7 ^
define(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);
  K5 b: R  _& m8 N4 K% x' N) O/ ]
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我3 i/ o5 G' M; R$ D0 y
, O6 _& }  Y/ w3 S8 ]
然后. d  t. S- f8 N# b6 Y5 Z

6 u$ e( y8 L& W4 X8 H; t$db->insert($table, $info);
# A8 u" c% j7 d% E5 K我们来看一下它这里的操作0 m( D9 M/ n  p1 m8 ^( `2 b4 @4 d, Y
& A7 q1 j5 A6 v" f
function insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
1 E4 O4 ^% g- y$ v$ |7 ?: D  d% m* U& C
所以你懂的
# Z  x4 R) D) M( e4 `7 o; r" y6 F6 `

; w2 z/ K9 c) S+ Q% e$ I
# l1 h) u8 p3 _' u8 [" l附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737
9 c/ ~) G3 E% R) L8 S5 [2 \, J- V* v

- X8 B; S$ X+ e1 H  f/ D! ?4 t7 p  `! A  ^7 o
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表