找回密码
 立即注册
查看: 2851|回复: 0
打印 上一主题 下一主题

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿
; s" t+ h9 e$ \5 z  b( }7 E+ y
5 {2 M/ c0 A* y; ?: f, A4 n1 F      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。8 {3 }* b; t2 f. m- N3 o
& l1 x1 U% _4 b9 ?
0×02 写在前面的话
, @$ s: @2 \" l  q
2 [  U- p( t4 e# ]2 _2 R2 i    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
! v5 P$ g$ @4 c" V) n2 d# J  v- K" j" y; j4 W
这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强8 p* w- l% Y+ L8 G) R

5 M& k# P6 ~0 d- s; a/ E  `8 X这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论
  s. f+ \, g+ m
% T# |& F) i6 h% t5 W0×03 路径? ? ?
6 t9 n7 p# Q2 N( L& b' a9 h, h: X& b# K
    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件
$ a1 i+ J+ U0 T/ B+ j' p( {3 J4 d2 T) C5 ~! ?: N5 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])); } ) d: g2 J/ c) Z9 K5 z% R
& M# Q2 V! U  s" v' b
这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的
8 T! B, S! f" U5 x; @0 J. K( V* `: c; M4 S% v, ]
然后就是将我们传进来的参数进行变量化- S9 R% p4 j2 g7 D& Q& N- s5 J# _

# \( D! J" O2 \+ L* |& v2 |这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
5 G- Q, d8 U" t) m
9 T5 O3 B3 N' t8 ?) k但是接下来这行呢?9 {5 D+ v# B, h/ Z" J" j  |
, d+ y3 k  x9 O2 @
9 C$ c1 ^- C; t$ ^" l: y7 S

5 t3 I+ y* w' O9 `if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); }
% c. W$ p) |1 b  _% Y7 S* S) H* i+ T1 y2 \* a' h9 ^) f$ T
5 D. e4 w3 L$ |- g

, U0 h9 |  Q  L9 B看看这里?
( w7 I& D+ H" f" R( W9 \
$ a/ R; u- X+ R这里的QUERY_STRING来自前面  w( n, e/ n: [

! Y8 w/ H/ O1 b$ m
8 q. C0 Q; \2 |9 ?3 [2 y3 ]* j* W6 i3 I% H1 j8 R* m
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']));
) |$ `9 A& x4 u9 d这里有个过滤,但是不影响: @- `% \2 s) k& X: s3 C

! q( `# |9 I  p' y如果我们在这里进行覆盖这个db变量呢
* x" e+ i$ O* T( G3 O4 y/ q7 K5 W) d' [( t- P# H$ E6 s0 [
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));. u% p) e5 P& a2 F3 p4 u
1 U" d+ q# d) U' G, N9 U2 ~1 @
可以将我们传进去的/ - 进行替换3 ?% _( N* E6 h1 @9 I* @0 Y
" }3 S! @5 i( t0 H5 N/ q& U
所以我们如果提交如下字符
' u2 P" w6 j8 D/ E
% w2 y) ^# b( L- ^' hhttp://localhost/phpcms/index.php?db-5/gid-xd.html. ]* D. ?0 f- Y) H; l
3 e( S: z) q) c7 t) y$ U3 M  X
他由于这个db被覆盖就会出错,所以物理路径就爆出来了
  w3 i( q2 b! X# j6 V7 q9 E7 c
3 c& [, F! y. ?0×04  SQL注入!!!. K+ k+ E- F$ W! \- ]; G/ z/ j
1 x& L0 @9 r' E! k$ c/ X& L
  在c.php中
* z- L4 y+ b9 C, g
+ H/ H, r! T+ L6 U5 Z5 ^' r
2 x, _* c! f; j5 O5 {$ j' g; {5 d+ s1 I. I
<?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']; } 9 N3 V7 `  l/ y- k
9 g, Y$ Y# ~9 X1 Z9 ]2 _
0 D8 p2 w+ X( I; E+ d! x+ J
: k. A# h: ^2 p, k" ^' o1 e
注意这里的HTTP_REFERER这个常量9 B# |/ k7 ^- ?) x% e
: b; e1 x, ]7 g* c( O/ ^( _
这里的常量是通过前面的common.inc.php定义好的" {+ `  ^: N0 |# _' A
. [# \2 A. a. W$ E8 k$ E+ e  n
define(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);
- a; n1 t, v1 c6 _- p1 r% s# y, v/ h
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我
! b& k( e! ]3 J( g. S
; W6 U9 Z" H9 P, ]5 g然后
+ G  a& C/ `, R7 _, X9 i' g
1 e7 j4 J3 t' M4 |% C$ G. i$db->insert($table, $info);4 x6 E( o/ {' O+ U* ?  ?7 l
我们来看一下它这里的操作
1 ]9 C& f0 U/ }6 u/ ~7 {1 l! d0 i- E
function insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); } , C% T$ l8 F0 }5 z, m

! `( X1 G$ j) @2 p# q0 D$ {% ]4 a所以你懂的
7 U0 k: ~2 w7 \/ g" r9 D; P3 K  D6 D4 E/ }

6 a, i4 A, x" x( N
/ x2 k  K/ _3 l! P! e# {2 _" |附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=40456377378 K4 f! M$ a$ v- g

7 w2 C/ ?( ^% X. C/ q0 ~
5 R" U- d5 @: |( s
8 A* W; v! T3 J
回复

使用道具 举报

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

本版积分规则

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