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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿
% z1 s6 h. v5 c5 G4 d- W9 `% f& D  e. N3 w4 ?
      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。
( l' w& ~" L+ D' w; A, @
: v1 {- o2 c) ^: L0×02 写在前面的话
6 B' {! z  S9 r3 Q
3 g7 x9 U$ B6 c    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
2 }1 Q9 {7 v/ m8 V% q
( S, J) v1 T" L) ?这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强6 U" `2 h1 W% v

( B7 `1 w# [) ]  g+ |这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论! G3 K9 w9 @6 v+ {
; e. E( B* s4 K8 |5 Z
0×03 路径? ? ?! h" s) \- a, @+ Z% B

: Z+ L! z+ y' W$ f' ?; `0 v    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件
: C" G9 x, d# G3 V! ~
' o! r+ P* v, E$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 G4 h+ E; E% f* v. r/ n) B, y
4 ?9 E6 S# L0 x3 q
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的% @! i) C( H. S& M0 ^5 M7 D, w2 z

4 L& G' s% O8 c  K8 p然后就是将我们传进来的参数进行变量化
; l9 J7 ]( y6 U# C# S. D; Z9 r, {& Q9 `
这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
  M2 Q' y/ u4 s+ w
9 }5 ^2 b  \& H" o1 m但是接下来这行呢?
4 x( S( G1 e* w' _* P
( Z* [7 Z4 z0 J* D6 | ( m  K, R9 H0 L5 \6 R
& ?" V  c  m" j. b: n5 D6 Y2 I
if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); }
, P3 j* d6 B+ ~( ~% I) a: g* T6 c9 h) P2 u7 Q
0 ~$ g- ^6 F2 @8 v

; E( r5 m5 Q  Z$ r看看这里?7 F: ~  v; B3 e) I% ?: @

% j$ j& x7 R" }3 }+ i2 \- ~; |这里的QUERY_STRING来自前面! _+ b9 h  I0 {1 e( G, b# d+ _- B
) i: Q+ q0 {/ z! c7 n

# r- I9 X2 [7 k
5 k: j' L) W& v# N6 r  k# Rdefine('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']));
8 Q- A9 o. n% u5 ^' z" H这里有个过滤,但是不影响  I; |* w9 a# `9 a

/ @  A* r! z' u) y5 F7 @1 C如果我们在这里进行覆盖这个db变量呢  A7 ^1 h( u) s" q8 P* b$ V
9 @$ w- m$ S% b' t, |
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));0 L1 I) o- O% p% M) S6 \7 J

$ T! `4 `/ V( ~$ |) _7 G6 y可以将我们传进去的/ - 进行替换
" J( z2 l7 D! z5 ]/ i6 k& v! ^' Q3 M6 I% K$ B+ ?& \! b7 [
所以我们如果提交如下字符/ {7 Y! f; A1 Z1 e
7 M$ ]3 i* E8 P5 [1 w% O" j  K+ ?/ p
http://localhost/phpcms/index.php?db-5/gid-xd.html0 k2 |9 D/ M( F  H: N

+ q6 T) J* G: t" E他由于这个db被覆盖就会出错,所以物理路径就爆出来了/ @3 ?6 J: V" J0 Z6 z
7 {" P: m  u/ E% Q' s
0×04  SQL注入!!!
$ M/ s  Z1 t) V1 f# j
) _3 _. }2 b; f* g  在c.php中% z2 s7 u1 m  N9 `9 A# d9 U. d( G

+ N* L) \% r# x- V) [. D
% G# S& z* o6 C
4 \* q- M" L+ Q6 ~! Y) O/ s' L<?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']; }
& s, Q8 \# c7 |; V7 P, X3 h; F9 \; P) `& [

/ t9 t" X4 C" O" O
! u7 l0 a% w' k% C注意这里的HTTP_REFERER这个常量
: w  K$ T- c+ A6 S4 f( V5 D
) R1 v+ a- t/ v  Y% b7 L7 H! W4 N这里的常量是通过前面的common.inc.php定义好的
9 ~" ^0 A/ p; b" I( R3 o) U* N- `. A0 \, V) i
define(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);
( w) }# ~/ `8 C/ m) u) s8 y- M5 w
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我, u4 h" f6 V: e! i4 f# j* O
6 R! d8 b3 y- I' }
然后/ [: H4 {% ~; t! f4 i; u

8 }' \2 G; [* s  N6 ?$db->insert($table, $info);8 u* }& f6 N0 R4 y, d4 p% |. b' {' y
我们来看一下它这里的操作* F' p8 l! j6 U: [1 B/ F

: I; Q% F! @& tfunction insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); } 0 O0 I+ z! i: q9 \% L% y: D& y& e) N8 C

0 D& a9 z, _8 F' z5 n. ^  q所以你懂的
+ K: v, \/ |7 F: {5 S& F/ [
1 K7 S& f" {* _6 o 0 w1 S% b9 l0 ?; x7 ]; V& V' P( W

/ \; o+ p+ i% f/ h附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737
3 m& F9 R1 ~" E2 k3 D: E4 Y
9 ^1 j1 m* b+ F
+ A! Q6 y  Q3 B
3 T& B1 E" \" v# A( d
回复

使用道具 举报

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

本版积分规则

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