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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0×01 前沿8 l$ Q& j# `* |* E) U; W
! G* [! k$ z! h5 s9 q0 J' W
      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。
& F! R5 b6 I: u! v1 r6 i  E, a( q# O
0×02 写在前面的话5 q  B  S$ v" r0 w: d- S

# U# ^4 r1 W& Q" l" r    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题# d* ~& f  J. s6 q

6 x9 E5 h# S8 E! l. f6 j这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强. P) \, w/ q# x+ I
8 w( A0 \5 T8 U7 j. ?* n
这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论
) X$ O; q- f5 E% _+ y
% k: h+ K& e8 t0×03 路径? ? ?
& B* F6 O! {5 |0 K9 {, D# i
8 k6 q3 V9 k; t7 z0 r6 B    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件; H) ^8 X+ O% C1 b6 ~

  B; M5 K8 z% B) B* x$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])); }
# c6 a) l: b% L3 l2 f! H- h0 K2 L
3 N, K4 S" h, G+ q这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的9 H1 b# a0 @9 v9 o

) v: T* D2 O1 o3 k然后就是将我们传进来的参数进行变量化
, V7 Q/ U0 V$ U, A
* Q; t1 z/ A+ s: y- Z* ]3 }" [这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
% ?4 x6 s. l6 r; T" ^5 J! P% c: X  \* T
但是接下来这行呢?
, ?* c* V( G6 z* ~; [; h
1 v- p3 k% S# ?% X ! K1 }9 a& R7 x7 `" u* L
, z6 b- e! M0 M
if(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); }
3 ]" o" ?5 h& n
; v* R& ~" X) J1 W6 X
$ [- L. j5 z# R5 i- p, b6 ]4 L* H
看看这里?
4 R, g5 c6 I& S" L1 W5 ~
% y& G9 f; g% E/ _这里的QUERY_STRING来自前面
. o2 H% N. v! G2 H1 A  l  ?7 R3 d6 w5 i- f$ y! @
. ~7 _" F9 y( N! D6 ~* {" K

( ]; M1 P! K# l' v" [  Edefine('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']));
# n3 {0 v- Q% a( Y, F, c这里有个过滤,但是不影响
8 f1 M5 @+ p  S9 z; p
5 u6 J6 t. u& m' @3 J. R2 q如果我们在这里进行覆盖这个db变量呢7 k3 ], k. c. x% ]. q. R, }: R

- m3 H1 V* R' l& q9 u; w  }+ A5 j因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));
3 N% W8 b! D' g! ~% [! M7 x. }0 \) W6 U& e* _5 ^  c7 G
可以将我们传进去的/ - 进行替换. r8 F& y+ S4 ?, {

! Q& y, E9 x0 O) X8 P( ?所以我们如果提交如下字符. N+ E8 t$ o( i) i/ m
: H- T+ K2 b0 K& C/ }
http://localhost/phpcms/index.php?db-5/gid-xd.html
4 q) `. k# j3 A; R, C. ], Q5 O) ^$ e
* U: N6 n' z% d, f- `9 l0 a! ?6 J他由于这个db被覆盖就会出错,所以物理路径就爆出来了
9 W9 e$ x8 K" [" E- ~& p1 A6 F+ ], Y6 P- o1 k" f
0×04  SQL注入!!!! {/ X  W3 G: l; _5 Z

) Z- Q6 C" H( M7 u' L0 P  在c.php中
0 `! h8 m0 a# a/ u- p: T( Y# D' _# b: P2 E1 g) j  [3 j
# F2 {" S& {( c1 s9 P' t

# t6 c& L9 }/ c+ y7 o3 H<?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']; }
- ]* c5 f, O; ?  P8 Q) c
7 m1 H% V4 o: m) j6 Y/ c
( S3 B& v; t9 j' C& ?0 ?
; ~" @* @9 M: u7 M0 E注意这里的HTTP_REFERER这个常量
" B; X4 G. ~6 x# C( E! E, [$ t  ~
$ U" N2 t% P! G0 D# I! |3 p% d这里的常量是通过前面的common.inc.php定义好的# b. V0 T$ }' N( {6 f5 e6 F

+ V. A) @" C" s0 L, m  V' Qdefine(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);
7 A6 `* F* L3 }' E$ M: K1 e' }
4 _# Y2 g4 T* }( B没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我0 w2 B1 H; I( e2 I; ~

9 g9 A0 o3 {4 Z$ e; ?5 v然后
; f! z+ W- [8 ?+ Y2 L3 a9 Q$ }& o& z9 |( [  Y4 e, h- h5 j  I
$db->insert($table, $info);, _+ L+ Z8 j. F* {* c
我们来看一下它这里的操作. T4 i' y  P. K7 z% H
" S- O: ]! P) n; _
function insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); }
6 ~  S* |" `8 |) F9 M( a" r7 p
5 H; |6 `: `1 N& d1 S4 e所以你懂的
) E7 }' C$ M* A+ ?3 w
, G3 ^+ ]$ i  F" c" W) J
/ X' R" ^9 }# P  C+ `3 }# r- N4 ^6 I; v7 J* u
附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=4045637737
4 @3 u6 o% n9 A6 t' F) Z
0 R: n; Y- C( y  W2 }" x' c0 J 8 v6 s1 f! W8 q9 g8 _8 n. f
- `+ l. X5 x+ l5 k6 |/ F: I
回复

使用道具 举报

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

本版积分规则

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