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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿# f+ ^$ z' [( n9 V" X: `

5 [1 M# D/ Z7 c. d% H+ L      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。. p! Y. Y6 @1 w, M& X. H6 z

6 ?% m$ y+ U, H2 g. y6 ^0×02 写在前面的话& W0 D9 T+ R* W, j. U4 {

+ d; V& @$ b) P8 T5 b* I    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题6 x6 c6 X6 Q* Y4 ~1 ^, E% y
  a# D$ b* I: |# N+ M
这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
( F  L9 N/ x* s) S7 \' q% I/ N% p+ f' A
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论
  \1 n- D# }# Z1 \1 r4 ~- s, a1 z' D! H; @( H0 ~! x$ h# j
0×03 路径? ? ?! Y  t6 m' X& L% c

) X& ], A% {: A. Y0 S9 p# i    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件
) Y& P6 ~5 B0 W6 c" Y) d% u6 Q* Y. F/ u, y8 x+ R+ H. i
$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])); } 7 ~; H  q8 t+ N& W4 y
! E1 n- {8 a% R- C* d% g; m3 z
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的
; X2 k! C% h& h% A
6 Q) X+ M3 G! w7 `9 \然后就是将我们传进来的参数进行变量化, A, o8 i8 U* ?5 S6 n; D+ [& P1 o$ v* t! K
1 b! p# m6 G" {2 ~6 A
这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
0 k# b9 A! e  }1 z" y0 |& r  ]# J# w  s" L4 D" s
但是接下来这行呢?
8 q$ u9 e6 W% X8 f) a$ |4 X3 t6 }: |) D/ _! i; M3 Y# @

- t3 ~5 L+ c% d
" N5 J3 t; T' y3 g0 `) o' Yif(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } : {* `/ }. |: Q$ D
- s& M3 o( J- X0 E# Y0 d
  M/ q- o. z" I# k& r
6 k$ X0 W) g7 E: i; {/ Z$ ~2 \/ A
看看这里?
; p) M" P- ]* g" I/ M- |9 n) x3 \, C3 r# P  B
这里的QUERY_STRING来自前面
5 v. J1 l6 w/ j* B4 F  s. B; C  J6 c0 V7 _  \" T

+ B# A, K$ B6 b  r1 ]- ~# q5 K' L3 ~: s: G
& V) W- e! W6 _2 Z. {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']));& I5 Y9 p1 q% ~) [2 O
这里有个过滤,但是不影响0 {7 W5 ^: `; a. f/ I. i
1 _; s. R. m. e5 w- {
如果我们在这里进行覆盖这个db变量呢
: \2 }* ~3 R. T
6 v0 X4 S7 G; K, |因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
0 W" J) g( q  r8 K% \3 ]6 |3 ]+ U% C$ K' Q
可以将我们传进去的/ - 进行替换
/ c) h: {9 ~& M' w+ v7 x! x; ~! |6 v# f  ^
所以我们如果提交如下字符
9 G3 L, D; n5 w: Z
2 n( T2 C, W; Whttp://localhost/phpcms/index.php?db-5/gid-xd.html9 K0 c; F8 A! m) f' I. Z* D

( ^" P7 A+ C/ x* S他由于这个db被覆盖就会出错,所以物理路径就爆出来了3 W8 b7 c* L7 Q/ \, X/ j- |6 T/ o

/ M, T3 O1 P7 Y: K' p; d7 h# e0×04  SQL注入!!!+ y1 ~  Y3 s4 y* K/ l

% W  ^6 o# U" g+ ?- J; m  在c.php中- S- T+ @0 }- [8 R0 |
& L- N- \0 @7 w

3 _  c" R3 O2 L  K1 @$ Y7 i5 K' e! u+ _1 f- P
<?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']; }
5 S& C0 H) `; ?! `: J% [( \+ S
) a2 H3 g  v  m+ I8 r# }! E   r! F+ S+ }5 G8 }6 w  }, ~: ~

+ {: O( ^3 `7 I! U! ]! [注意这里的HTTP_REFERER这个常量2 X( R. A& u( x, H

" B$ u4 w/ m( L这里的常量是通过前面的common.inc.php定义好的
) l6 u( B% U, y# ~
$ s0 K- W, C6 Q: M+ L3 t3 Ndefine(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);% q/ v% o4 t6 N& o( Q1 m5 U7 M) ?+ Y

7 E+ c/ y  F2 S% K( F" M6 z, g没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我- g; ], W: X* B5 M6 w: Z

, D, O4 p; o0 c5 O, Z然后1 g7 c* P$ k4 \7 G1 Q/ i5 p
5 L: I# a2 G# ~2 j3 A/ u6 L- s) Z' E
$db->insert($table, $info);
) V5 L* k2 b5 b7 @我们来看一下它这里的操作
8 i) O% e' p2 e7 ]% `& e7 J3 e
+ S6 ]& \, A* P% u: Jfunction insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); } - {$ }& d/ y+ x$ B. e, Y
% H6 o6 O, ?1 z/ f, Q
所以你懂的
/ N* a$ j+ ~) b8 a3 d* \0 h, L. ~6 M- \

  }* O# F+ L4 P  {  u0 T. k( d
  X5 m) N: `7 |; N! f4 D/ J0 Y6 ?附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737- [2 x* i& \6 X+ {+ r" w' O

, K; A; S5 o2 a- ~4 ^8 K1 `. I
& j1 z2 U0 |' _% F( @) A6 `2 v9 ]! }( B. ]4 s& f1 O
回复

使用道具 举报

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

本版积分规则

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