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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿# [* [' M2 J" [- J  k% ^
# T9 {4 ]+ d3 N' i/ |
      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。
0 h! K2 f3 m/ R2 J4 i- C& T" ~0 X6 V0 y
0×02 写在前面的话
$ r" ], ]% p3 ^- s
  r+ D% I% p: s& e) y1 Z    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
8 u; k& o! I7 m7 ?% ^7 v5 V; r4 A2 y: e5 g1 z
这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
* U0 w5 `% p0 r1 F) o$ y9 h: W: ]  z" z% S+ A1 e0 J
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论  M# ]. }+ w: G+ q( X

7 B- Y) Z" d- l7 \4 n% l8 A0 X# J0×03 路径? ? ?3 b. B) C5 H* S6 @

4 ?% ?* X0 `7 T, L9 ~; V" G7 Y    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件" h( H$ P* N7 }7 Q& V3 ?2 c

/ C4 w, W  `3 o# h1 l1 G2 s$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])); }
" p; @: k6 u( A5 t2 N, I$ a4 n( v9 C/ x: o8 y. K
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的
, }# r( z( G8 t
3 z: w5 _6 g5 n# E3 o6 r然后就是将我们传进来的参数进行变量化
7 q0 G' {. @$ `. X# ?! I  t# m1 P8 v( F5 E- Q# E" r
这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量( J  D# A+ x2 T/ S. K

7 I& Y# O: A8 f但是接下来这行呢?0 Y8 B5 W- I, u' j) b

" o& }6 a2 w; T0 F+ ?. c% b  u
% E, `% j, d* O  p0 B
# n+ C! v% m+ O# {" Cif(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); }
) n5 e# d- e0 [! E$ t
0 F- `) f8 {* o0 c, d' v" M : J) c6 L6 ?3 p% O0 \& }# [
, p" `* ^7 W8 B
看看这里?
2 E3 _3 N# O; \3 h% g3 P. q! H: P# Q  y
这里的QUERY_STRING来自前面
! m; W) r" G. u3 Z6 _* |+ B3 H) [0 E7 C3 S# U5 O* `2 u

- ]4 y- {( W3 n9 v/ ?# a* U
: i, p! u% Q0 Adefine('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']));
& B9 A1 ^- [" C1 J. S这里有个过滤,但是不影响
& @8 F/ s$ b2 Z/ G7 u4 T( N  b6 o& {0 D3 }4 z# ^" f
如果我们在这里进行覆盖这个db变量呢, [0 b7 ~; \6 h& L

* W" k' `/ e$ l% V6 K6 l因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
. T* L8 e# w# R+ l0 i9 y* r. B4 f, K' [' H( a& d
可以将我们传进去的/ - 进行替换* ~0 ]( W  f- \3 {8 s5 P# |* y

5 `! L. b) D0 m* }; D& m7 a) Z% N" }所以我们如果提交如下字符
; |6 @* e$ Y4 H3 U$ B' q
4 M& Y6 J1 A/ I* d, }http://localhost/phpcms/index.php?db-5/gid-xd.html1 k) R' a* J) n% x0 G
& @) W( ~! ?  }  v0 Z# M: A% }
他由于这个db被覆盖就会出错,所以物理路径就爆出来了: J5 ~2 ], L( I& e7 x$ A5 c( M3 M
! C+ ^( n' A; I3 G
0×04  SQL注入!!!
& Z1 `& R: T+ ?+ P2 X# C5 B  w0 \: R- A# y
  在c.php中
$ B& P  O' R$ ^* I  _6 y! y5 t+ {6 W. K; D; ]7 N! x1 Z

1 x- v8 y1 p& g; s$ A: n
& J- [" D/ B$ `' S- S8 `7 v<?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']; }   {2 d1 Z- ]* v
" R: y; j! @. z: y

9 }4 d* ?1 ]& S% V
; Q  r8 K! D0 r, P* w! N" f2 U注意这里的HTTP_REFERER这个常量' u. V* F, h4 ~7 d( a
. o& M* n6 x) x4 }
这里的常量是通过前面的common.inc.php定义好的
; `" v! G$ X# Z/ G* ~! n2 d9 o* I; {4 N5 `5 j1 C
define(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);- q9 V, m# m& f0 W; V; S6 t, w

) }+ D% y; x, D, b4 _没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我1 Q7 W8 {& ~3 v" x
; u9 a) G" ]% G/ U1 x, }1 z( y
然后
7 U9 ]4 |. A$ e" y0 E9 y% |
" u# T3 t+ I2 H8 K8 q$db->insert($table, $info);
3 @& |2 k% r* P7 |我们来看一下它这里的操作' M  I$ u" ]- _1 {8 j5 A! R
; m/ _' G: c% n) o/ a2 i
function insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
4 [/ n# R! j3 D+ x- X
$ g: H/ t, u9 O* {所以你懂的
4 C2 e1 s: _' L' @8 d( n! z0 E% f$ g, F7 o; |

% s* p! R3 p/ j( S  a" {* n, n# e9 f8 x1 v" V( o
附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737
- L! h+ `/ p! s) [5 c# ?7 F2 {' ~9 Y% ]* k* @. s( @; a$ g7 P
# J, ?, }; s8 k2 W

' @- d# R( o9 ?9 U- w' h1 Z/ W8 }8 T
回复

使用道具 举报

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

本版积分规则

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