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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-25 20:43:29 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
0×01 前沿
$ }! g. ]& _0 m/ j3 U3 u0 {: O6 U/ I- m- ]% G: R8 |: E
      Phpcms2008 是一款基于 PHP+Mysql 架构的网站内容管理系统,也是一个开源的 PHP 开发平台。Phpcms  采用模块化方式开发,功能易用便于扩展,可面向大中型站点提供重量级网站建设解决方案。3年来,凭借 Phpcms  团队长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得 Phpcms  得到了近10万网站的认可,并且越来越多地被应用到大中型商业网站。
" G" w1 j) Z2 N% M: V5 _# W/ \# I! u% X( u7 D' g
0×02 写在前面的话
. ^1 w5 T( y/ b9 |- R0 D0 R
! {. `+ x5 \5 f    phpcms 2008 这是我看第二次代码了,之前已经发现了一些问题,只是没放出来,这次稍微仔细看了看,又发现了一些问题
. w5 b- H" c  c: x2 r! l
; m4 g6 N% v$ i& o! h这次就放2个吧,其中啥啥的getshell暂时就不会放了,比起v9来说,2008的安全性能确实差很多,模块化以及代码严谨程度也没有v9强
" j5 S* h% u$ o. z; G1 Y+ y
3 z) |+ r; _0 f9 U这次还没把代码看完,只看完几个页面,就先放2个有问题的地方,如果有更好的方式,到时候一起讨论6 R! L* ^+ a7 D

0 W, b$ t: G/ d9 z1 r6 j7 j% P) o0×03 路径? ? ?; x$ v2 _! S5 S' H: y0 K3 F

3 c& R5 F8 k- m/ Z2 g9 K    在include/common.inc.php中 ,这是phpcms的全局要加载的配置文件
9 C+ R: n( s  Q! T" m
- D  j0 O9 d) G: p6 v) @$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])); }
- G" m: S# o. z- w! u: P
4 b7 Z* p/ V  q8 [7 W6 q这里的话首先实例化了这个数据库,产生了一个$db资源句柄,他是用来操作数据库的& u) @: p$ [; X2 N' z- d/ A
. F. r  T1 C' ~! L) h' ?( G
然后就是将我们传进来的参数进行变量化
' N0 F  l5 M; m) M$ u% ]
/ _3 k: M& [7 b8 H! G& s这里有一些小过滤,自己可以看,所以这里传进来的参数就作为了变量
, N7 A: ]. N, D
0 U$ p. [- F  i2 |但是接下来这行呢?
6 @3 g  w- C! ~* v  s( F! _5 }# b1 \
1 h* \/ z8 B! F% Z & G. w6 p0 ~% v6 T7 x( E. ?; O6 L

$ Z, G, [, E' \3 ?2 X" Aif(QUERY_STRING && strpos(QUERY_STRING, '=') === false && preg_match("/^(.*)\.(htm|html|shtm|shtml)$/", QUERY_STRING, $urlvar)) { parse_str(str_replace(array('/', '-', ' '), array('&', '=', ''), $urlvar[1])); } 7 {# K# `+ r1 Y! T; j

$ {3 V! U8 X$ I3 @1 L9 d3 @* Z# ]
, V" E0 F8 y9 W3 Z5 w! l3 l" R: ]( X$ G- d4 w, A* g
看看这里?2 Y2 O# o0 P% r/ I  M9 }
! Y' D: P/ u* k; V' K. e9 _
这里的QUERY_STRING来自前面3 p; ^6 R. }$ E, ]8 a  E6 u% |

- x9 h, _6 b% I9 {. z5 `+ _6 t   [4 o/ F& I7 c1 n8 \- A) y
8 l5 t6 A$ P' O7 p+ x( \
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']));
+ z' X& J5 A0 b, K这里有个过滤,但是不影响
/ b9 m8 S+ n9 Z$ J
! R  V$ ?! |  J9 G9 `如果我们在这里进行覆盖这个db变量呢  a  q$ d, z$ a* t

6 W+ ?7 `+ E) p, l. Z7 |3 q因为这里 parse_str(str_replace(array(‘/’, ’-', ’ ’), array(‘&’, ’=', ”), $urlvar[1]));: L: Y8 z& A/ x. T
3 Y: z! B5 P2 c  J6 C
可以将我们传进去的/ - 进行替换, n+ E. v4 O2 Y6 u: p! h
/ n) G+ A) b$ S! |# C! \! z
所以我们如果提交如下字符9 R+ `. Q% `3 ^% U0 m

1 M0 C8 w7 \" P5 Q$ fhttp://localhost/phpcms/index.php?db-5/gid-xd.html
' R$ @8 c6 e% Y5 ^) |6 s% Y; J2 h$ n3 C0 l" z$ C- [! H
他由于这个db被覆盖就会出错,所以物理路径就爆出来了' k# w$ E1 }& |) q6 j
# g. H7 V$ Q- G, m
0×04  SQL注入!!!7 D+ X! M3 L$ p; N( Z
: w/ C* H9 W0 p$ t+ c
  在c.php中& c/ v- ]0 c; S
7 u; _% I) T8 ]8 t/ o, O( G& F1 f

  h9 Y; B2 y7 U! X5 Z  j
. [, U; b* w% q' S% ]<?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']; } 3 o0 [) h2 y9 K" O! j

* N3 Y! k6 V; j 6 _/ U, i$ v) }/ c

) E* W$ |1 w' I2 K0 k注意这里的HTTP_REFERER这个常量
- i0 t; s3 C$ n1 W( n. @0 B" b/ X4 |
这里的常量是通过前面的common.inc.php定义好的/ |. x5 x$ }4 H0 Z& E
- c- C8 H9 L7 X* v' }( x9 e9 r
define(‘HTTP_REFERER’, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ”);& n# b' h' u; _+ j3 ~

$ L2 O! o+ t* d没有经过任何过滤操作,所以你懂的,我估计很多同学已经发现了,只是没去公布了,所以俺就替你们xxoo了,哈哈…别骂我# n! L' ]0 s4 e* P% i
# V2 X6 Z) y+ _9 {
然后9 h+ c% S: g/ J1 d2 S' v8 c6 j
* E  t" b8 e/ j9 q1 _, f2 x
$db->insert($table, $info);# H* j( U. {3 c: D
我们来看一下它这里的操作; E8 E$ P- b! O0 C

, x& D) h8 W0 X! ]% h. Ufunction insert($tablename, $array) { $this->check_fields($tablename, $array); return $this->query("INSERT INTO `$tablename`(`".implode('`,`', array_keys($array))."`) VALUES('".implode("','", $array)."')"); } ' X) m7 m' u- O# N
) a" z6 ~  {7 I8 P/ k5 w% `- g2 q
所以你懂的: ^, W% |6 L0 J+ l: l
2 ~( ]7 p% R# `) h2 t. q# t

) w7 ^5 ^& m  n/ m5 ?% [$ b' m# h9 v/ S9 L- Y$ ]' ~3 r2 s
附EXP:http://pan.baidu.com/share/link?shareid=468231&uk=40456377373 ~9 b+ [! J" Y- E7 ?6 h

1 f" _' D' u8 u 0 _& V' _7 c/ q4 f3 y

$ ~4 J: l- _  }! B
回复

使用道具 举报

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

本版积分规则

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