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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿
. S$ G9 E0 ^2 ~7 `4 Y* |
6 y% \7 Z& ]6 @9 d      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。
. V0 C" Q+ N/ S4 f/ ^
( c3 x& p  ]9 u, z2 q( ]) {0×02 写在前面的话5 Q: {6 b+ d5 s

, M/ e( D' n3 }6 Q' O+ C4 l    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
9 r0 s) x, _) Z# p7 P4 f8 Y# |  U; U$ N* N8 G* T, P# c
这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
6 ~7 B$ S% B. p' C7 P# j1 X$ f/ A# v& ^$ Y
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论
3 v4 I+ V4 y+ ?0 [% G
/ D8 L& e3 u) g* l/ f7 C# q0×03 路径? ? ?7 T6 ?" S8 Z/ |1 f
6 T# g0 I9 m) C1 i
    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件" w: k; u. _6 j6 M" o3 x

( }# b1 f1 B% c' A$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])); } # ?0 d- i' Q. x9 l" l% _

# @8 U4 v- `# z这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的
+ Y! L% E& r/ e- R+ @; ^
1 O& b" O. h2 D2 z! I2 y+ J然后就是将我们传进来的参数进行变量化9 ^% o. P3 z' J% @$ y- H- c

) {# D! r* X+ O$ G* Z# ~这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
/ T/ Q7 _( a8 x: K, s; L% q( E1 c) U& l& `6 W9 s4 S  R1 l8 I
但是接下来这行呢?
5 {. h0 r- c4 ]; ^- u2 M3 m) T  F. V' }1 P& J* \1 H7 }

1 r- c8 h  x" t; P$ T9 ?% w& @, I) t4 ]
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 X7 w9 W- Q/ u0 n7 n
& Z! [! h' I7 g1 H5 Q# g" A 3 d# z- O6 y: U" S

9 H" r1 d+ q) }# R# |. ]  |看看这里?* [- B3 k+ B  k5 X

$ U& }6 G* F, F6 v! j; r, j这里的QUERY_STRING来自前面$ ^4 x/ g  R5 N/ V
# k  I8 A8 y, D  ?& }( }# a

/ Y, A6 A9 b  I. T% \) o+ \5 @  a( N* O& j# r0 a  k
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']));
% @" `; J0 m- L& ?' X这里有个过滤,但是不影响% H1 w( h' j' s% E2 k# B  [$ G4 v8 a

( C" R2 E. W( ^如果我们在这里进行覆盖这个db变量呢7 G4 p+ i0 g; `. @) n
7 b' e/ W1 d  \. _& `4 c6 |8 A
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
- ?0 G- V, j( e8 t' g! Z) t% I: h& l
可以将我们传进去的/ - 进行替换( L) Q# b" X& x3 m

  y6 Y- e4 I* e所以我们如果提交如下字符
! F; J6 L1 P2 y3 u* Q
6 l, s5 P8 L3 {3 {2 Shttp://localhost/phpcms/index.php?db-5/gid-xd.html
- f1 Y; z* c0 P, v( \' t5 J2 [! [
* i5 l3 I: @( X他由于这个db被覆盖就会出错,所以物理路径就爆出来了7 d9 Y  V: z' ]+ G
. ?9 `, s$ ~. t, O7 f7 T
0×04  SQL注入!!!
* j; T/ B- N1 Z/ ?5 W: a5 j
" q) ?0 o( ]* G  在c.php中
/ ^; i; r. c" Y
9 Q3 _2 Z2 R2 s6 H5 L4 m
/ c/ {% C  ], n3 s; Z! R/ V4 |2 ~* `. z) A
<?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']; }
9 H  Z" Z- U& c; j2 w  n7 C* [& ?# b" F  c1 s  m2 p

5 t) m$ H3 H' o  b6 d, R3 C4 T
$ b( w( p3 x$ r" P6 q4 E注意这里的HTTP_REFERER这个常量
8 c' e) t# r: w$ p
6 A! |1 x6 E' f: e  q这里的常量是通过前面的common.inc.php定义好的. r9 B( M# A* u4 j* x

# X, R6 ?5 {, @5 w9 gdefine(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);
$ o3 B% _1 V6 C: z4 c% Y0 {7 F* _8 c! Z& l- g) D  F, \
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我! a4 I8 d& Q5 |2 A. ]. ~! s* j  j/ j
" D) G" s5 [2 n: G4 V/ C6 N) R
然后
$ L- m% d2 O& O6 a* T) a8 W
3 A; L, f/ \5 _$db->insert($table, $info);2 J' B% V0 v2 M& n
我们来看一下它这里的操作" q8 ?4 v4 z: U8 C

0 ^" J8 k& ?9 X. {2 d' y; [function insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); } + f9 n7 j8 R3 G/ P

$ \+ {: g/ `- }$ a5 F$ H- y所以你懂的
  X  G& @1 Q) q! V; q, {& N
/ [* o6 o8 q& |+ d+ a( J# b ; o( X& E5 m; J$ d' t* A

: Z5 o* y7 |5 }# ]) X) L附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737( B% d% d5 |" V( e1 c

% ]; T* x5 W. q+ h  F
1 C& |/ S( @0 U
4 J" |  q) J- }* T2 ?
回复

使用道具 举报

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

本版积分规则

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