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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿
4 D4 t% |6 ~* F' r
6 p7 p8 [, r5 Q7 a  \: e. h8 U9 q      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。4 Z8 D5 p0 H$ q: d& o; F
0 [# x3 _- b( h1 s( \; w% F  C
0×02 写在前面的话
$ ?' S: P' ~  t+ {4 E4 r8 Q3 n& j5 b' t' v4 v
    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
& Y$ S' B- M, W3 I* |
9 v# r1 V. s: O0 U. x这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强" S( @7 B+ @8 f( \: m9 H
$ M1 T9 ?0 b! u! i( E9 [2 a  a
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论. X5 y* u: S+ g
$ \, l4 z' `5 u3 z* b' F
0×03 路径? ? ?
0 t: v8 J  L+ I+ {( p
# ^. u; j4 J2 t, Z9 X1 F    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件7 `( X* T7 W, O# G7 P) |# r7 j
/ j' Q3 U+ Q3 L+ c3 O& E& v, {
$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])); }
2 ?# A$ F0 T5 g* ~3 n+ m: Z  P2 F7 G% H
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的
8 c$ E# V& J! |4 |0 W. ?7 r% X% C) f9 D6 ]* k: r/ y
然后就是将我们传进来的参数进行变量化7 Y& f9 w9 H% z; W

- d, x3 x! z/ R这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量/ m6 a  ^6 A$ \# u, e
# N# @# N5 F5 S2 S. `  t
但是接下来这行呢?7 l( F0 i: u! v; t

) B" `( ~6 q8 V: E1 a- q 1 ]3 p' A! s9 M' v8 c

1 x; m+ R0 {  o  S3 n, Fif(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } 8 s' `! j5 O6 C! p

, Q& A7 w, o: i0 Y , H1 q: B' b) d/ n6 Y* y. x+ _
2 z9 N0 ]9 F5 ]) F. \& v7 C
看看这里?
& T9 t! d( Q+ G) p7 R% s: u6 @4 J8 G0 w2 f9 X
这里的QUERY_STRING来自前面
) v2 k! ^) _- s$ A* @) \" D
5 N1 @# L3 d, a! _+ n 6 B0 d3 j6 t$ w0 j& f/ _  e* S9 e
' W5 |/ c9 L% J; Y6 p. \) _/ S
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']));
! n8 J1 T4 `1 i5 u( R2 ~4 e这里有个过滤,但是不影响9 S6 K5 E4 H$ m, k+ W+ P; I
4 [% x! x- B+ d
如果我们在这里进行覆盖这个db变量呢
" C, }" \% d! S- R6 Q
+ ~6 p/ S9 C4 [+ l+ E因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));4 G6 ~# M2 ^6 G% s+ R, t
: Y/ V7 v* F0 b! Z$ X
可以将我们传进去的/ - 进行替换1 T/ n) k* [0 \6 V. b! N3 b
0 J& |6 w* w. K6 j; U1 w# l# [1 e
所以我们如果提交如下字符
6 C5 i2 H7 i) M4 R! s# N2 L  Z) J0 X5 W5 G1 F% O0 l4 R
http://localhost/phpcms/index.php?db-5/gid-xd.html6 q, o* g0 f5 W4 e- R8 G3 `, |

* N( f! e2 t' e- W- k他由于这个db被覆盖就会出错,所以物理路径就爆出来了/ j# R! c6 B4 [  ^# V7 |7 w1 k

! F7 {# }& f8 k0×04  SQL注入!!!
+ _, I. U6 d; a+ v2 @0 V
  W6 Y/ S9 L* q& E- R  在c.php中+ E" `; O: \9 ~! r7 P; M
1 l- y& A2 ~- h0 {
  `. e' }2 J$ i" B* v0 G1 G) B4 E

6 J, ^8 _6 s0 a, B$ f: t<?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']; } ! y4 ]. B1 O8 ^  }, D
( y  c, v' q- e$ ~( c

2 h9 T2 r  O% K+ ^3 [4 u8 ?* E
* o* p: i/ f+ y, ]. J( B6 Z注意这里的HTTP_REFERER这个常量
  M0 A( R* a7 k1 k# o" d. w1 W1 R3 `4 N9 D. A7 j+ c0 ^* e9 M
这里的常量是通过前面的common.inc.php定义好的
" V& J( d" C% k/ o4 Q' i) P
+ W' R5 K+ u) \* H4 ddefine(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);
3 o, v# |' F0 U: h/ X# n$ A. |* b" l6 q, ^2 `& u1 o7 h2 C
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我
8 y& {3 H7 y0 x, X' p
% |2 i% W7 N" v7 X, V7 \9 ?然后# X$ u7 \$ J! c3 p( r' B
" r; U: S7 @* u0 O8 i  V9 M# l' p: [
$db->insert($table, $info);
0 a. ~$ X3 Q; a9 X% T. V我们来看一下它这里的操作/ w7 Y; S' s, g. X& D

/ }  H5 }9 S1 N8 j! G. a1 @* Dfunction insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); } ) J" C: p# W3 z1 R# g' V

- q& t; n% M$ E9 W- Y所以你懂的) X. K1 F4 X$ Z: b! S, r. y& {% q1 b4 s2 \
. n9 \; S, }& A8 f- U
! m: {8 v, {% O

; q- v! [& y5 e附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737
4 E  a1 V, U+ |( w: _4 a+ T' m9 j

6 @/ @9 N6 F0 s  T; E
8 v" a/ ?3 F- S# F+ v: A- |$ R
回复

使用道具 举报

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

本版积分规则

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