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

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

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

1 p$ v, o, A1 r9 C( P1 a0×02 写在前面的话
# g: O" F# M' i+ J: g. u8 d; f' h* s( ?' g2 l* ~
    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题3 H$ X$ _3 V& i8 |) ~6 ~
- w) [1 O' j0 E! c" P; A
这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
9 R7 P& ^9 ^6 w2 w* Q$ S. N, u4 H+ t
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论9 I# ~$ t7 {' T6 z# s1 N
5 q' Y6 r! }4 _; P! @  [% D: V
0×03 路径? ? ?
% E, S* G7 _7 Q- p# l+ J, _& R0 b, Y5 r4 P
    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件
" e5 q, F' m' D9 J5 L: B0 \; J2 ?4 D- ?! n0 \. H: K
$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])); }
* T" `8 j* M; j! d2 g) T& \5 `
3 w% h6 \9 x; z0 |0 A* `% ~# ]这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的
+ K9 e$ K2 P+ l$ C; u1 S/ u! H' C/ P$ T0 a) ?: @
然后就是将我们传进来的参数进行变量化
  d# J5 F# X) E# f+ Z9 n" D& [
2 Y: V% l! a' H7 c- Y这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
7 N9 h. q' O: W* U3 {3 n# r1 B0 d* X- L1 H# `! h% [0 P' ~
但是接下来这行呢?) A8 p1 w& w. b5 m% `7 h; L

1 [4 ~: w3 N8 \1 E4 m2 t+ E & S, Z- Y% h9 H) e( W8 F, n

1 ~) ]5 k: l# nif(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } 3 z  a, c9 f* X+ n
( Y" n3 ~( L  Y6 T2 F$ W* `

' f  j# F( }( v4 R2 l
6 V3 w  \" A/ P0 S看看这里?$ g9 j/ C6 |2 h4 o; e3 U

$ B# j1 U" W% X, H! B1 b% S这里的QUERY_STRING来自前面* [3 G; h3 X6 D6 K( c: q- j
1 B7 c3 i: N0 l% ]* g
- ~  Q" Y- ?# n, N
# M# Q2 d. T, w& S
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']));
9 G7 o+ J9 Q; o( z这里有个过滤,但是不影响
1 `! B: l8 y, B1 Z1 L0 v5 ]% w/ x/ T* ~. k0 e. Y
如果我们在这里进行覆盖这个db变量呢
( }' {- m! x4 g) D4 e& T9 o6 }5 X' I9 [  m
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));% ~. o4 m" \7 O4 s# |8 p
. e( ^, q5 o2 d- ^7 s" t
可以将我们传进去的/ - 进行替换
7 V9 w' [- Z3 Z& u; J' C% f0 i
! `0 t0 ]8 W2 u1 X9 B所以我们如果提交如下字符% |- o6 k; O- O2 S  w* C! f9 ^

% E5 H; A. @% ~http://localhost/phpcms/index.php?db-5/gid-xd.html% g  P5 t7 o! n/ z! v7 L' S

! f/ u5 t3 z1 k# }. z他由于这个db被覆盖就会出错,所以物理路径就爆出来了
7 {. R) C( a$ @! _, {# N; B& A& u; J+ T( t4 n
0×04  SQL注入!!!6 `$ ~% m( d& G  l
9 C# i# ]* K# C0 d! H; O
  在c.php中7 N$ V1 @+ ]; a6 ^, H8 L

  Q+ z  O) L6 J/ `0 J8 F ' L, ~: x* d, K, j8 C
3 b. H9 v7 N# c' s' R: |) ~0 x
<?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']; }
- B- j0 R; v7 h- d6 G" F
3 [/ k: t+ T% c
7 }/ ]6 s# L/ g: R* G$ v, e3 i+ L6 T" C4 x# U1 V0 D9 D% ?
注意这里的HTTP_REFERER这个常量" t2 k; J6 n5 l% @5 Z

7 T2 J9 Z% l# c  l这里的常量是通过前面的common.inc.php定义好的
- H! X: _! f5 U# {+ f# Z$ R: J/ K8 a2 `  A5 ?% |7 p9 F6 ^
define(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);
/ n* _0 }1 B7 @# ?8 d4 r
* C# U* o  X% f" h2 g9 T9 n没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我; }2 J6 o/ w" U( L9 O
. s* H; w& }" B$ h. D0 ~# B
然后
! M9 _/ ?  j8 m2 s; j) A1 {. e% L/ v% v( c( n( Y, S
$db->insert($table, $info);
- ^( V! x  b1 C1 q0 ~+ j我们来看一下它这里的操作& A! s6 b" \4 G4 q

$ q/ U9 _: H+ _1 D/ yfunction insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
0 l) C/ `/ z  m+ f8 o7 S/ D: ]9 Z; V) q
所以你懂的
1 H! g* M) C- U. W* F% @' b/ B+ W5 U4 u7 Y1 t
3 v- p/ s. j2 z2 h6 K3 V
6 y" k8 V; F7 m$ U2 N# ?$ E: u5 b
附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737  E4 L' V" q* ~2 C4 q2 i% Y# K

* @) Y9 |. R4 K( [0 t, i   L( ~3 ~/ N( E4 `
8 }/ E4 i+ R9 C
回复

使用道具 举报

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

本版积分规则

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