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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿
; i# w  V/ A, Y3 K8 T9 b
! U# F3 g/ [, u2 v+ @# g; B9 ]      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。
& f$ F+ c# G! i, Y4 @( U7 a7 R6 b! Z9 a; S: R5 t! M. M
0×02 写在前面的话
, g( {; I! Z, ]+ R' f, [; i6 z* u: a# m
    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
; l) H/ y7 x( V! e3 v: S, z
8 s9 n: h+ K8 b7 x1 }& q6 F这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
: B3 W  U. j8 |: K6 q
: P: s. w( B6 b& Q* s这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论6 {* n  t' s/ V( N: B3 B
: M. \, [) ~" c$ D8 P, `( J1 U
0×03 路径? ? ?! T. _& S* W6 X) C( T6 m( a0 E' W

  }" A) l, }) X, a% }% \4 v    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件# z; D! {* d2 B$ c; P

4 z' k+ j2 Z; }: L2 z! n. n8 T6 b$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])); }
  h) J" R/ f. i6 K' A5 K( q1 E  k- [9 X6 d0 _1 s: s* ~
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的& p, p5 v5 e  p! I, F: a  G

- E6 \. l( ?" G5 p- H$ k然后就是将我们传进来的参数进行变量化$ T* _2 V1 k+ ~8 r2 q  j
! e  |2 M" J0 o* S
这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量7 b" D' E0 H$ d  C

% F; _$ ^0 a/ o/ Z- f8 B, T% Y) ?但是接下来这行呢?  \# t* {" `& D1 ]/ @

: W& d& d& S/ V9 |/ j2 w( z  _ 8 Y; g7 f: g& f6 l  q3 f
3 J9 O% r- G* V0 \! F
if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } ! ?' }, p( W# _- M1 J0 O
1 q$ @( j9 m% w1 G9 P) @

& k2 O- M7 C" l4 b: }5 o& O2 Z* s2 J6 n8 a  t4 Y
看看这里?  q* k5 k2 I/ r

" E" T' z5 m. \8 W这里的QUERY_STRING来自前面7 v  t& \1 f' {6 z: g1 J4 u& q

/ _  r2 J, Y6 \# D0 f5 _% R ) d/ l8 @$ p' I* s" w, S* R" P

0 g, k6 z- _4 d  L: @6 adefine('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']));3 z( D. x' P6 W. |6 [* D
这里有个过滤,但是不影响
: |2 y4 n+ n! [( }: {, ~  B( ^4 F2 d* k1 ?7 [
如果我们在这里进行覆盖这个db变量呢) }5 C: y& X4 y+ R! k; W0 T" P

/ E/ B5 ^' Y; C, i) w. k9 Q! g9 R7 f# t7 D因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));0 R% U0 t& V# h7 e+ r
) O: n# {! p7 _+ \% i
可以将我们传进去的/ - 进行替换
# w9 N5 k7 j/ x+ Z; r
# g" D. k4 }) b8 a- t4 R所以我们如果提交如下字符
7 p1 @8 H' W3 n, Y9 E7 t: h( B0 H$ `6 \
http://localhost/phpcms/index.php?db-5/gid-xd.html
# x# i3 ~; U, o
) Q0 @0 L: f. `8 S+ I4 j他由于这个db被覆盖就会出错,所以物理路径就爆出来了4 j& a' Q9 p% {5 C8 y5 d
* ^' N0 Z5 c  W( E0 G2 P
0×04  SQL注入!!!
- X4 r2 t- E* ^6 `9 k) A1 }! p) a3 s7 O; f3 C
  在c.php中0 D0 `0 {+ o' f8 f
( K2 X$ @1 F* N7 @1 A
2 D5 Y3 G5 d5 b' J* _- t

' [0 h1 S3 s5 R* e2 ~<?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 w& S7 {' ^8 t: }. i, _

1 w! S* k: J! U6 ^1 c  { ! F1 V' ~, A/ M. Z! h  w
" A# O& ?( J1 ]7 B7 ~
注意这里的HTTP_REFERER这个常量
+ y& q- c) E7 H$ J& e/ K) {! K3 b9 x; h7 k; h- g" Q, F; R
这里的常量是通过前面的common.inc.php定义好的' l  I! L4 I1 ?$ L

* ?8 O. I9 N) n; Y3 ~, M  _define(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);* o3 E6 @/ f; A: ?+ f& z

# M# O( ^2 R7 ?8 o! D& P! r5 A没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我' h/ i; _4 T" S. c

) S6 z9 [; v1 a. ]$ ?) Z$ P- y然后
! w0 `- m/ J/ W- b" h6 u7 w/ O4 T6 r% D
$db->insert($table, $info);
9 c) C+ h8 c; }# w" [* S我们来看一下它这里的操作- E  f# s: A1 m' ^8 M) K% ~
# g6 O- M7 ]0 F; Y
function insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
  G  X. L- e7 X1 v( H% v/ U2 X6 V4 z4 R9 b* Q
所以你懂的
5 ]5 y: X0 F2 |8 Y3 }) R/ @) J9 n7 U. f6 ?( W% z* s7 A" t

9 w5 O7 ]5 s1 n8 H* t* k8 j3 L4 s( E
附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737, w8 T+ L) i  X7 r

8 i9 S: x: H  k4 l$ {& j
' B' a. _% Z9 p9 P; T! }7 }/ p1 s1 D0 o* R% x6 Y4 w  J
回复

使用道具 举报

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

本版积分规则

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