文章目录
一.PHP伪协议利用
php://协议
php://filter :用于在读取作用和写入文件时进行过滤和转换操作。
作用1:利用base64编码过滤器读取源码
通常利用文件包含执行php://filter伪协议读取的源码会被服务器执行从而不会显示,因此需要使用特殊操作读取源码。
利用php://filter
的读取源码的基本语法如下:读取源码以base64编码格式输出
php://filter/read=convert.base64-encode/resource=文件路径
演示案例:
<?php
$a = $_GET["a"];
include('flag.php');
include($a);
利用php://filter
以base64编码方式读取的源码:
用base64解码后获得 flag.php源码完整信息
作用2-(1):利用base64解码码绕过防御代码
利用php://filter
的base64方法先解码再写入内容基本语法如下:
php://filter/write=convert.base64-decode/resource=文件路径
一些防御代码为了阻止webshell代码被执行通常会在传递的参数前添加一些代码。
演示案例:
<?php
$content = '<?php exit; ?>';
$content .=$_GET['txt'];
file_put_contents($_GET['filename'],$content);
?>
尝试通过URL参数上传webshell代码到文件webshell.php中
成功上传后,webshell.php文件内容:
即使webshell成功上传,但是前面多出的防御代码会破坏webshell结构使其无法执行。这个防御代码十分常见,通常出现在缓存或配置文件等地方,防止用户直接访问文件。那么,如何绕过?
php://filter伪协议支持多种方式读取和转换文件,其中包括以base64解码的方式写入文件。
当我们尝试利用php://filter伪协议将文件以base64方式解码再写入时,防御代码
<?php exit; ?>会被当做base64编码进行解码,而<?php exit; ?>是php代码而非base64编码,<?php exit; ?>因为无法正常解码会被当作乱码写入文件,乱码不会被执行,就不会影响webshell的执行。
注:base 64算法只对数字/字母解码,‘<或?或;’等字符解码时会被删除,且base64算法解码时是4个字符为一组。例如,<?php exit; ?>去除字符后只剩“phpexit”只有7个字符,所以给它增加一个字“a”一共8个字符,这样“phpexita”才会被正常解码。
成功上传后,webshell.php文件内容:
执行1一下webshell.php文件试试--->成功执行
作用2-(2):利用strip_tags()函数去除防御代码
strip_tags()会
剥离字符串中的HTML和PHP标签,我们可以将webshell进行base64编码后上传,这样strip_tags()函数会帮助我们去除防御代码,同时联合base64编码过滤器将webshell解码
二. Apache 日志文件包含漏洞
Web 服务器一般会将用户的访问记录保存在日志中,同样的,我们在访问站点的同时URL中插入一句话也会被保存到访问日志中,通过文件包含漏洞包含日志文件来执行URL中插入的一句话。当黑客找不到能够上传一句话的文件时,日志文件就成了最好的上传位置。
利用条件:
- 对日志文件可读
- 知道日志文件存储目录
演示案例:
随机访问一个网站,同时在URL中插入一句话,查看Apache日志文件会记录哪些内容。
GET请求传递的URL被记录到accsee.log日志文件,同时被记录的还有一句话。
下面利用文件包含漏洞包含日志文件执行一句话
<?php
$a = $_GET["file"];
include($a);
?>
设置file参数值为access.log日志文件的绝对路径,包含函数include()接收到参数后执行日志文件access.log中的一句话,执行结果如下,执行成功
三.Session 文件包含漏洞
Session 文件中包含验证用户身份的信息;可以寻找Session文件的用户可控变量,再构造pyload插入Session文件中,最后包含Session文件执行webshell。
利用条件:
- 找到session内的可控变量
- session文件可读,并且知道session文件存储路径
php的session文件保存路径可以在phpinfo()的session,save_path看到
Session常见存储位置:
/var/lib/php/sess_PHPSESSID
/var/lib/php/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID
session文件格式:sess_[phpsessid],而phpsessid在发送的请求的cookie字段中可以看到
案例分析:
- 在可控变量中插入pyload写入session
- 后台session文件内容如下:
" PD9waHAgcGhwaW5mbygpOyA/Pg=="就是我们写入的webshell,包含session文件试试:
文件包含漏洞位置:
http://127.0.0.1/include/include3.php
Session文件位置:
C:\securty_software\phpStudy_64\phpstudy_pro\WWW\include/session.php
文件包含漏洞源码:
<?php
$a = $_GET["file"];
include($a);
?>
利用php:filter伪协议先以base64算法解码session文件再读取,读取后浏览器执行结果如下:
URL:
http://127.0.0.1/include/include3.php
?file=php://filter/read=convert.base64-decode/resource=
C:\securty_software\phpStudy_64\phpstudy_pro\WWW\include/session.php
浏览器报错了,简单分析下原因:session文件文件内容如下,
:1:{s:8:"username";s:28:"PD9waHAgcGhwaW5mbygpOyA/Pg==";}
解码过程中会去除特殊字符,将剩余内容(如下)解码解码需要遵循4个字符为一组,而”1s8usernames28“只有15位无法解码,从而导致无法解码报错
1s8usernames28PD9waHAgcGhwaW5mbygpOyA/Pg==
要想成功解码,需将”1s8usernames28“扩展至16位,考虑一下session的前缀“username”;s:28 中间的数字28表示后面base64串的长度,也就是说我们可以制造足够长的pyload,使pyload被编码后base64串的长度从两位数28变为三位数,这样前缀的长度就会从15个字符变为16个字符,从而能够被成功解码。
四.临时文件包含
PHP中上传文件通常采取先进行安全检查,然后将上传文件内容写入临时文件,最后将临时文件内容移动到新创建的文件中,常规代码点击此处查看条件竞争型漏洞。 此时可以在临时文件被删除前包含该临时文件,从而执行webshell脚本。
要想成功利用包含漏洞执行webshell脚本,需要知道webshell临时文件的路径,而Linux下文件保存路径是随机生成的,想要知道文件路径就得利用phpinfo页面的php varibles会直接显示上传文件/临时文件的路径。
我们可以利用如下脚本(点击查看脚本)完成条件竞争,脚本关键代码分析如下:
setup函数里构造了post和get两个请求模板,pyload变量中保存webshell数据。
下面这个setup函数中的post请求头中塞满了大量垃圾数据(每个字段插入5000个A),这样就可以延长phpinfo页面显示数据的时间,从而争取足够的时间包含临时文件。
下面这个setup函数中的get请求用于访问含有漏洞的文件,从而触发包含漏洞包含临时文件中的webshell代码。
phpInfoLFI
函数是脚本的核心,它首先发送REQ1
请求到目标服务器【s.send(phpinforeq)】,然后尝试从响应中解析出上传文件的临时文件名【第二个红框部分】。一旦获取到这个临时文件名,它就发送LFIREQ
请求【s2.send(lfireq % (fn, host))】,尝试包含并执行该临时文件(临时文件中含有webshell脚本)。