找回密码
 立即注册
查看: 3223|回复: 0
打印 上一主题 下一主题

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿
! u; Z$ W; G2 t+ B9 {! e, t. C
2 e4 F3 v' I5 z2 o* l      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。1 d, B& h  k4 R. R; H

& w3 _# ^2 |& ]0×02 写在前面的话1 G% F) ]) B. \# r0 Y1 c; d

+ m, p6 Y: B/ T7 {, e$ I; a    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
) [% c  r+ t- z! g+ U/ G$ {; ~" c) o, r* T
这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强6 ?0 ^9 o9 t+ K( e" m6 l; r
5 N$ |9 C+ {: Q) O' h/ v2 U
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论
6 Z& ^5 |6 g" N3 F3 o  Q6 p; J5 O
& Z' D3 R  j) ?0×03 路径? ? ?
) R) u- l$ q/ i7 o( C' V) P# ?3 U" E6 B0 V' g! a# e5 M
    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件
) O2 Y( \* K7 n+ {8 R
% Z9 t3 x1 o: Z5 l8 A  M, u$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 q" [9 [8 e, J0 f" D( I

( K+ j* _0 n& X5 }' {* i这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的/ q! p% O4 ?& [! K- {; J
; s( }8 ]: ^4 ~% L- Q; }: W
然后就是将我们传进来的参数进行变量化+ E; R+ h) K: @: k! {; t# }5 t

7 w' F$ M  t& j. ]/ ^这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
$ D5 l. T) o1 |- D/ v/ V; R0 l5 o
4 l: e  O, p8 C9 d. l$ D* A但是接下来这行呢?7 s( H! s8 R* L# h

! T+ x# q  u% a. h. F- n : b$ l+ [( l$ K* b, h4 r5 e
, `% J2 F/ ]9 b6 v/ N
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; o: [- V6 W2 l) O& q: X; Z  \% I/ I3 s6 |0 c- g

. Q) z9 H8 N0 Y! @& F: m# ~2 N- e5 }8 l+ F) z) t6 b( C4 E0 a/ J
看看这里?9 g1 [% |" A, V* A9 `' v
4 b6 i* }2 C( r4 J$ Q4 [
这里的QUERY_STRING来自前面
  T, y/ a, m' q* r! L  v2 T1 \" W, e3 x
8 G2 n8 ?; _4 ^1 w0 {

% \( V+ ~2 ?, m* t) p/ Jdefine('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 W) P8 Z$ [: U
这里有个过滤,但是不影响
' t# N. \, y) s) q2 r8 m+ ]$ D/ n% @! m) ^; i; _* ^) X' `6 x
如果我们在这里进行覆盖这个db变量呢
1 K  w6 w" Y! q$ z  P. f' o! y- O: C( R4 W& A) Z
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
1 J( ~/ r/ I9 o& ~$ g/ d' S7 v/ V8 }* C
可以将我们传进去的/ - 进行替换
. C; N8 y* ]: Y( J" v3 J
3 O( A- o5 Q3 V; g' k! C所以我们如果提交如下字符) g0 @1 s+ W% @7 p9 `+ ?- H" r# Y

$ ]6 S* b- x" u$ n$ F  Ghttp://localhost/phpcms/index.php?db-5/gid-xd.html
0 Y% n( ^2 L, |$ ?: U; f
. Q/ o1 X/ j, t4 n6 }2 ~; c7 }  _他由于这个db被覆盖就会出错,所以物理路径就爆出来了( G) _4 o6 \9 J; h1 Q$ f. I

" w! b1 s9 O/ N; n1 e% W0×04  SQL注入!!!6 t' t" h4 P" T! @
, j  I! x! A3 F; O
  在c.php中
  e5 N; {& @. ?. c3 C6 C. J% V: s' P* v+ {7 Q
* ^$ m; l8 }1 j% v2 T/ R

5 E9 H' c; A& u+ P0 b8 k<?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']; } ; }* j5 W* `, l! H6 `6 }) ^: R

) J$ w! e' L5 k' ?4 V' l ) N0 @0 J# }# ]/ n
8 e2 K( M) w6 m6 v8 r- k
注意这里的HTTP_REFERER这个常量2 `8 |- p# {$ h8 R& w+ `

" q; p. }0 t5 U1 q# r4 `1 }- M% Y! ~: ~这里的常量是通过前面的common.inc.php定义好的8 c/ {. |; S7 l$ _
+ z/ ?8 K* ]6 P! ^, j' y9 u; U
define(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);: U( I9 n/ R/ X: l9 m

1 c3 G  T$ Z) f2 |! h没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我) @6 t+ a& Q1 B( H. z
  `% f% i) n( Q6 d/ K
然后* m  t1 `; K$ c

8 @$ @; o  y  }7 \$db->insert($table, $info);% W) a3 \& x" {# m$ ?
我们来看一下它这里的操作: _0 o2 C, g1 q- R

/ q! F3 W' b& _function insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); } / M) h8 ]% j" h' m1 y1 Q2 G

& ?  `7 Y  k0 `- A: V" j1 b8 P所以你懂的- I* o$ j5 y. t: _3 _5 `" y
+ P4 c. ?" M. G* t0 Y8 \$ Z2 p

# e: a/ z1 Q" y' b& ~# [. P# v
; S, N5 d) ^; x+ @: V附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737
7 I5 ~- `3 f& t- S' F2 N# A$ q. S0 r* W1 a  ^- q& Y% g) O1 q" L
  L3 V+ D7 j6 Z5 ]3 ?2 |3 E
; {" }  h( g5 N0 E8 w, E. G
回复

使用道具 举报

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

本版积分规则

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