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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
0×01 前沿
' U* H+ \6 Q: M4 n, q. {$ Z+ \! y" g3 p) O0 j) S$ K
      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。2 ]: `! L3 r$ \
2 k/ q5 A- C3 r! n5 T
0×02 写在前面的话% Q9 A! u, C0 g, o! D
  U& d# u$ U6 z9 I* I) s
    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题& ^) |. `# M$ q6 {
: S) s, i" `* S; w
这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
; {& }* Y3 {' P) O& i' G- b+ E/ Y( E/ @8 Z
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论/ L8 G- j' E$ g; I/ k

7 U; U7 N* _( G4 G5 t0×03 路径? ? ?$ G# c+ h% \$ M& y% B

& i6 @5 R$ P/ n5 [    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件  [2 w8 U' f% `% l& ]' J

% m3 |& |( N8 I& t9 |' ~3 q$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& Z3 {+ o% }+ h$ R- j
7 V, q4 s! \! U- h5 u" U; Z* D
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的) o$ ]7 O/ ]( p. n; R) X- ~

9 A0 Q& y# _2 s8 n然后就是将我们传进来的参数进行变量化
1 m: [  C6 m) U9 w, i& l' z; T, w0 ?8 t- f! F
这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
; O  e0 V/ N, O
2 u7 U( q) y  ~" u# f但是接下来这行呢?3 Y$ y+ K: M/ e# K
0 ^" V- j0 ^* g' |$ ~, l

. ^; Q, Y* m" x+ K
- v& n/ }" N, M/ lif(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); }
( c! e9 y: a+ h2 |& c
" {  f: A1 L8 t5 f. [: y 3 g1 [0 e4 A7 L" Z* x# q" ]1 o* L

0 n2 F! Q# Q2 w, A7 x. r看看这里?
8 l, l5 `3 i5 d8 C8 n
, N& r" b. i1 ]8 C4 b0 G这里的QUERY_STRING来自前面
; s0 S7 q% k* u+ E
  n5 u/ y1 n8 Y8 k
! n* B# Y9 U# K5 q; G& |- ^  c8 D( \2 b3 [3 b* m: F
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']));! d& F' W# i( q6 M7 Q1 [
这里有个过滤,但是不影响
1 @* o! L1 p! G0 d+ C- S; u
2 |- D, ^- L5 j. d+ H1 q* t4 M如果我们在这里进行覆盖这个db变量呢
" q/ ]4 _" c7 G2 h( t& u* U% a- r
  l4 n: R- Z: z7 }3 T因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
. T9 z/ X5 J2 c9 [+ g
2 k# M7 p/ {& Z$ f+ C" D, \6 O可以将我们传进去的/ - 进行替换
- n+ v& V2 R: I4 \4 ?5 c% D0 {, {  D  ]/ _# A" c- |$ g! S; T
所以我们如果提交如下字符
( z. b7 p6 y; j+ ^( N' C$ A( O" {9 K- `0 v+ e: i: U
http://localhost/phpcms/index.php?db-5/gid-xd.html; C; ~3 ?  ]$ Z' q2 h

- ^8 F" e) G9 ~他由于这个db被覆盖就会出错,所以物理路径就爆出来了
4 H; n" R. H$ b  j8 ~* n0 D* l: ?% n* p5 W
0×04  SQL注入!!!* v$ y0 W5 \4 |! X

3 \, x- N6 y4 H* u+ C9 Y) H  在c.php中5 r- j8 k+ a5 u& T/ t. j0 q
/ H1 u- |' l, M4 ~

' F3 V" D2 }( `" P. \: }- n
' {( {1 I0 }% E7 K# ~& P& 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']; } 3 v6 j5 S9 q, I# t

( ]9 N' M+ d, i+ F4 o 8 E* w! E$ G$ Q

/ B$ n4 a; b5 d6 `+ d注意这里的HTTP_REFERER这个常量
$ q. [3 l. M: B3 z( L  \! v* U, a% n: k9 O4 q& C
这里的常量是通过前面的common.inc.php定义好的+ |  Y8 E% P" ~; t

, t' C( ~; S; b) g$ n. g/ v7 ^& _define(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);  d. s) |, f& e
/ ~% g' n3 p# H  j/ k% N$ G0 K& o
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我  \6 o& I, T1 X2 x# p" V! K
) [+ O& r3 p) s8 t
然后6 _/ F2 h+ E* m4 @* I' z' G
6 h! X, U" P, {- E: X  A
$db->insert($table, $info);' o5 K8 I3 S& L7 v5 M2 j+ D4 T8 J
我们来看一下它这里的操作
/ O/ D* B2 W/ O* X
9 {' x( x0 f9 t- M# Jfunction insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
9 F: Z0 q- t! S% Z# ?6 J! w$ v) L9 z5 ?8 I0 {
所以你懂的
  e8 q/ V, Y6 |
: i4 _* e& ?" r) R7 y: y
8 @- P# `  e" W2 H' b: n
; [9 G( F* U; @1 U6 e9 \附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737
! W6 y5 @0 T, n, h" J5 a
2 M8 Q7 g( Z7 H% V: j& g  j5 s
& p/ c+ s* F3 |4 D" O# D2 T0 t% c4 z2 h4 ]1 @1 \: d
回复

使用道具 举报

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

本版积分规则

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