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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿- c8 t0 I& q9 S1 u
4 X4 M) S1 _- o3 M
      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。9 t) f4 W4 d/ O3 b$ f* @
$ n( C0 J0 g; N4 Z4 D
0×02 写在前面的话
. b! {" |% ?. u' x) |  Z: q8 E9 _
    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题6 x1 D8 W7 ?( ?
7 U0 F/ |$ h5 u
这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
) @+ S) e2 E9 r$ V
; s3 g) o& y/ g这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论' V! {( A# @& H0 N: `+ x
2 Q) x( I" t% a' |
0×03 路径? ? ?6 x+ P5 R- Q. u

7 n! \" l- g1 b) p    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件& c/ v' M, w! u) V( {) s7 @
2 ?+ o7 j8 M% F- A, O+ ^
$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])); } + h4 A, }2 j& O$ }3 N

* N+ c2 ?0 e. b2 `这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的4 M) l; \9 X3 p7 L; A) K' V, M" l
% |; `# l4 r1 l' I3 D6 N- K
然后就是将我们传进来的参数进行变量化
8 b. b  m) @: [# y& |4 p: @' ~( l8 K
这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
) f3 D2 Y1 h, n* u9 I
" [$ e/ s5 C# m6 x6 H但是接下来这行呢?
7 D1 Z" r' G. S- s
6 Q2 {1 @% z; m3 ` 1 Q5 z/ N1 W2 ?+ v0 Z. |

; M1 H- U5 k/ v% \8 w3 Iif(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } , K# K* m0 w% I0 m

- i* m4 m+ J0 T- X7 V4 f0 u
7 Y9 g/ a% C. d; S) e
# d9 {3 ?0 R$ d% s* o看看这里?! a+ c% m- \  s- R

8 V* P) ]: p0 }0 n这里的QUERY_STRING来自前面2 Q# j: a/ z/ o

0 A4 q5 {6 D( t' q% l5 q7 B
, K6 i8 Y! D% u/ ^% R" H: j4 ~  i' T; H; a1 D
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']));2 ~2 N6 p: m) i$ K  c
这里有个过滤,但是不影响
# x( q8 x, N; e) c1 q& r- E$ S& Y$ x" R9 v2 Q* O
如果我们在这里进行覆盖这个db变量呢
* ^6 R/ J" _* R9 |2 B/ j- d# i- Z' Y7 |/ v, i
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
$ t1 t5 Z6 y- T& r0 F3 o$ T
4 J0 r& }* S4 I+ {可以将我们传进去的/ - 进行替换: F, W# o7 R4 E, U3 Y
3 Q* C6 m6 u# F" N% e+ `! L2 i) {
所以我们如果提交如下字符( J# }2 l# j- [& U4 o

6 L8 S+ ?7 L1 B  j8 [1 lhttp://localhost/phpcms/index.php?db-5/gid-xd.html8 h- n% Q+ R2 U2 J
5 S9 ^# o! F0 P# K, m! G
他由于这个db被覆盖就会出错,所以物理路径就爆出来了
- U) ^0 r5 j4 f1 ^7 \2 M/ P
: O' ]4 [6 o5 ]8 M0×04  SQL注入!!!
( v+ G* q. j, B  M; L+ H+ S
' L6 X8 e$ L' m" Z8 V  在c.php中
+ K' g' y; N& D5 f
4 e1 G- D' N1 A4 p: a- |" l7 Z
0 I9 l& r  L# n: q  K' B) Y; v" x% ?. A3 Y! T$ N( f
<?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']; }
/ {0 }; q8 g3 D% ^$ F8 V7 x
( x6 _6 D5 U8 Q7 D, n ) V" K; |% D7 p

  U8 r, W! ]0 z! c7 h1 t- c注意这里的HTTP_REFERER这个常量
$ H0 i5 y" T2 f9 C( S! p- |0 n6 Q7 i& M
这里的常量是通过前面的common.inc.php定义好的
0 Y: V! p. H* a5 b2 k+ A
0 S; \: ^, b+ V+ |; P/ ldefine(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);8 Q$ [, K$ J. v0 |4 Y, o; K; O
3 q& R9 z6 W- i, e. e7 h
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我
% o# |6 O& W: e
! V- P8 |  a/ X然后
" e; m- S, N% A9 ~+ q& [
% R0 Q/ R% E" c$db->insert($table, $info);
) }2 N( h9 }, y" O  ?7 S我们来看一下它这里的操作
6 d4 g6 H5 n6 S: m
; j- |# Z8 j& O9 s% Mfunction insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
3 _! y; m& w) U, F, n. h& C% Y+ h8 P1 f: [% y" b6 g) `
所以你懂的
: h7 z' O0 W$ o! m8 s1 }1 C0 \* ~& B, ?- J- u7 V4 S( K8 Y3 _; n! N

3 k: {$ D! X5 [( t5 X$ ^; I0 Y
4 a( x3 R. l8 Y" |5 T附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=40456377376 o$ U& Z) W+ E% ~

1 n# N3 T2 ~6 d0 X7 }6 d2 s# N ; B% T0 C: S; B3 K6 Q, L0 g" H

3 V3 l: z" v1 S
回复

使用道具 举报

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

本版积分规则

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