LFI漏洞总结

上周打了个ctf,几道web题的思路还是要总结下的,自己搭了个环境,简化了下代码,当然echo的内容是我自己为了方便输出的,如下:

很明显这是一道文件包含的题,首先实施包含/etc/pass文件,是可以输出结果的,那么使用php伪协议看下网页源码,这里需要普及下PHP伪协议的知识:

  • php://input

可以将字符串以post方式传到服务器并包含,理论上可直接获取shell。

  • php://filter

允许渗透测试人员包含本地文件,并将输出数据用BASE64编码。当然,用BASE64编码的输出数据需要经过解码,还原出原始内容。

  • zip://

ZIP封装主要在服务器端处理上传的.zip文件,攻击者可以通过一个存在漏洞的文件上传功能,上传一个ZIP文件,并通过LFI来执行zip内的php文件。

  • data://

data也是可以上传数据的。

然而当时的题input和data都是不行的,那么怎么办,我们只能去找攻击者能插入数据的服务器文件,第一想到的就是日志文件,我服务器上的日志文件在/var/log/apache2/access.log,然而Apache的web默认用户是没有权限读这个文件的,放弃。然后想到了PHP的session临时文件。session知识:

PHP session用法其实很简单它可以把用户提交的数据以全局变量形式保存在一个session中并且会生成一个唯一的session_id,该session_id的值会通过setcookie方式返回,并在服务器上创建以sess_+该值的文件,内容用_SESSION[‘username’]=设置,和我们代码审计的结果很类似。

下面就是找这个文件在什么地方了:

文件的路径在php.ini里的配置配置项session.save_path配置,所以读下php.ini文件就可以了。

现在东西全都有了,还差一个name参数在文件中是使用base64_encode($username);编码过的,那么我们包含的时候需要解码下,php://filter/convert.base64-decode/resource=搞定,那么需要考虑的是怎么让输出解码会原来的输入,开始研究base64编码:

上网找了下,这个图一目了然。这里需要拼凑编码,但还是可以偷懒的,看下格式4个base64编码后的值返回3个编码前的值,也就是说我们凑够4的整数倍就行了,再看session文件格式username|s:X:””,这里X的值为后边字符的个数,那么后边字符超过100则字符串正好是16个字符,成功。最后结果如下:

发表评论