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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿
1 ~5 U4 j$ P  O; ?- v# s8 Z6 d1 ^7 l( X+ U, Z  n
      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。3 {4 U- f! t* w) n3 ~

# b6 N4 d+ r" J) Z6 i8 A% }/ N0×02 写在前面的话
$ {3 R# Z7 i* t/ B+ ?
7 K5 V9 M# `4 m5 T7 j4 e    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题! r! B& r% {* p  \
$ w* {0 u# C2 t" M& c* Z5 [8 G
这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
" l; u3 r9 U6 S$ u& L2 p% Q1 o$ |) h
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论
0 Z* Y9 [7 V2 o& B% F6 {% W- v. m" K
0×03 路径? ? ?& `! _, H- V* B/ Z# b
% @9 d+ T  |* }5 L- t2 d
    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件
" N: E  {: J) n4 f* U& l4 Z7 Q. u3 p. A5 i( T
$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])); } $ P9 P: f+ `2 V4 H) V' t; L+ A5 I5 I( P
2 E3 d) a5 k+ {4 E0 j; }
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的
) a0 D, }4 x) I( Z; Y  O' r: e% N8 Y* G4 a$ m6 O
然后就是将我们传进来的参数进行变量化5 o6 ~$ }4 m4 H- A+ V

1 x  d. j" Y$ Y7 u, K这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
  I4 [! n3 Y7 B2 |% \
5 Y7 _" r* ^& C但是接下来这行呢?" a' r$ [9 e0 ^. K

8 F; Y: r- U: o3 r1 J. i
3 ]/ O: l5 J3 F0 N9 {$ H& D$ M$ s& s( E$ O- q+ Z
if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); }
2 ]- i/ w. }, o% o: j2 Z" P" Y
1 d0 B8 ]% @% i 9 h; W" J. g7 p7 z' u

7 F" w( E1 B3 v看看这里?
+ _! Z( k) W0 I8 `7 X. C! o/ @6 n
这里的QUERY_STRING来自前面
3 N. e$ h" O8 a6 o
. w' S; i. u4 G: z) c# J/ c  q , x$ o$ D2 e2 a4 N3 e

# B- b8 ]1 ^: k  z: E6 fdefine('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']));4 k( c0 v  B; i( {4 A3 ?7 h
这里有个过滤,但是不影响
, C1 L5 N) \9 f0 ?. e6 K6 i& T1 D# S3 N( |/ D! Y
如果我们在这里进行覆盖这个db变量呢* A- X- N" g  P& e9 ~
) \: E9 ?9 m2 L* ]) I; K
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));8 U% E  m. o! T$ I7 e

, P9 m9 y2 {( A/ n& ^/ S$ u% u可以将我们传进去的/ - 进行替换
! G% `6 r* P! |5 r) M1 d: O) r1 U( O5 D9 C) O
所以我们如果提交如下字符
' v; ?2 {$ L+ c! C
( O2 [& I5 Y# `/ g: xhttp://localhost/phpcms/index.php?db-5/gid-xd.html
+ D( n# k' m4 l" e
8 G+ G% l# b- ]5 }& S他由于这个db被覆盖就会出错,所以物理路径就爆出来了
+ J9 P, d0 m/ d* V$ y; `+ A1 _0 J% N
0×04  SQL注入!!!3 F5 [' e  V0 [1 u5 Z% ~/ j$ `% ?
, X7 c* t0 h& O$ p* h# O6 H9 L
  在c.php中
2 p0 z' [, ?! `1 ^; s- q* l
9 a1 y  s! g, h7 k3 Y& o # d6 c7 e5 k% T0 r7 n9 ?8 q
$ N1 _- i2 Z/ j, h
<?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']; }
' Q: o; Y- y% A" t# r
! Z3 p2 g* _- J4 E4 Y2 V
" o6 e' }; ~5 Q
5 p) j6 d5 C" h$ J$ O5 \# G& d注意这里的HTTP_REFERER这个常量
5 R' f" G2 ]% ]  T) v
: U3 [; \9 p- R( B这里的常量是通过前面的common.inc.php定义好的# j- n4 H  ?. t- t; m+ \' r

' U  t: p3 @+ F- H2 ^. O2 Fdefine(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);! C! ?) I5 m) p; [3 D1 h/ f1 v

* _1 v) L% _& {% E9 @没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我
  s' \" v0 N$ i8 D$ u$ F2 d- C+ c4 `
然后
, k1 M$ L. Y/ X" G5 g& Z- O3 q  D8 K* N! d  n7 p6 ^
$db->insert($table, $info);4 g: N3 G, a7 K  A6 x# v/ j; p  @7 C
我们来看一下它这里的操作
2 Q; K" r6 j+ M2 V: @6 Q+ r, i9 T. f' H1 O% |
function insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); } 7 q- B0 F* V; n. S
& o# H: K9 b- t5 r' U( G$ r3 F; P
所以你懂的7 q5 q% A+ W+ t# _9 U4 ?0 O

) r! g8 r2 F+ B7 d3 ~
/ O% f) I% T  J( v5 r6 C7 z0 ^3 g2 b! ]5 d5 J
附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=40456377376 o# h" S+ j# ?# z8 K
/ P0 H8 Z! C# @$ w
) b9 c+ w. I& K# _$ v+ S
: p! ?/ U' [/ N5 a
回复

使用道具 举报

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

本版积分规则

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