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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿% }; T4 `1 b' ]% g# O
% y- x# n2 N% Q4 ^4 N2 f  e+ n8 R
      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。7 X6 ~* ?& B' }5 n) b% B7 D
! y" d, F  x7 z8 G
0×02 写在前面的话( p; s" m9 c" e" |& x( t# s

* O* I5 a1 Q' R$ e4 i7 a    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题% ], m& h9 J7 v. `$ ~# O

* _; l+ R5 w  r8 t4 |  t5 O& G& U这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
- [+ ?+ u% T# v2 p+ k' H
8 ~. g: Y3 Z9 G$ g这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论
7 R6 J* S- [) Q8 D0 q8 H, q( m9 }, @3 X/ f
0×03 路径? ? ?
  o, V1 f1 ]- {' P- e9 T! l3 U$ E- M' ^( d. _
    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件, ~7 D+ D8 B4 a
$ i  u0 O6 m# M
$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 g9 `, M5 r& e2 X3 r" U) t

2 x2 e; M9 E% x# s. k- ?这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的/ A( x  K; H4 ]! F8 t

" \" C  S8 K9 `2 m' `0 s( ~/ u" M+ e然后就是将我们传进来的参数进行变量化( j0 \3 B& U8 @0 O7 ~
3 d/ @+ r3 B1 I+ z
这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量4 p7 Q& @: E5 F5 b  Z$ P1 j
: J- ^4 b( x  o0 S
但是接下来这行呢?
0 b! B- P# E0 ^" n% L
' f: r% L7 w/ z 7 @; F. [) Z5 f
; W% r! K# A0 |- J
if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); }
; R4 Y; [5 h, h5 ~0 ^* M- }
4 G( ?0 W3 c* W) |' P+ o. |' q
+ b" n# e" W7 T, e  ]" y+ e- H# d5 e1 b- {
看看这里?
( {9 L& h2 D' f! K4 s; P1 I2 R3 j0 d! k( G+ L
这里的QUERY_STRING来自前面# u  B  N* m, H# g5 O

& a) X# s- V7 |! r0 u+ N
) [8 z( f; j( d/ b! a& d% b3 y/ l+ Z9 D3 l8 m8 V7 B
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']));7 |# P4 d) e) u" I% c  y
这里有个过滤,但是不影响6 ]4 o: m/ e4 f

3 X( ^# j9 L7 ~如果我们在这里进行覆盖这个db变量呢
% w: `7 f0 V! i  A. x' Y# X; v& F1 B+ F5 z# N7 L6 ?7 F
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));6 x' h- n9 l5 v' }0 z+ E1 S$ \& A9 ^
" f$ g/ \+ O7 \) h% \7 b
可以将我们传进去的/ - 进行替换, I" t$ n& w- t! m( s

- F& \, h; p3 k3 ?所以我们如果提交如下字符' S" D7 ^; C3 N* ^/ T: x. d

2 O4 t* n/ t6 L9 t9 Y) Mhttp://localhost/phpcms/index.php?db-5/gid-xd.html
5 s6 _0 U3 t( j2 L9 \- G6 S6 k! U  x3 T) u4 b/ k! v
他由于这个db被覆盖就会出错,所以物理路径就爆出来了
3 m9 K1 s2 A: u9 q7 X/ ^
/ n2 @2 @8 u: K' x5 F0×04  SQL注入!!!
# v1 z: _* T1 L% Y( B) ]1 J: P) z  _3 y, n  O% E& V
  在c.php中
+ J% o3 u" a6 X2 M* h. ~: V3 k2 w* x5 w+ b4 w6 R) g+ v8 Z: X

& Y! R  D4 V* \! \" t. B( \6 o" r7 O
8 U. u- [5 V' \  F; V% |0 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']; }
; }: D- E. p! h) c7 W8 x0 v# e4 J& s
7 P# U2 M4 D% {- {# @; P2 _1 |

  m+ x6 L( F+ q$ V; x  L注意这里的HTTP_REFERER这个常量
$ t" E7 y8 U) Q6 g! @
0 ], ^4 N( \) ?. x& d: [9 o1 l6 }3 j这里的常量是通过前面的common.inc.php定义好的; p4 M5 e/ h7 v  H5 D2 Q, y) `
9 c8 P  I8 p, w2 ^% Z/ X
define(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);8 H' w5 F+ K; F0 X# E* |9 O  w
8 }0 l5 A# q" ?" U/ r) j: O5 g4 q, Q
没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我
7 \; C5 J4 \' F/ v2 m- b: j: [4 g$ I+ f9 i* u
然后! [; _- x+ H& _
( I4 y- y/ t: D5 B
$db->insert($table, $info);
' o7 s! C& T, d$ v$ N, k/ J我们来看一下它这里的操作$ Z& {1 U7 C) S+ K

! v5 q5 I3 S9 q. y( Afunction insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); } 0 @, b. E( f6 g# _; x

' a: W- G5 a; g所以你懂的
8 |3 c1 T! x! |' i
. y  p( U# I+ M8 w# C0 t
- g* d- P2 G0 d# E
& c9 u" _+ ^0 }9 F" S) t附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737
: e  J+ S* a& m5 R) A
/ v% G: E  W) P) \5 X$ z; L$ t
7 M, O: f( b/ j3 [7 A3 g
1 Z9 g* y: K7 T1 m% z2 C, P% }' h, `/ ?
回复

使用道具 举报

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

本版积分规则

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