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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿
* {( U5 C7 }+ u- d7 K
" u$ _3 b# F% z& J      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。
2 E6 t5 u& T  W: q9 K( h6 f; j: o+ B9 N2 {! q" C4 k: G- L, v
0×02 写在前面的话, J6 y$ q: d; B8 S* m) t' R
/ }6 }5 f/ P* F& h9 M
    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
* d7 _6 Z0 |* G5 h, I; }
: [: G# r* G8 }1 R这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强* B4 n, X& ~4 a1 X

$ ~9 g5 L  Y* p3 w  K这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论* o% q' K( J( d# ^/ c% W( v
+ {3 R% W* \! v; x& m
0×03 路径? ? ?/ i8 z. N. S: T' a* a: c
& S9 m- z! _) ?9 |
    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件3 b& W! l0 e- y: G1 d
( `2 P  \. J8 x" V
$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- l; J; N2 G+ v4 F, Y; j9 z5 B. o, C: n# e$ V2 n# u
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的
5 J; V. [; v$ E3 S/ k, n( r" T3 }; W2 o: R5 {3 E. n
然后就是将我们传进来的参数进行变量化
- x8 S4 f4 _1 H. c5 B- q; s2 a6 n+ F& `6 J
这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
5 f( x. K; ~3 ?# V/ K5 u, e
+ \, w3 D) g. U# z/ y5 i2 a4 n但是接下来这行呢?) o7 u( N* e+ A, I+ p
+ g4 G( a% d# L" G+ C& T. A
$ [# C" c0 h2 D' u
& S3 H- v& t4 l2 Q' h
if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } # k8 r  R/ N" ?# |) C! S) D  G2 M" L

2 R5 v# I, ~# K/ U  X $ T2 }8 R, I! v8 S5 `" H* `- Y1 ^& C

: g  c+ y+ A+ e8 X' F看看这里?8 c: ~/ P8 Z; x0 @' q
2 _- R2 T4 p) {2 ~4 c% c" n
这里的QUERY_STRING来自前面
, B& V$ y5 T; E: _" n0 W# G; L" y& b
/ p/ x% \# \) a" j, t4 R: k4 a

# `$ f9 c5 b" w# r% @$ N( ~6 xdefine('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']));: t2 h( X; Z0 J0 Y2 l- `+ J
这里有个过滤,但是不影响
$ F: `- @7 n7 \" R$ k, m( n- m$ P9 X. Y" r5 y3 s% B
如果我们在这里进行覆盖这个db变量呢
3 F; ?1 M% ]/ c. y" L
. [2 C, C. X. F0 B因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
& r; f  ]1 L* X: L$ d/ I& }6 s# |: r! U) E6 [; q
可以将我们传进去的/ - 进行替换8 U6 d5 Y7 `) p( c) b/ \) F  |
% H9 H% Z0 P8 P; }
所以我们如果提交如下字符
; C. T* f7 W( K" B4 J3 ?( h% e& R% S! t. `: z, [# E8 _8 P& D, R
http://localhost/phpcms/index.php?db-5/gid-xd.html
9 Q" V  u6 _6 `7 G$ h# n2 S: {: t0 I% [2 z
他由于这个db被覆盖就会出错,所以物理路径就爆出来了
  t4 A6 s8 j. \6 d' c6 L- i+ o; H+ v' \8 \. E$ {5 W
0×04  SQL注入!!!7 o9 q1 k: H7 }" X$ w7 s5 b

. O8 J. z0 K5 ~/ l8 F3 \/ F7 m  在c.php中7 h7 U9 {7 S' u& m. N

+ H& X( A; ~: s0 n6 A2 {' ^2 r# b2 K
6 j' E2 X" |2 O% S" v% m
6 q  y4 m, m5 \4 J& \8 v3 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']; }
" |: l* P* @7 c8 z. ]' W* R/ _& n4 L( s. R3 D, x) M' U

3 o, f: W8 s  o/ F  ^, H
  ~9 S! b4 ^! Q$ o  u& n注意这里的HTTP_REFERER这个常量" L- p1 l: r2 R/ e0 _! @
2 R1 ?: d! q7 u8 T4 \: |# V
这里的常量是通过前面的common.inc.php定义好的, ]/ T* y/ A1 G. X  M+ `: W- c
) Z8 L: W5 A2 p
define(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);; s! S" @0 F, x. h
) w+ l, C- B# j" X5 B! T
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我
( Q' j: a3 n) a6 ^% |7 N' t  M1 @4 e: E( O  q( }- B4 X! k4 r
然后
* N) H4 W5 m3 W# ?. W( R) I! @0 ]6 d; q' A. |- R4 M$ Q( E* s; W
$db->insert($table, $info);
* Q5 b% }$ E! u# z- |; H% j0 y我们来看一下它这里的操作0 y0 y  N* F( R

; U; S8 r$ ^, E- d6 U5 @  tfunction insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
$ w9 I# b& a$ L; h. Y# K9 i4 {! L1 [# `0 q0 `* k
所以你懂的
( B  h2 I% {( x1 [7 I  R4 p* q7 X4 [5 G# t. v, l/ S

0 r  S* Z% s, v, m+ ?! C9 z0 N) j( n, F  w
附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737& ?# H+ e2 m+ R$ X( X) b8 G/ D
: }' c( a/ P* L1 t2 K; {  c, W% Q- h9 Q

3 E( z( O+ r% f) G8 X, W0 \
4 Y6 K; [1 V, e# [7 |  f- W
回复

使用道具 举报

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

本版积分规则

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