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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿6 A/ j& L* \- i% G. T" P5 x: f

: J$ w* P% q. O3 k& y( J* z7 u      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。
& ?" v; A& n" q; _# R8 n- w# I& Z# F* y4 P6 A- \7 r. Q1 `6 f; K
0×02 写在前面的话* T4 I$ A$ H" Y0 A' Z! u0 l: A  I/ Q% {

+ J+ g8 ]2 P1 j1 m$ ~) V    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
6 X7 O* H% C% O$ U
. W8 _: h( L1 W/ k7 x, a; O这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
3 a) `4 N+ ]1 U9 C/ y6 g1 t+ r2 `) l1 H2 S2 v
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论# Y, \& W4 ^7 [4 \. w" S
/ X$ e+ n# P8 t$ C  s# z( U3 x% B/ S! h
0×03 路径? ? ?
7 Q# m# \+ Z* W! [, C3 M3 Y% `
% I; s1 a8 s; F    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件
: G* g+ N& |9 N5 X& d# q5 g( ]5 z! C3 K9 q& n  i$ S0 Z2 }8 \" y
$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])); }
# n) t& z3 w) P( _/ Q* `
6 M! [9 d) m( n) S9 G9 Y8 m这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的1 g1 P  i& |" B: O, O, r3 {1 q
* [$ z3 r2 a3 T3 E! v
然后就是将我们传进来的参数进行变量化5 D5 P* ^6 @% Z6 F( @, m
0 |. h+ j" l. @6 x* `: S, u- \- {5 {
这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量1 H) d* I7 C" s7 n% z$ i4 _

; M+ y/ i$ E- O/ l但是接下来这行呢?4 ~+ }7 k% D* q8 J  X( H
- m1 i, R5 `+ R3 l# }

3 K7 Y5 z% u6 I0 g" f6 Y  x& E
  _2 Z  g. c5 aif(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); }   B1 J% f8 J$ w& i7 \, v" r) |

( c" |3 p) P7 q: j
/ w7 I! m7 p. D. ~1 O/ i6 F. D; s/ `+ |6 j
看看这里?
8 ^9 @8 {1 o9 Q; i6 v' F! [9 d/ [5 H
这里的QUERY_STRING来自前面
9 L# t( p# U* L; R1 Y# T% J; |2 D0 ?0 @2 C

6 ^9 t' B8 Z) Z5 Z" ?
& ^3 l4 l" H" {3 Pdefine('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']));! P0 Y$ d! R6 W1 O  c
这里有个过滤,但是不影响( s9 b3 E3 a. V, I4 ?# A6 n+ _& |2 V
0 [) F: J  }1 A. ^2 h+ I5 z+ D
如果我们在这里进行覆盖这个db变量呢
" @4 W- P/ j6 v" ~; `: t: K( Y; f% }* D2 r* r' r
因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
( N7 {* q- q7 g2 ~+ p/ Q/ |% i1 G( G6 }" D
可以将我们传进去的/ - 进行替换
9 q: O* p. T$ ~$ t
" b7 h6 C# }; @所以我们如果提交如下字符  N: `( F4 H: n& k* O
; M$ h, i: F6 p4 |/ t- k
http://localhost/phpcms/index.php?db-5/gid-xd.html
( j& {, |" `0 @/ r6 ]
9 E" r0 w* Q- u" G他由于这个db被覆盖就会出错,所以物理路径就爆出来了+ o! Z- @7 |- F  t$ H  g0 }$ K

2 K8 T# b1 h) W" ^, x8 A- S1 v0×04  SQL注入!!!
+ Q! u) {6 K; T" h3 S" @7 {' n3 @) k0 ^9 P+ G
  在c.php中
3 m& r2 k4 U& R0 M) n2 d
( N  T$ z0 H/ f0 G' c  q ' f7 v$ M2 N$ C, t

, G5 ]# }) z: M' B& y% 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']; } 1 R/ [  g- q( V" a/ e8 Q

" W2 ~# @5 S# K2 o , G; z  K. J  c# F2 F7 |. a) L
/ ]! T) l* x* \, D& Z; W
注意这里的HTTP_REFERER这个常量# i  W! G9 y# r2 {# \3 L5 C/ Q
. X+ f0 [# {! X0 |8 R
这里的常量是通过前面的common.inc.php定义好的
4 ?! C8 O1 \" p5 o
) `. }" Y! @/ A/ J) R, x! Mdefine(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);% c7 Y9 |# g2 p# |) m% T

: J' a  a# k) E+ t3 e) p- o没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我
" i& T8 B* {9 C+ L( k) S5 L! i+ A3 i/ ?; ]7 T: f
然后
, f/ I2 M) J+ m( W4 n* I: j9 t- ^0 X# I# i- E% v- K
$db->insert($table, $info);: a1 p7 U: p$ s* N% Y$ M
我们来看一下它这里的操作
) x; Y# H! R7 I) r: \; G2 O! R6 i. t  O' k& E( j
function insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
. h. Y* d+ n7 m( _* A2 t# p$ z5 e
; D+ A9 F( F1 {& }5 D0 e: O4 F所以你懂的
& @9 ^; K2 ^2 R$ Y1 d1 H! `* a+ L* H' R) Y/ E* B5 u. _3 }

9 ]& M' D3 {" V" Z: U: F: Z
- w9 o, O, c3 M# R' d附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=40456377378 Z4 e+ g# I$ @5 F7 ~

' c! @/ Z* j% {: B 9 j! {' X: c( @+ k
  f" D4 C0 t7 H4 b  O3 b; P; h
回复

使用道具 举报

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

本版积分规则

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