目录遍历漏洞在国内外有许多不同的叫法,比如也可以叫做信息泄露漏洞,非授权文件包含漏洞.名称虽然多,可他们却有一个共同的成因,就是在程序中没有过滤用户输入的../和./之类的目录跳转符,导致恶意用户可以通过提交目录跳转来遍历服务器上的任意文件,其危害可想而知.这类漏洞大家比较熟悉的可能就是在一些邮件列表程序以及网络硬盘程序中,其实这类漏洞还广泛存在与一些国外的BLOG程序中,这类漏洞大概分两种下面就来通过实例来说明这类漏洞是如何产生以及该如何防范.
4 `5 n. r, J5 t' P; Q+ c* H( n+ A" B7 x1 H' k6 ]
首先,我们来看一个国外的BLOG,前几天从网上下了一个名为LoudBlog的BLOG程序,
. L N3 `4 Z6 c( T, p- o
在它的index.php页面中看到如下代码:
9 r' o/ V+ x' @- o5 a, A, v5 U<?if (!isset($_GET['page'])) { $loadme = "inc/backend_postings.php"; }
+ _: d( }7 L1 y; k
( J/ `" Z+ ?( Z# ]# j1 j
//build an include-path from the url-request
R# {$ d$ u" L8 E7 B) I
else {
8 D, N" ]" R4 V/ q4 q, z0 ^+ w) P* a
$loadme = "inc/backend_" . $_GET['page'] . ".php";
1 n3 P, H$ d, Q/ v+ Z7 f
}
7 D" i: R/ S; ]0 [
+ V5 D7 s' K/ M //yee-hah! finally we do show real content on our page!
8 @7 ]. M; o2 Q2 kinclude ($loadme);
# J9 @7 X! H% M, X
?>
# N- S- \1 a n
+ Z% q# x6 L& Q+ k0 b+ V, ~; C4 Y
这段程序很简单却包含了一个可怕的漏洞,变量$page是我们GET上去的,如果没有设置page参数,程序就自动包含inc/backend_postings.php这个文件,如果有page参数就把$page的值放到inc目录下以backend_前缀开头的文件形成一个新的文件.这里并没有对$page的值做任何的过滤,导致我们可以遍历所有文件了.
+ G! Q7 \/ m' p( c0 _1 U2 y/ z
这里要注意的是,我们提交的$page的值会自动的加上php后缀,所以我们阅读php文件是不会有效果的.当然我们可以读一些配置文件也是很有用的.下面就来测试一下,我们在inc目录外建立一个 TXT文件,内容为Wh0 !s H4K_BaN?我们提交如下URL看看结果:
7 D! M7 h2 j) D# `
http://localhost/loudblog/loudbl ... /../../hello.txt%00这里要说的是由于变量会加上php后缀,所以我们要用%00来截断后缀这样才能正常显示文件内容,结果如图1
' U9 S/ d9 Q. _$ Y测试成功说明漏洞存在了,那我们接着读一些敏感文件吧,提交如下URL:
g# m9 d; G% w, s( l3 }
http://localhost/loudblog/loudbl ... /conf/httpd.conf%00结果如图2
- X; _8 c8 e' |* e# L1 V) v; S) z
APACHE的配置文件也顺利读出来了,接下来就来看另外一种情况.
5 m2 o/ f2 `! F5 n, w6 e! s0 g. |
这类漏洞主要是存在与基于PHP+TXT结构的程序中,漏洞代码也是来自于一个国外的BLOG,代码如下:
+ N8 @/ V6 N9 H- e+ Q
<?
/ F' X+ ]6 M; M' d2 m: v
$act = $_GET['act'];
( w) p+ p; I, _% d. hif ($act == '')
; k$ A' Q9 X3 D9 H- s# t* }{
0 a( g8 f% z! P4 Qinclude("blog.txt");
9 O) m3 w+ K. ~ p+ ^
}
: m! ^* O. J( e1 r7 telse
( Y# G5 D/ N5 h% C' g+ ?# f% X{
" u! p: ^' m2 D* dinclude("act/$act.txt");
6 ^0 M; i( m2 Q) d: R; @+ @1 a
}
& h) w4 F0 E- x$ ~& U- K" u; N
?>
2 U+ }$ `# H; l& G0 y+ w<?
; O s2 ^$ w0 ?$blog_id = $_GET['blogid'];
9 l1 ]$ F5 A. I Q$ c2 }if ($blog_id == '')
- Y8 R* J" H+ ]9 A, H2 O% V
{
7 w5 [ ?( V1 n' I8 T, Q. s+ einclude("blog.txt");
5 S9 \& f6 r+ W}
/ I8 e. w7 s$ V3 _9 E0 x' g% B
else
_( _6 J. ?/ F) l" j4 y/ L" T{
. D" J# I, d! Q9 Ainclude("./blog_entries/$blog_id.txt");
9 G- ~8 s" ~+ [* `1 l
}
' g; N: v9 ^3 I: q/ _6 _) G3 o?>
* f4 s) x* X% }# J) Q从上面的代码可以清晰的看出问题所在,第一段程序获得$_GET[]提交的数据并赋值给$act,这里没有对act做任何的过滤,而在后面判断如果变量为空就把blog.txt包含进来,如果不为空就包含act目录下的$act.txt文件,不过只能读以.txt结尾的文件,读别的文件加上 txt后缀后会提示找不到文件,可以配合某些上传漏洞把文件包含进去,比如提交如下URL:
' E2 {4 J% m2 ^. v: {% H2 ]index.php?act=blog&blogid=../../filename这样带到程序里就成了include("./filename.txt");包含近来的文件只要里面含有PHP代码就算后缀是TXT文件也会被执行,原理给上面的一样,我就不截图了.
, @9 @/ J! T0 _5 Y: f! i 上面分别介绍了现在最主要的两种目录遍历漏洞,从表面上看基于TXT的PHP程序如果有这类漏洞似乎利用更方便一些,其实两者的危害性都是等价的.其实避免这类漏洞也是很简单的事情,象$blog-id这类数字形的参数只需用intval()函数强制整形化就可以了,对于字符形的参数我们可以自己写一个过滤函数把危险字符过滤掉,类似代码如下:
( ?7 x- j) G! X& H. G- @function fuckchar($var){
& V; s% @$ P! H9 a9 a" i1 P3 }6 m $var = str_replace("..","",$var);
% j! U: b4 a1 X" _1 \- ~( F' v" R4 z $var = str_replace(".","",$var);
/ q! R* k5 R4 y" v" V2 c( o( p: Q
$var = str_replace("/","",$var);
+ y* C8 m7 n2 B8 z $var = str_replace("","",$var);
( S/ g5 K; P' k) ~& A- h
$var = str_replace(" ","",$var);
: ~0 {" i! |$ y% e4 f( n9 o
% R/ ?: |" F' N; G/ l9 [- V2 P}
0 |: Y; b- p) p$ Q) i
大家可以自己测试一下这类漏洞,不管什么语言过滤的思路都是一样的,用GOOGLE搜索: powered by Loudblog可以找到一些这类程序,不过官方现在已经推出新版本了,更多的漏洞等待大家自己去发掘吧.
. c$ `* Q0 P" ] y当PHP配置文件中的allow_url_open打开的话,我们可以在自己的WEB服务器上建立一个同名文件里面包含shell命令,然后提交我们自己建立的shell文件让被攻击的服务器远程包含,可以以WEB权限执行命令,这样就是所谓的远程执行命令漏洞了。