0×01 前沿
+ t9 {" K2 _) ^& {3 L
7 c/ l$ `3 T! W" Z. {- w- S7 f Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms 采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms 团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms 得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。
5 {! I' P. Q) ~; q @( Z9 p. }
* {! x- Q& t/ U, ?# m+ C* G7 r0 O0×02 写在前面的话 g6 x9 b- K( Z$ R8 I& a$ Y
v" f+ c; _8 b4 k3 Q( d phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
! M% F w/ P) C+ P# W" B4 W7 Y- G; u, d! C+ ^! E
这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
6 F) _+ t0 j+ K ^ m
4 t. l( ?, n6 ^3 P. N* J6 e这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论& k8 C; g5 n7 ~9 o& E4 E* z
1 N/ \" R9 F8 z& n! P, p0×03 路径? ? ?, ^/ v- y1 U1 e5 A5 E; B. p9 `, S
6 i" \. }9 j9 u5 E$ [* L
在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件+ @& Y: I* f3 z2 K6 U
1 g& T3 A" Q# 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])); } ; E* T. W7 W) m# v0 n! ^
. i1 m% {/ [ `# F
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的7 C+ }1 Z3 ?5 ?) o$ \
+ q+ x8 T' j5 j& ~
然后就是将我们传进来的参数进行变量化- \! R; [# v) B1 J+ o
- y" R6 `) j0 p6 ^2 i+ k; ^这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量' {/ j. Y. \9 T6 H. Y- }$ G, j; u
1 Z( t& D7 h( |但是接下来这行呢?
8 \0 h3 x2 c5 @. u; ?( a$ X
2 Q0 B4 w8 Y3 \2 X- E9 u
+ T" c; W! Z2 Z
4 G7 r0 t9 X4 [( mif(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); }
$ ? G" q% Z4 j
. B: k- I( z" {. Z: i
; l. D. K" j- n& Z2 ]4 P
# S$ k M) ], q" b看看这里?/ f* ~! z8 `% K& l1 N+ _
& c$ Q* E0 W' O3 j5 j9 h4 T3 W这里的QUERY_STRING来自前面# ^" R+ d! h7 Z
7 W' r3 l6 U. @ A1 G# |8 G
9 Q# G: W9 I6 ]; k$ _
! U. n I2 l1 _* Gdefine('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']));! L. b8 h$ s$ x' k8 b/ X
这里有个过滤,但是不影响
" x7 t" P6 Y! R7 W. h x
! p. w# e! H$ L; D5 l如果我们在这里进行覆盖这个db变量呢4 W) j8 o# u( Q' O* i
8 W# `, F( C; H因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));7 J0 B/ K5 k# W7 _0 d4 X! @
" Q& X6 }+ e7 m, w; D. i
可以将我们传进去的/ - 进行替换
4 B% H! v# X/ `
0 J' r! \& _+ @- p所以我们如果提交如下字符* _$ U4 t) x: t& n/ C0 v
( E" f7 I) s7 e; vhttp://localhost/phpcms/index.php?db-5/gid-xd.html
4 b ]1 k; {0 }, e4 V7 r
+ ^; A8 S! ?1 |他由于这个db被覆盖就会出错,所以物理路径就爆出来了
$ N4 n3 L2 }5 f1 W4 U4 i* k
# C! r' W6 Y. u6 I& X0×04 SQL注入!!! T" D+ x2 `8 g+ Q
! h* x2 u1 g/ @; }
在c.php中+ G( F& e1 u) i
9 Y9 l5 d0 ?7 ~" G& H6 H0 [( s
9 Y5 m/ ^" Y* E1 C* r
# _; O/ m' D/ D4 E- j) }7 H<?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']; } 6 l# \! C+ J4 ?3 u- v) w
$ E5 f, Q$ x" q* V, Y( D" y8 g' f
/ c9 D+ \4 G- H
( y& f' u9 a4 d5 d3 l' Q5 u注意这里的HTTP_REFERER这个常量/ G0 r" p0 B* R. T. i! l. e
$ H/ [1 B' Q7 M4 d6 S% N, f- Z; W: a这里的常量是通过前面的common.inc.php定义好的
+ I, O! `- R* g6 m
" _5 Q5 x. {1 C7 M c( Z# o# adefine(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);9 R4 ?$ @( l0 @* S6 F; B
* R* E# I) O2 h6 r B+ X
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我3 E6 x4 s" c# L$ D9 ]3 \) q7 ?: n
5 v- g* d# r, K
然后" d7 N3 k6 D" l1 J
, l* A' I2 Z* q i; r0 `. p3 @
$db->insert($table, $info);
( }; t: J: n" t) T8 ?8 U我们来看一下它这里的操作
1 t/ h) B4 v& ]# s0 X4 k$ d* l: b9 m! W, S$ U6 d
function insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); } # j* t8 O- Z8 p( C+ k
- I; B. V* A; {
所以你懂的
r/ A! C" z6 r N% T {. D, j |
2 y! G) A: b* N% ^0 z" f
( U3 H) M4 ?" q' P: Z3 \/ u5 V, q8 k) [0 B
附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=40456377378 S# Q+ y5 a) G6 I. c& W
8 l0 S6 x! X5 r* t( l. G: ~/ l ( m \# c6 s: z! e. G0 X3 ^
) h$ R& u. x0 d a; [
|