(原文:https://www.yuque.com/ni4n/blogs/qm4g1s 作者:Ni4n)

包含日志文件

当常规的伪协议及一些关键词被过滤时,我们可以考虑在访问时于user-agent写入命令执行代码,然后再去包含日志文件即可实现RCE。

demo

  1. <?php
  2. if(isset($_GET['file'])){
  3. $file = $_GET['file'];
  4. $file = str_replace("php", "???", $file);
  5. $file = str_replace("data", "???", $file);
  6. include($file);
  7. }else{
  8. highlight_file(__FILE__);
  9. }

bp抓包实现如下构造然后放包两次,第一次放包将代码写入日志,第二次放包实现包含。

文件包含学习杂记(转载) - 图1

注意:

需要知道日志文件的存放路径。

利用session.upload_progress进行文件包含

在PHP5.4之后新添加了一个特性

文件包含学习杂记(转载) - 图2

也就是说当session.upload_progress.enabled = on 时,我们可以POST一个与INI中设置的session.upload_progress.name同名变量,并将变量值设为一句话木马,就能将木马写入session文件,session.upload_progress.name的默认名为PHP_SESSION_UPLOAD_PROGRESS

注:在Linux系统中,session文件一般的默认存储位置为 /tmp 或 /var/lib/php/session

然后看另一个默认选项

文件包含学习杂记(转载) - 图3

其默认为关闭状态,即我们可以自定义Session ID,如,我们在Cookie里设置PHPSESSID=ctf,PHP将会在服务器上创建一个文件:/tmp/sess_ctf”。即使此时用户没有初始化Session,PHP也会自动初始化Session,并产生一个键值。

如此一来,session文件名及文件内容可控,我们就可以写入木马然后进行包含了,但是

文件包含学习杂记(转载) - 图4

即在上传后其会立即清除掉我们的session文件,所以我们就需要利用条件竞争对其进行利用。

demo

  1. <?php
  2. if(isset($_GET['file'])){
  3. $file = $_GET['file'];
  4. $file = str_replace("php", "???", $file);
  5. $file = str_replace("data", "???", $file);
  6. $file = str_replace(":", "???", $file);
  7. $file = str_replace(".", "???", $file);
  8. include($file);
  9. }else{
  10. highlight_file(__FILE__);
  11. }

利用

首先随意上传个文件

  1. <!DOCTYPE html>
  2. <html>
  3. <body>
  4. <form action="http://c2526f5b-c6ab-4843-b0aa-756d227456ec.chall.ctf.show/" method="POST" enctype="multipart/form-data">
  5. <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
  6. <input type="file" name="file" />
  7. <input type="submit" value="submit" />
  8. </form>
  9. </body>
  10. </html>

然后抓包,在cookie里设置PHPSESSID=ctf ,这样产生的session文件名就为sess_ctf,然后在PHP_SESSION_UPLOAD_PROGRESS 下写入命令执行代码。然后利用爆破模块进行空值爆破。

文件包含学习杂记(转载) - 图5

然后传参?file=/tmp/sess_ctf 同样抓包进行空值爆破。

文件包含学习杂记(转载) - 图6

然后发现成功执行

文件包含学习杂记(转载) - 图7

绕过死亡die

在一些不允许用户直接访问的文件,如缓存、配置文件等地方都会加上exitdie 等进行限制,这样即使进行包含也无法执行。

demo

可以看到其过滤了大部分伪协议的关键字,但是可以通过content进行传参;也就是说可以向指定$file 写入恶意代码,但是我们看到,在写入时其会预先写入die 导致我们的代码无法执行。

  1. <?php
  2. if(isset($_GET['file'])){
  3. $file = $_GET['file'];
  4. $content = $_POST['content'];
  5. $file = str_replace("php", "???", $file);
  6. $file = str_replace("data", "???", $file);
  7. $file = str_replace(":", "???", $file);
  8. $file = str_replace(".", "???", $file);
  9. file_put_contents(urldecode($file), "<?php die('大佬别秀了');?>".$content);
  10. }else{
  11. highlight_file(__FILE__);
  12. }

base64-decode绕过

BASE64编码中只包含64个可打印字符,而PHP在解码时遇到不在其中的字符数会跳过这些字符,仅将合法字符组成新的字符串进行解码,所以当$content 加上<?php die();?> 等时,其只对”phpdie”解码而已。

再根据BASE64解析规则—以4个byte一组,我们可以在其前面加上两个字母使其凑够4的倍数;随后以BASE64写入木马,这样在其解码后就会执行我们的代码。

利用

首先我们用filter协议进行写入

payload:php:``//filter``/write=convert.base64-decode/resource``=``123``.php

但是此处我们要进行两次URL编码进行绕过。

  1. %25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%34%25%36%35%25%36%33%25%36%66%25%36%34%25%36%35%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%33%31%25%33%32%25%33%33%25%32%65%25%37%30%25%36%38%25%37%30

然后对content进行传参,首先加上两个字母,然后后面跟上我们BASE64加密之后的一句话木马

文件包含学习杂记(转载) - 图8

然后我们去123.php处进行命令执行即可。

文件包含学习杂记(转载) - 图9

还有一些其他方法见谈一谈php://filter的妙用

一些bypass

指定前缀绕过

  1. <?php
  2. error_reporting(0);
  3. $file = $_GET["file"];
  4. //前缀
  5. include "/var/www/html/".$file;
  6. highlight_file(__FILE__);
  7. ?>

利用../ 切换目录。

  1. ?file=../../log/nginx/access.log

指定后缀绕过

  1. <?php
  2. error_reporting(0);
  3. $file = $_GET["file"];
  4. //后缀
  5. include $file.".txt";
  6. highlight_file(__FILE__);
  7. ?>

可用截断方法

  1. ?
  2. %00 //5.3.4以后失效
  3. 空格
  4. #

参考链接

谈一谈php://filter的妙用

利用session.upload_progress进行文件包含

ctf文件包含总结

利用session.upload_progress进行文件包含和反序列化渗透

php://filter的各种过滤器