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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿: X% {+ i9 ]7 g
0 ]: G0 y  p  s- M
      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。# u8 x( j+ n! O! m! f; r
& J+ B( K! \' }5 O2 R
0×02 写在前面的话
! Y# D6 t( f* K
2 L. d+ ^- e8 `, M7 O    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
, d! H  `9 B# a2 f
, _" C$ v7 m- _这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
( d- v. v. c8 Q% j# C: k1 n/ H. ]. a( R) g/ i5 x7 t$ t  v/ _
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论
& i) \3 c" |7 ^: q
0 y; h7 G. I! s1 i  [0×03 路径? ? ?9 T( ~+ U( S+ n* r7 d. P) S7 Z5 B
' i( E$ Y( p- J. `* e& C5 n6 r+ w
    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件- y; a3 R  E. `2 z8 s0 E3 t5 D

4 n% ]' m% I" d" r8 K/ h/ V2 Y1 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])); } ! ?1 r8 Q% Q, P$ D: J+ I

1 O( ^5 q* g6 v, @* }" R9 k( ?这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的0 A- k- ?( I2 r% w4 ]$ Q
. ]2 }, N8 {$ |: d
然后就是将我们传进来的参数进行变量化- ?/ b: d0 E3 a/ {

' x  F) L% @+ Z3 z这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量; ]  r7 y, c5 l# ^) H& b1 m9 h

) a4 y" I6 P3 ^, Q" C9 V; q但是接下来这行呢?
2 O7 S; U5 b+ K  G/ A/ u0 U9 T$ o& B  V4 z$ |  G7 l
$ Y! J3 j" P9 P& _9 G

. T6 d' U' t- E& J( Iif(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } % a3 D# A5 X* q! O
: L5 X9 M% P  j9 N/ @! b8 _

+ p7 o. q5 Y+ ~& o; o
+ Q- }7 Y. Q/ O8 F0 V$ F1 G看看这里?
9 D8 }* ]' O) j5 g0 y8 N* X
( u. {( h) d: [5 ~4 a3 [这里的QUERY_STRING来自前面
6 l: k1 G8 [$ P
3 D8 I/ S/ Z  Y$ O+ P/ p* Q; X' a7 X
. w6 q% s2 m* t/ X- g% W6 `0 t7 K8 P* P* M$ {1 H
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']));
0 f( n1 [) R) A/ H) ]这里有个过滤,但是不影响- |9 o3 A; g! _: G2 v: ~# Z( R
7 |6 |, H- B& c' v8 X- V
如果我们在这里进行覆盖这个db变量呢
# @% Z' u& a$ i" `. s  Y9 u- ~* {& O* [7 ]* M5 P+ j! Q
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
0 K1 z1 C$ h3 c7 W( K# j8 J% O
7 p# y2 i  T4 r, j, E/ o可以将我们传进去的/ - 进行替换$ e* f- H, R) Z" ?9 k$ T% `

# x1 d7 Q6 Z$ }# l2 l. w9 r3 j; b所以我们如果提交如下字符3 G* n/ b" V) C  w
7 Z. T9 V; l$ b/ g
http://localhost/phpcms/index.php?db-5/gid-xd.html
& m6 r# k$ t0 u6 V; F8 Y
3 b3 x1 \: g# P他由于这个db被覆盖就会出错,所以物理路径就爆出来了
4 G7 l- N& Z* d( v2 I5 a5 d2 b
$ d) B2 n) G- p5 _  i( j5 \/ H( h0×04  SQL注入!!!
- D: H  p4 p  g- u( _
, b4 Q% v  W* {3 p* c  在c.php中
( i1 j. @9 ?% q( p6 U  N$ \% z, M5 r

* a' o7 _, I  e. Y" r% _8 u5 y/ t5 g! K: A
<?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']; } ' a# @: q/ o9 \* n' M" I! h
! A5 r+ C2 K2 I7 C9 o0 F

" O/ ]& W" e1 N3 m4 m# i' r4 w2 Z! [  i
注意这里的HTTP_REFERER这个常量: o& m& D  |5 M  ?

0 B# z9 \- p$ m/ n# c* N. E0 p+ E这里的常量是通过前面的common.inc.php定义好的
1 P" k( P: K3 D2 f% X! P* D
2 k. `/ N  G" ^1 y/ Fdefine(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);; Z% k% |* {6 [
6 `8 s/ Q. R( l( N' Y
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我8 l( n* l1 u: |1 w* W7 N; `
5 b; U1 ]2 C: C" w
然后1 J8 M3 s4 M+ ?2 @2 r. m3 g

) p& ?+ y2 v3 i: L% T3 m$db->insert($table, $info);
) D; T+ N! ]2 i5 G) |* c我们来看一下它这里的操作
+ H0 v# C5 \+ |6 x' `1 s1 }" ?0 {& p+ Y2 M
function insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
' Q$ ]& G, o: c6 Z" I# x2 z4 w) [4 I# s' F- a6 \
所以你懂的  }: I+ Y5 o# U+ t% R

1 @  |4 b6 F) @3 N8 A' x
' S# N9 W7 j  z' k5 i4 ~9 D9 ]
) L* ]# ^1 L8 s) c% S附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737) @; W* Q/ d# j% I0 b
1 ~' Z: V1 o! n) c7 [
+ s$ n  r( n& R2 y0 p
5 [2 o3 i! S6 {  `% o
回复

使用道具 举报

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

本版积分规则

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