中国网络渗透测试联盟

标题: PHPCMS 2008 最新漏洞之通杀注入漏洞 [打印本页]

作者: admin    时间: 2013-3-25 20:43
标题: PHPCMS 2008 最新漏洞之通杀注入漏洞
0×01 前沿
' K) L( y0 j3 D1 X4 s
. |$ b# B# S' B0 c9 K' D: n      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。" m% b) A1 ?" b

1 r; A! Q5 I  A- Y9 S' l- c7 l0×02 写在前面的话
2 ~: c' u& X* N7 P# Q  h! V, Q' o" q) ?6 |( F4 P- ]* g* M
    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题& Y# O( w5 z+ X5 V; V( s

( Z1 k; H- k: D) r' s; }" _# ]这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
( m2 _+ b1 z0 @; p/ p! @$ d
6 H# ]1 w" S% f  |这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论
. t' z* @) f6 X3 r% |5 x; V* a2 Y0 |
0×03 路径? ? ?5 w! e$ J, V) f
2 e6 K: i& m- I2 {- Z1 E+ z! Q# w
    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件
1 A$ C- P. I, O! }8 K3 u4 K' _0 H
; K& h  L% e3 Q4 {5 C6 Q$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])); }
/ u! ~8 {+ L: u: Q  @  o
. G  r: ^/ ?$ m这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的  w1 [  R7 B+ R' i: v: L. X/ S- z2 Y
! _0 j0 J8 g! [+ U1 ]
然后就是将我们传进来的参数进行变量化
8 b* h' _, j9 E/ }, i7 h. \' u( q8 M- t0 }2 D) A
这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量4 D) G. W3 ]% k

' _1 t! L6 B8 ^" K) l但是接下来这行呢?2 w/ U; V: w/ p2 [9 [* j3 v  K5 y
3 x* G5 O* u( Z- d$ i5 d

+ k/ o% r4 b+ E
" Q0 M/ z9 y! Z2 ~4 O9 |if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } - ^  e! V0 k2 G( @! @
! C1 U- M) _; _* N: E$ T, b0 D
$ w3 {6 }4 P) j8 U1 U
  s6 H4 T% u1 s5 l4 G5 Q6 D1 K
看看这里?* T* {1 ]: @2 T1 _! j5 @: _
0 K- x* z9 U- N+ @0 d8 o
这里的QUERY_STRING来自前面
7 u# W4 o$ z/ l0 s& w) j! i5 q* f8 X, Z6 H/ u

; ?, q2 k: b; A- [7 o% z! k
1 H  |2 u0 {8 @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']));3 Q7 J$ j" x- l8 `( }) V1 W
这里有个过滤,但是不影响
/ ^; d, U: z* n4 s# R" o2 U$ d: L# c7 c: Q1 f9 X
如果我们在这里进行覆盖这个db变量呢' N3 p, K. X2 U. Y
4 c. B. K$ \8 q( d! _4 W: x% ^8 v
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
2 }8 B: h6 [$ g. P- t8 F$ G: s1 q' [. H
可以将我们传进去的/ - 进行替换
$ o7 T3 f3 w, E( B% s) x" K3 t1 F4 C& E, j& N, I) E
所以我们如果提交如下字符
6 |4 G8 f* H4 Z& a3 j% T
3 Q4 ~' v& }) y% W+ a: zhttp://localhost/phpcms/index.php?db-5/gid-xd.html
4 G. F. G* ?+ I: q/ u5 G6 j, B9 W; z, C( }4 F8 U
他由于这个db被覆盖就会出错,所以物理路径就爆出来了
7 V. k6 s, L* t& k7 Y, ], c) C
2 t3 h) S; ~9 m/ F+ Z0×04  SQL注入!!!/ Z0 H+ s7 l$ V. _

+ R' j" f$ u0 n' d7 P  在c.php中
3 g9 Z9 B1 s. _8 Q4 w+ l# p9 k6 E4 ?( ~7 F. k
9 E7 w7 A" v, [
! }2 N4 \; a# B1 v4 J
<?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']; }
4 w9 J4 b/ I0 e7 Y/ z# G# Y+ @/ O1 l  f7 F0 t. k& ?

" l) |2 ^) M6 |
/ V  @- e1 T/ o: o& I注意这里的HTTP_REFERER这个常量' {' w. D; e/ {, P& S
+ F, z8 {0 J; l
这里的常量是通过前面的common.inc.php定义好的
. _! S$ O. W) Z1 d- V) Z( s% j+ n9 K% j% V: {! j0 }( J- X3 D
define(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);. {6 c4 i3 ], d; g$ [
; r% a+ M, v1 f
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我1 e+ |2 t! p; A' S# L+ @! W$ c9 t0 r

: S9 A9 _" ?7 w  E. S7 ~0 E然后
5 \- n( K4 m+ M" u1 e1 H2 L
4 s8 }) V6 C  r$db->insert($table, $info);1 Q0 \0 R9 a. D
我们来看一下它这里的操作, |2 T; n5 j% Q3 l$ p- U
' ?# y; o0 v! m+ U) ^
function insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
, F! G8 z2 {7 P  a8 B; q) t7 z
* V2 s9 O  c. r5 p4 b  f3 f所以你懂的
& W0 H8 Y' X" {) ]2 a  b# i( a: L) Z
. v; I' B0 C: p; s" G( C

  h* F- p4 b5 P4 C- s- _附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737
. ?. W. I: k6 e0 n5 ?! M
, M. n+ q' Y, w3 [; x* M   T: O4 P: q. |0 S' w. g1 X2 Z

- X, f% U2 |) m, v




欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/) Powered by Discuz! X3.2