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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿
- x5 d% e: e7 S2 ~" I1 G6 s/ b0 [0 e/ i
      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。  J8 Y8 \' U: `" e2 t- m8 d

4 o! C9 F. `' W0×02 写在前面的话
6 _0 t8 c0 ]* i; V& u3 o( N
# o$ }. c3 i" T    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题% Z' Y2 Z. Z! H3 L: s/ _& Q

: e# J. v: Y' [, F1 M! N这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
/ Z8 T2 Z6 E+ Z/ s
+ F; ^; G; Q( y" f( g  ?% X! ]这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论6 W0 f7 I& ^# \  G. E3 Y3 X& {
! v$ j7 d. |1 q. H: D" y
0×03 路径? ? ?3 X' q0 \1 Y2 m: Z# z

! R% F5 s$ i$ U& ~! x; H    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件
/ p) J! i9 a# v. ^8 F
# Z* y$ ]; D$ s3 V8 ]$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])); }
, q1 ]) i1 l" B, N
! g; x4 M- P( X! p- l这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的  H* s) C( @  ~8 @9 o- t

1 y& f. ~3 G$ O然后就是将我们传进来的参数进行变量化6 v0 H8 ?6 g! y+ M* L- w  J
: f' D$ @4 C; R6 l- [
这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
6 T2 ?9 [; a% p, U2 k/ r, G! d8 S8 c4 a
但是接下来这行呢?
( m8 X6 S5 L+ M5 R% D4 G1 N
7 U9 W3 L7 _9 B6 z ! {) l4 L% l- t5 X" d

+ t3 K% e1 _9 t6 T& ]if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } 3 g6 u* U/ r7 d9 ^4 U  `; @
! V' R0 y6 `* [# U3 _# w
% Y  g6 y5 J$ ?9 }
% L/ @( ~7 I4 W; A9 h
看看这里?9 T- w: D6 C" {! m

( f$ ^! q/ t+ E8 [/ X这里的QUERY_STRING来自前面( f! d8 [1 p1 K, T/ V( L' M7 [

- P) s+ P( V' d2 q ! c$ ~; f8 R/ _
6 @  e! |4 y* c/ ?# F3 ~; E) N
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 x9 x2 r- W! V0 w: b4 E这里有个过滤,但是不影响
9 \9 P: X0 \& q
5 o3 J8 K( H7 L; M8 h如果我们在这里进行覆盖这个db变量呢
: [- L3 p) ?* l# l1 d7 o) V; C! t2 _3 C! V: Z8 z
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
8 ]" H6 M4 Q/ Q7 A# A
; f3 z- |' n6 g0 i4 |0 c可以将我们传进去的/ - 进行替换. V- P7 G; ]# u# K8 G
4 P4 z4 R! u- Q3 q/ K
所以我们如果提交如下字符0 P; g9 H" F0 ?, V' J
# _( @# I0 ?7 q" p
http://localhost/phpcms/index.php?db-5/gid-xd.html) O2 E5 w# X3 F

" i1 |* U  Z) H% T他由于这个db被覆盖就会出错,所以物理路径就爆出来了: g' p! t' j1 a; D+ [2 _2 p# |

- d$ N# J) ^, b3 ~" t! w0 h+ v. i0×04  SQL注入!!!
/ H0 k/ L& [, l, f$ r! r( k9 g3 x& Y
  在c.php中
" a: ]1 J# B" n5 v( K( y+ L, ]' t3 L" `' i! d% P' ~1 T
* E  d. t# J* j7 p
+ @6 Z, u) |* h* g5 B
<?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']; } ( I+ p: g& A9 l( p9 S" M' J4 [2 \7 L

  P3 h1 G6 C/ |1 D ; j# t+ l4 F' O0 j+ H

. X8 p/ D& ?$ B注意这里的HTTP_REFERER这个常量. v& h: e" ?# e4 y
8 A) Y4 x4 |, ]8 V: z* p) q; F
这里的常量是通过前面的common.inc.php定义好的
$ b" S6 g6 M3 Z1 C- A
1 o+ k/ v& \7 U; ?8 U8 \7 r. Odefine(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);
5 |' [$ {4 d1 e$ S; F/ T
8 y8 B8 N# E/ W3 e7 Y* [没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我, |# ~4 c; N+ j$ G, i
& A. q! {, U2 R7 C1 @0 R8 h% E- ^
然后
+ J  P" h2 Z2 F  K, U# F+ v# O2 K  K& \" Y$ I/ B/ j$ E3 o+ Q
$db->insert($table, $info);+ p, H0 S$ H2 P# Q* P$ U/ ]/ F
我们来看一下它这里的操作7 w  M7 M/ n- y& }

6 {* p3 W8 g2 [' }7 T% o& rfunction insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); } 9 f9 s  Y0 S" C% t. P
/ e- z  J: H& V, _
所以你懂的
8 j0 w) e/ G# ?: B! A  Z8 _, ^' `3 q& v; [" ]5 T$ d9 v
1 q0 ~) e* P: Y! F9 v

! x) m4 w* o, [. {. p8 y- Z附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737
) `, A  t* u4 X! H
4 G$ E6 Q2 j* M( F: v6 n
2 c$ z9 b/ N; B! n5 m1 R! E! z5 U$ h
7 t, e+ A5 H* B% E( q' i
回复

使用道具 举报

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

本版积分规则

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