中国网络渗透测试联盟

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

作者: admin    时间: 2013-3-25 20:43
标题: PHPCMS 2008 最新漏洞之通杀注入漏洞
0×01 前沿1 j$ R1 M* v$ C. u9 C+ r' \9 C

+ C) z' V2 V+ h      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。0 q% }, v- `8 H3 `. K" H7 Y
8 a+ ~0 O, d* ]% T1 r$ V
0×02 写在前面的话) L1 B# C2 e6 u' N, A" f0 u  s5 c

$ R1 k3 k& u7 f6 u$ H    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题  n( ~9 t/ b% r) c

- h5 q; K  O& ^* O( U这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
, p) T4 |' w. M1 C% w2 \) E( [% P& s0 K' Z1 n- M
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论
5 ]" F' _9 z0 N8 B( E+ b0 \% S, ~- L" b1 D8 z% D' v1 |
0×03 路径? ? ?
1 v  b/ p' M, Y) ~. }+ f3 z1 v! \
. V* ?4 U, x  A- `    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件# w2 i& `. R9 G$ N& `% x  K

& f' s5 P- @: c! K% ?: H7 H/ o! J) P$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])); }
; o# W9 H: n# u. x8 i+ l) b2 P- Y6 g9 i! i/ K' @3 V
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的
' d7 _' O" I5 V  J, Q
& h1 d+ X5 {( S+ J2 v' U然后就是将我们传进来的参数进行变量化
# X. u5 ^6 u5 X+ M2 L9 s1 H0 U
- g+ N+ U0 Z" Q) m+ M. S- b这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量: K# a- o: e0 G* U6 k& ?) q* {
) b4 _* W5 ^5 x9 B% U$ p6 r0 o' P
但是接下来这行呢?
9 R" S9 C0 R) |2 Q% ]0 A4 o. a& Q8 m8 H+ g

& t3 r7 m7 y9 }) B- e3 U! f7 h' t% y# U1 A6 n' H" z8 M& p! E) I3 \
if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); }
2 h. l% c1 R. L4 @, c
1 |# T# z$ ]& J   N  m$ I; w* D- s0 p

0 I- `5 S9 C& r3 Y5 X6 |$ R看看这里?
- x" i1 k: ]2 C) c% {1 x( T( z& C; E. v
这里的QUERY_STRING来自前面
) G& z/ v& o* N  J1 V% h
  k5 w" K  `" B7 H+ D; @ , p  P' Q' s4 S' j+ f1 z9 C

! L" r6 m5 M( L% X2 G" Tdefine('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 E4 z0 l! C& U; l, r, W  Y
这里有个过滤,但是不影响! v" Y) F3 {3 N8 g

" n7 l2 h4 l8 E. l- B8 h8 N如果我们在这里进行覆盖这个db变量呢
4 c( I  P0 d* o2 _2 \  Z3 ?4 O# f2 h% H
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
6 z  u. J  C+ n& t2 c& |
0 Q5 q4 j0 D$ w8 S可以将我们传进去的/ - 进行替换
% H+ T! }3 I0 ^: l1 j6 e9 f
  n8 V+ N$ i$ E8 G/ H' c* I所以我们如果提交如下字符) a+ M8 s  @" q2 }$ N
7 U7 A# J' P( ^/ ?# o+ |
http://localhost/phpcms/index.php?db-5/gid-xd.html' z5 q% d5 e) ^, ?- }9 E! h
- ]& ]- v# P6 S) l; @$ H2 u1 ?
他由于这个db被覆盖就会出错,所以物理路径就爆出来了* M' v! A/ b" J. D# h: p! Z8 D

! M  t0 O' I; o* }  t, G0×04  SQL注入!!!: M7 \( d) ]8 L  f
8 f$ `* T0 A' q* X. V* _- a
  在c.php中
) p  ^. G& \! Q# W0 l1 {! ^5 `& D9 b) Q
) h1 H' ^& v1 _! C5 A
) \$ E6 n7 \  u" f4 ~3 i$ I% q/ F% p/ S
<?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']; }
) D$ w5 ?. G1 c4 m6 R' Y: f
5 U" v1 i& w' f2 j- H# z( `$ N) D
# X' o3 I! @' n8 d7 H( h9 \$ e% {) k8 e) Y3 @
注意这里的HTTP_REFERER这个常量% [1 c0 Z/ Q4 F

9 B9 h3 ?& A! B0 }5 |这里的常量是通过前面的common.inc.php定义好的* G& V5 C2 Y3 \# y

- T  B. K/ k/ ^4 \: k1 Wdefine(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);5 U4 A6 j( c" e1 y9 w' j% v7 h. a
& m( f+ f& L& [2 ?$ _' ~
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我
; @* w, N0 A: r$ w
+ m* m4 @7 J+ w* V1 L; m然后
- R8 P1 T% W& \( ^) ]" j4 E2 S/ {# ]1 l7 b3 o# |$ U2 M/ g4 V
$db->insert($table, $info);& o9 M$ V% o$ i
我们来看一下它这里的操作
; v! p) s# k# F8 C5 ?2 s6 u! X
2 c! e4 c/ C/ O7 Y) u( Zfunction insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
/ _* g; \+ e  \/ H) g  v3 Z( C9 t- y( o7 {  O
所以你懂的3 G. R" d1 j# W" A

* }2 {- t% F0 j* I' U9 x' r: m - x: o* V" [. s1 E# B  k. U
, p7 c4 ?. R" W% P8 z
附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737- W: A: k9 k: T  J, @9 T5 f

& ~4 r& p' V" u1 ~) V. P
' R! i3 m6 E/ s2 L9 V0 G6 l' O) a  h9 A+ F





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