中国网络渗透测试联盟

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

作者: admin    时间: 2013-3-25 20:43
标题: PHPCMS 2008 最新漏洞之通杀注入漏洞
0×01 前沿
7 D9 `# L" C& T* v
' B: s* C" b/ I; w      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。& [) G7 m+ F- V+ q# `- a* P$ {' U
  d' q. d# n* a% j7 c  a& A# p0 s
0×02 写在前面的话
4 m! r  Y5 K, P0 F2 n$ U% Q0 z4 L& L1 x$ F6 t- [1 Q' D/ y# _; P
    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
$ x, |4 p: {! F8 U/ k' |8 g! v# {3 ~# E, ~8 u8 U
这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
" G" N5 Q' B$ j1 f+ J5 M% n
: ?; \* W# ]" R# q: J/ _/ D2 }这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论
3 g5 p' d2 O6 r. r7 I3 t3 @
" s) P& _; ^( w" W6 z* [- v5 }( a: H0×03 路径? ? ?' z% Q9 k, W. g! u# ]% k3 I7 U

# w: k* i, F% o) ?( j2 y    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件
0 u7 ]- p4 l. `9 w6 G" {8 U" S
% V* H, F% J' j8 [) R$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])); }
7 _. u6 _8 E/ f/ t' w# y8 k5 E1 d  V: ?3 Z) W
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的( ?7 N2 a4 V$ h

. p* j& Y: s$ ~3 N然后就是将我们传进来的参数进行变量化0 t: w& m8 p+ _6 i: O$ }

! Y! \- u1 `( a& I8 ^1 {这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
% r& u1 d$ {9 r; o6 t7 U' d/ u1 g: s( y4 P  G. ]6 B; ?" l( {
但是接下来这行呢?
9 J8 D# J2 @1 g& [5 M% m! Q+ Z  A
, |% ~2 b! [  D! z/ w  `  S3 {9 x

% w, l' N; J6 u$ h- \5 C& Tif(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); }
2 K$ M& i* k# ]
( B6 U9 t+ I: a/ a
* [0 A  R4 u! c* @. E/ e: ~; d# d
, _+ u! X: H, V. r2 W3 I" r% u看看这里?
9 w' o, R* U# G; |" |
& I1 l8 w! I7 a+ T8 @2 N- c这里的QUERY_STRING来自前面
( X" B% b# Y' M0 Y' A3 y0 t& Z6 z0 K
2 o  K5 C7 g5 B$ u: v' |( J) }
& x! V* q, Q2 N* a. ]8 |
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']));
/ O; X" M$ p' m. g, s& q这里有个过滤,但是不影响' V) F* f% N/ z  x
* o0 m, ^/ W6 Q9 d; _8 c4 I7 s( J9 x
如果我们在这里进行覆盖这个db变量呢
5 U, x  A+ u$ a4 k9 E
# o2 A" L' X4 M* c% @5 T因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
3 q, P! F, u) Y5 w6 a( e
! }4 p6 u! s% ~& i, L5 U- [可以将我们传进去的/ - 进行替换7 |! T6 F# c6 `4 L" \0 Z. ]% i; i# N
5 K1 N) m/ w) S; I% x, R1 p
所以我们如果提交如下字符( d' F" C% t: a( q
7 r. _1 B* \- k) c" w: E5 N
http://localhost/phpcms/index.php?db-5/gid-xd.html
% V& g+ n8 x8 I: s) F7 s- O1 x4 E0 Z9 ~* _
他由于这个db被覆盖就会出错,所以物理路径就爆出来了1 L8 t# ]0 }# I4 |

/ t# C8 p+ v9 A3 H! F. q+ n: g0×04  SQL注入!!!
; R: K& H2 D3 h+ Q
" @2 R  x! c. I% \/ {  R, N  在c.php中3 J+ P* V# O% i

. q7 T4 q" v" ?6 V/ C! Z! u6 B" s
/ P' V0 v( U/ A* X, u" {* |" M% L3 F) E; M+ ~; ?- k; P
<?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 T5 g  b/ V* ^6 l: P6 V0 i5 L& }0 M3 m" K! I3 q  _% i
! J: \2 u- ]7 i; |* B! B1 v

. X1 \: p( N: R注意这里的HTTP_REFERER这个常量' a" B$ @6 t9 Z1 W7 Z8 }, e) `: Y
  G' Q7 a( ]' w" U
这里的常量是通过前面的common.inc.php定义好的
, C' k( B" U% X; ^+ E3 N
) S. y/ k+ l  l* w6 F) B; w' Ydefine(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);
/ e' f4 w2 d3 [: \1 ?' a+ N' [+ E! }* D" h
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我: e) O! H! W) z
3 ~( O. l% U7 e
然后
( F. g  n6 F" L7 i) T# o, A7 f7 _( D6 {( t
$db->insert($table, $info);
" r2 ^& Z, r5 z! M, j) ?7 T& U7 Z我们来看一下它这里的操作
- S8 Y! @0 t5 O% M3 U7 h; [. }2 ]7 Y( G
function insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
. e1 ~3 W2 g" i' U6 f7 ^6 }" W: X. R( ?% @: m9 r
所以你懂的" z$ _1 ^0 c9 p& H, K' `

2 X' K3 E. ]0 Q8 e& r3 Y 9 q- F* Y# l* V: M

$ j4 z5 M9 k& d- |9 i2 ^: P" _: R* l附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737# E( ~$ P& N; ]/ y  |! G& ]

% Q3 [2 {6 q+ B, Y/ \, {0 H9 j$ X% K
) R2 n3 Q& @$ e( ?5 @) V3 H: ?$ c" j/ |# ]& H5 t





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