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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿8 G, z  O1 n. a; t2 `& C
' R2 h3 j! R+ d( v0 B$ @
      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。
& B: W& ^( Z3 _* M$ [7 I+ f2 p
9 [9 p. X$ ~5 M! z- h0×02 写在前面的话0 n6 h2 t7 |$ J2 S% M# |) l4 s. r

/ o' \6 @8 [( T8 e) l; c8 _    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
) l/ ?& _8 q) f5 w+ m$ G4 S( k
2 D0 @; s2 W) p这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
1 @; K" T( @- e( k- ~+ o" |" [& K  P' a0 v. z% Y; H( O  n
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论
' b+ [& E8 T9 T8 i
# Q% R; s: m$ q0×03 路径? ? ?
% `5 S  B9 z4 Q- E/ ~- @3 U
! j. a1 F9 V6 u1 a; Q+ h    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件& i5 G0 u) l- W' Z

- ^7 @7 A- \' F  Y+ |! d$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])); } . U6 ^1 N* A( H) I
" z" H: F% d8 v5 y. h2 r5 V: v' g
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的
2 Z: b/ V2 T# W1 I) Y+ l) `0 F  x6 G2 j0 ^2 R; t8 `
然后就是将我们传进来的参数进行变量化
: f) O1 s+ u% a- j# S( [9 o( j( u" A% H1 o+ q, ^
这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
7 `( C/ ~. R2 g% A9 v% A9 ^4 z8 Z  L  K: P& z' a$ m0 l1 b: `/ ~
但是接下来这行呢?
! g  Z* ~7 ]$ A2 a! Z! j- p- c# o- \  B$ A7 v

+ K) e4 d9 ]' S- e; q& J; Q# P& L& p# z
if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } 2 `5 x% q$ P! k" w3 C! w) g# O

3 h3 n* \' T. X2 B& U; ]+ D
" L" m( |5 w% [$ i! ^; _. E" Q; U2 m# L( l( W. d( M( g) i# Z9 e9 o
看看这里?
# a( |! D6 P3 K- s3 y4 i
* K" q2 u( l8 }0 W8 e- J这里的QUERY_STRING来自前面
0 f' ?' v9 _8 s1 z5 M. y1 _! H8 E, B  o- a6 m

- n7 B- \& S8 ^! e6 T8 T, v& j
4 x% ^/ ^: l" ~" c! cdefine('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']));" r5 ^* R; T1 Y2 n9 f7 B* h. C
这里有个过滤,但是不影响: \. b% W, q% L" l" d/ _+ a

  X* ?3 z, r! H- v& t$ R4 _2 K如果我们在这里进行覆盖这个db变量呢
" J8 {4 D0 t) \: C0 j
3 |: |1 E3 p6 B1 [因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
1 @! N4 j5 f6 y" A# K' n/ Q* t( t2 {
可以将我们传进去的/ - 进行替换
, ?0 {8 ]0 f9 r2 G7 K$ v3 L7 W" c' O8 Q5 f& K0 I
所以我们如果提交如下字符, Z4 A+ v& K# K' E& H& E7 \& f

. M0 s8 s' M1 L2 I- I( Vhttp://localhost/phpcms/index.php?db-5/gid-xd.html
3 `  o2 q0 J) K  ~$ ]( I6 J) w) K0 M6 _- i" f3 C
他由于这个db被覆盖就会出错,所以物理路径就爆出来了+ a0 i. Y( h5 k2 _  \

& e: R  z' o! d+ l% c; {  F3 m  y0×04  SQL注入!!!" _6 L2 S9 T8 m* r, ]4 O

* _  r$ w; X  ^  在c.php中
2 ?: i- Z7 w& V" f9 b/ H. f: x4 }& G* _* a, \, L
% `7 K5 ^6 H6 e" F& {
. J. r; d9 n$ y+ c
<?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']; } ! G7 O4 a9 b5 O9 X) B
  X8 ^: ~6 p4 Y- S0 W

2 ~0 ?1 _# `* O+ N3 r
; |3 x2 U  {. F3 E注意这里的HTTP_REFERER这个常量' Y* O; v; J1 h0 k& q: m( C) F
6 t$ O6 L* w; u+ }4 j1 V
这里的常量是通过前面的common.inc.php定义好的
1 V/ G9 E: i; I  F6 s, S# N* _7 R9 _- H8 `3 E
define(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);
8 P! z9 [4 C) y% F' n& n- i6 ?. b. H7 F
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我5 w, h  p% |0 E  R6 L5 k

1 y  E" K5 t( P$ w$ j, I1 Y然后. }0 K. y! `- V0 b9 F% `; [, h' |

+ J" X3 V6 t0 m$db->insert($table, $info);7 q; N/ {0 ?% t8 r5 H
我们来看一下它这里的操作' q- |: J. e5 Z- \. E

: G$ k3 W) Y/ J- D% {! Ofunction insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); } . @' [- o, D; p7 p
5 w' ]& {8 O1 V
所以你懂的0 s# ?+ G" i0 u
# k* H' s, u) }1 X/ _4 i
5 [- F* j( ~' `5 Q" H, c9 |
9 F# ?* R* u: |+ h0 v# P
附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737+ r8 U" x( `1 x8 y* F

6 P8 o8 n7 B8 A7 h6 Q' x; o+ T
; V5 k& e* c* |* H% m4 c) A
: W5 d4 c% m1 K' _- f, M, h9 Y1 T, a( b. k
回复

使用道具 举报

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

本版积分规则

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