中国网络渗透测试联盟

标题: PHPCMS 2008 最新漏洞之通杀注入漏洞 [打印本页]

作者: admin    时间: 2013-3-25 20:43
标题: PHPCMS 2008 最新漏洞之通杀注入漏洞
0×01 前沿- N* P4 j5 v" m! F6 e" `

/ o9 U  ~/ i* C  I. h      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。
/ |6 P8 ?. m; ?# x  q5 D
* o& n% i% i8 I4 h0×02 写在前面的话! n4 c# d/ h3 q) v
; R, C) ?) A  L3 ?
    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题& R1 t8 a5 _9 E

9 a* `2 y) C3 c! r这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
3 q+ c4 g. O( @3 d$ ]  n$ [: u- ]- s1 g
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论: `) d; T8 \+ ^! D+ ^
# t3 T$ i1 j* l! r& I1 F
0×03 路径? ? ?
4 ?& w' k2 ]' f. u$ b- Z: |) X
! o) ~( O! x0 R/ i    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件; L# Y/ R8 k; A7 o* ^( @2 ]4 L

' m+ {" j* J/ f$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])); }
8 ?6 W# @3 u0 w' w
& R' F/ p, F% q2 T! U5 F这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的% r* r  M9 \  t8 b2 V, Q! x* e2 p

3 u, f9 n! g5 K9 O+ f0 \7 {6 a  O然后就是将我们传进来的参数进行变量化
7 G9 C  r0 d2 Z. k. M, U9 f0 X( {& V0 I3 C3 m
这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量$ [3 `, M' b  _6 V' m
' F! g; c- E# b9 B
但是接下来这行呢?: H# i7 t4 g1 ?2 y& }! @; ^6 C
# ]& f: q, b1 Z1 N+ Z5 U

, F1 ~+ O& s' W9 j. v
. g; J" G: [% ~4 j( P! @0 _4 I) D, `if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); }
! ^5 G$ V) X! O5 E9 s2 H) J/ S' X# h, T- S4 ]8 L/ c% I

% E  G3 n0 C3 S8 c  d0 o8 l& F6 L
看看这里?! w! j. g) D7 P
  {' N5 y& o5 V9 F7 z
这里的QUERY_STRING来自前面* O1 R* \+ j# O! ]/ t; ~  s

. ~% o9 z; Z- W3 R7 [# ^% [9 w: e: X
- P2 ?6 e; b! c. @  L( b4 f% K1 h+ M& N' Z5 t
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']));
; E- w% z6 c% [" H% ?, X+ ^这里有个过滤,但是不影响! U$ |* E' @' z. ^' ?7 N' N* ?6 }
0 g* l4 V' p! J+ [  i+ O0 E- d
如果我们在这里进行覆盖这个db变量呢; K/ t4 l/ {, x3 [3 k! J

9 s9 U" V  o) l因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));) B- p2 o* \* \5 W* L
" ^4 Y! C& i. R
可以将我们传进去的/ - 进行替换- s# s' g3 `0 y$ S2 m" m1 A
+ w$ d- n% U: j+ p2 {7 n3 {4 s- J
所以我们如果提交如下字符* k% _* D( z2 S  N

; D! a/ m6 w+ J1 u; X1 [http://localhost/phpcms/index.php?db-5/gid-xd.html/ c8 T1 e' k& F6 @( k2 M! A

4 r' |" S' V) q: _4 p他由于这个db被覆盖就会出错,所以物理路径就爆出来了. o" G0 C) i6 l
" Y/ Y$ a: i  O! n9 Y" ^
0×04  SQL注入!!!' K. T, {7 k/ r! T# n; o. b
8 V, L/ Q5 D0 K& U. `% N
  在c.php中
! N6 G4 W( m7 h3 u& }  F, v: M
9 R! s; z+ C+ ~3 K/ V  L2 n
# U- w! T+ w! \5 Z. S& j& Z  m  @/ P1 g
<?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']; } * ]2 v  p. U, o8 s2 e6 g7 q
: c1 L9 v- M% R" q
0 K9 a# |" k' E
4 C4 G  Q4 \# y$ a# _
注意这里的HTTP_REFERER这个常量  Z6 x  [. ^8 x, A6 g: D

1 o5 w2 |$ ]& k# U这里的常量是通过前面的common.inc.php定义好的) P5 p$ z$ O4 b# W2 L0 I; l

+ [9 S9 ]! x( Z' D3 B& \- ]4 x0 wdefine(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);
: G( b2 ~" L- W; P# @- G/ b5 o
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我! E8 _3 P/ `4 B5 \/ U
, i& ?# {, U0 ~
然后) O7 B: ^/ t9 _% d7 e# F3 b2 ~

7 r  T+ s5 G& A) M% i: U$db->insert($table, $info);
  V' d6 U- |) l/ N( L我们来看一下它这里的操作
$ S3 g& S" g0 }3 a6 O+ ]
9 D$ Q( D) q! l8 [( nfunction insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
7 `4 L5 I" ?: j. q9 g; D9 B0 v: G2 i& P4 y- b
所以你懂的$ y9 }2 [$ _, n
% g6 m/ U3 l6 k# k/ i; n( ]6 ~8 W

+ g/ b$ d9 [1 X- z  |& r3 n- x7 `2 W1 d6 U! x/ D& I" Y/ _* h7 u
附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737
! N) [+ K5 R$ q6 c8 b* `- s, R4 O' w

4 [; o" k% u% {! R6 r* c2 K- f) f$ S6 n9 \





欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/) Powered by Discuz! X3.2