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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿
9 a1 C: }1 K+ R( M  f" D$ q9 f* e6 x$ I. O( `0 I5 ~/ \' L
      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。
4 F0 r. \8 O7 N( D3 c  G, E( W' S  S1 z" ^
0×02 写在前面的话( @/ D0 S  S& A7 k2 e

9 m- W. u+ y7 ^/ w* A8 y: S/ K- H    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题: i5 ~2 O$ I, x) g% _: B+ a, ^, K

2 |; N& `+ D# S' X- d) |这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
* s. i. c6 b6 m" F% D0 z8 m
0 ?( w5 m  _$ b  |" f这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论5 U7 e$ s7 t2 i  ]0 Y9 s
7 t5 G/ G! T+ z1 d+ ^
0×03 路径? ? ?
) N( g2 ^* F4 u5 O/ q  }5 S: f. w, O: M7 Y) ?
    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件! @& q: x5 e9 y6 q* q

, f  Z5 ?, H2 \2 c+ Z( 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])); } . ]$ g3 P# }5 L* q+ a; [

1 l( z8 i# U1 ^  [1 I1 b1 i: S这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的6 V/ n% P; R' \% p* r

1 c* K, ~. B% i0 Z1 P然后就是将我们传进来的参数进行变量化* y, ?; h3 M* U( I

. Y, j' A; I0 @这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量- n, X- p# y  d- o* u* q. S

2 v, w9 p2 k& X* E7 B! k5 E但是接下来这行呢?
, z3 P) l9 t0 I; \4 X
% {( h+ a) }# }4 Z
% T# n8 u' p3 L( X, M# P: i
5 ^7 t  O; J! o+ d9 ?$ r9 rif(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } 0 m' J& i# |( L/ A- L# u# L; e
, ~. y# _: [$ {2 x" {' ~
5 `# f& J' w( F

9 L5 t! {: I2 ?5 E看看这里?
5 J- i6 ]3 s$ T; R# F
3 D% P; n- \' p2 T; ], W1 p  p这里的QUERY_STRING来自前面
# D2 y% Z% A8 \0 R7 n9 K" B, @% F' f) Z3 P( @, o
8 L' f8 J8 D7 y' K& [( ~4 C9 u) H! c
4 {0 Q  }8 c; T! U. ?4 \
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']));
! p1 w5 a& ^# T# y' \这里有个过滤,但是不影响
& n6 }- X6 f/ K5 D5 `: ]( y
' D& L  `9 p. Y$ D, A. B% e* E如果我们在这里进行覆盖这个db变量呢7 g+ t5 t. |9 K, m. @& j! F
7 r8 A1 x6 C: }' W% u
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
4 H; z1 t; b( `  L% B2 U( l$ [3 R% M1 z1 p1 D6 m
可以将我们传进去的/ - 进行替换, ~6 g$ w) ^: Q% S2 V- }( l( N( j
" R: `# ?/ L% `5 N0 @
所以我们如果提交如下字符( F1 F. `6 P7 V/ n( }+ ]* T4 ^
. M' V$ R" q: q) H/ J
http://localhost/phpcms/index.php?db-5/gid-xd.html
' t, C+ n$ L1 h& d" B2 G1 s0 \6 ^. g  I, p% }0 B+ n
他由于这个db被覆盖就会出错,所以物理路径就爆出来了# `8 r; C9 b# V* J
7 y5 Q6 X1 o5 e; t5 ^- f; A* s
0×04  SQL注入!!!
6 J+ t! {1 s" j) |2 l. ^* G4 `( h2 G/ e& y  o& h& p
  在c.php中5 N+ T  t  H" X) b: ?
- l# r$ ?- n) h

. \+ s) K) M. C
8 |! \5 a! V% u. W0 _<?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']; }
5 W) C( P. |1 D* x. C, F0 H0 c$ c- T" ~$ a
0 f, F+ e( R$ Z, B& r% s

8 I: z$ C* Q1 N+ f- z! o0 j注意这里的HTTP_REFERER这个常量
) X+ x- l, Q! w; U% I: |. I( U7 l0 g; S$ B  s; v
这里的常量是通过前面的common.inc.php定义好的, P! z8 S% e1 t) a* I

* ~/ B- Q/ K" `# ydefine(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);+ o3 e( `, |0 @4 v
: e  n2 `- D3 u7 u, p& H
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我' W( G+ @% f- Z( P9 N9 C
! H5 u5 [: m+ z
然后% j: k! T% k' \7 Q( E
- M  L* O! W  E/ e' I4 ]
$db->insert($table, $info);
- _! o9 \4 V% a9 o1 O# x3 z5 ^我们来看一下它这里的操作
3 K4 J  `  Q) l) n9 ^( i
% v# l) j9 Z7 N. jfunction insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
# P' o* \0 i/ K# r: [7 }" n! D
# m& U% N! ~' h8 a; T& J所以你懂的
7 @+ s3 i  N1 _) L  }  U2 G. @. w
2 G9 L2 j6 J* N; h5 A2 U2 r, a3 q  o
% A, K- C; @$ P) a" e
1 g5 X, x. \' L$ V$ n$ V附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=40456377374 h* {! N7 ~. j* Z) \! y" z( Q. r+ f

/ i  ~; o, O; M# c
  ^: E7 X; R. w5 ]
# }( G2 Y5 Z8 V: X
回复

使用道具 举报

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

本版积分规则

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