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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿
( T) D+ ]6 W: X+ B5 x. ]7 T8 n; n, |
      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。
* L& @1 e' Q2 j/ @
5 B7 _8 a1 t9 T, Y9 v1 X0×02 写在前面的话
2 z$ ~9 l! T' d! C% S" r
2 y& S: I  [6 b2 r    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题. j3 b7 [2 n- B1 l) e! v& Z
" g1 T/ q/ |2 U6 D8 Q
这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
& E7 ~+ f+ V/ L6 b) a7 S
( }1 {- @, `$ Q7 @1 J这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论: b* q$ t' M& Z+ H
# Z- K/ Z7 C2 b4 L
0×03 路径? ? ?/ \/ k- e9 M- C* n) D2 P) w8 V
  k! p" f( y( ~! ^6 i% i7 ]
    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件
: W7 G$ E+ J# S& O
3 D' ^4 G. U/ ?# [/ S3 M& b5 S$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])); } * s, G5 q$ s+ m

9 w- F+ s4 p( f( m* L这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的
* i& U: }9 M! P$ M' n3 I7 E) f7 ^/ c7 L/ m
然后就是将我们传进来的参数进行变量化
* g# O" k: S1 R
1 y" ^# `6 A: w% A# `- A- E5 J! S这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量3 L* i/ L0 c. @1 J* n
" l) I3 k. p* H
但是接下来这行呢?$ F0 }3 }4 p% a; H* z& C. t0 a
& N- V1 Q5 n1 D7 E$ D: G" a

0 D/ g$ i8 `, Y* S
, `  `' I& G8 Z( bif(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } 1 M, ~( _* m7 R9 v% l$ M

# q3 k& y% w8 f' f0 i, N8 c  M
; w7 e; ~: {4 J' v' P# u( Q& B* L6 R0 A" q& F
看看这里?0 z, N9 i9 f3 U! y; Z- R& ?* a" C
. O2 m8 H2 r' _, v2 k+ C0 \
这里的QUERY_STRING来自前面5 p- M0 q3 d9 e8 X% }

2 j7 v, z, _2 `1 ^0 R8 m
5 @! X; z" d, n7 R
3 P) n& ~4 p  f" d+ A' _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']));  j% J" m1 N* E' |7 O
这里有个过滤,但是不影响
' _5 N/ @6 {# `! r) i
+ W5 D6 Z& x; t, Q- o$ r% b如果我们在这里进行覆盖这个db变量呢
1 Q6 P) b' h& |! U3 G8 e8 X0 o1 o0 o+ H2 [7 k0 N
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));; Z* K8 n0 t8 u5 M, h7 ], E
# J. z! u' [; u+ L/ ]5 w1 ?
可以将我们传进去的/ - 进行替换
4 f2 h* E3 n" J9 S) Y3 ~( x8 o3 k. y
所以我们如果提交如下字符
5 [% [5 U" d3 c1 d  |( p
/ F! j6 l" Z/ X, ohttp://localhost/phpcms/index.php?db-5/gid-xd.html' ]$ o& k7 Y- L4 u+ m, T2 z
$ |: ~+ b4 Z8 z$ Y! m
他由于这个db被覆盖就会出错,所以物理路径就爆出来了+ p+ Y- N# l. n# Z9 w( S

1 ]3 F( u1 `, _1 C: W0×04  SQL注入!!!$ t% V2 o. Q2 j. C8 F! o
# ?- N7 ^9 h1 r' e
  在c.php中
1 X4 t4 N  O! E( d: L  U0 U8 B5 ^0 ^* U. G4 F& L, T9 ^/ N8 A

) R- D2 K. f  @4 G4 Q
/ v4 k6 K$ B7 g+ V# V" k( d<?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']; }
3 ~  |9 r0 ~$ s/ a
8 k$ K6 @9 B- _& A; G + S3 X+ L2 M( X0 F4 H; Y$ \! h
1 ~( [4 V; W6 f! K9 f( m% |3 j+ U6 i% ]
注意这里的HTTP_REFERER这个常量
+ u# e8 ~. t3 p
* H! s: e4 c) E; [: I这里的常量是通过前面的common.inc.php定义好的6 _" L2 H8 `. @
5 I% E3 {2 X5 v! ], e% G, a6 U
define(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);1 Z5 P  P% Y3 {, c0 p& g

2 O0 G+ w$ w1 ]2 u没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我
5 C- Y( Z5 V( W2 ?8 u* I& I3 ^* |; q" }) I$ `5 q0 c: p- a1 L; {/ L
然后
  f6 F5 K5 @8 J, k/ D4 V: k+ C; w+ b; U; q: {; A+ V7 M
$db->insert($table, $info);+ R- A$ r, p) a; |
我们来看一下它这里的操作
3 y; I1 I# N# V4 S' ?2 J1 q- ]8 N. E6 I
function insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
# F% H6 h. S+ v  q# e
3 n. q( p5 ^0 q9 @9 {所以你懂的  n3 `% A( v- d7 `: g& L5 ~

3 y! x* G* e( L( Y# L+ }; p
+ p; F2 m3 C+ s. V- @! X1 c
5 b1 t% z2 `6 `0 H  p附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737
6 f/ T. h+ t3 Z) j# V  g2 A1 R: V
# U* W: X6 m# ?3 E# P/ |8 j. t( J 9 J: N: m" ^/ m3 M
* p# m9 p" s' o& Q8 F% F1 O
回复

使用道具 举报

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

本版积分规则

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