[第五空间 2021]EasyCleanup

POC

这题对于我来说有难度,不看WP确实写不出来

首先题目给了源码

 <?php 
if(!isset($_GET['mode'])){ 
    highlight_file(__file__); 
}else if($_GET['mode'] == "eval"){ 
    $shell = isset($_GET['shell']) ? $_GET['shell'] : 'phpinfo();'; 
    if(strlen($shell) > 15 | filter($shell) | checkNums($shell)) exit("hacker"); 
    eval($shell); 
} 


if(isset($_GET['file'])){ 
    if(strlen($_GET['file']) > 15 | filter($_GET['file'])) exit("hacker"); 
    include $_GET['file']; 
} 


function filter($var){ 
    $banned = ["while", "for", "\$_", "include", "env", "require", "?", ":", "^", "+", "-", "%", "*", "`"]; 

    foreach($banned as $ban){ 
        if(strstr($var, $ban)) return True; 
    } 

    return False; 
} 

function checkNums($var){ 
    $alphanum = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 
    $cnt = 0; 
    for($i = 0; $i < strlen($alphanum); $i++){ 
        for($j = 0; $j < strlen($var); $j++){ 
            if($var[$j] == $alphanum[$i]){ 
                $cnt += 1; 
                if($cnt > 8) return True; 
            } 
        } 
    } 
    return False; 
} 
?> 

从这里可以发现两个攻击点,一是eval()函数的RCE攻击点,第二个就是include的文件包含攻击点

RCE那里有很多过滤,很难从那里去攻击,那么只能去看include的了,这里应该要思考到include应该要包含一些我们可以利用的文件,首先日志文件是一个方向,但是日志文件太杂乱,不是那么容易就可以成功包含并且利用的;但是源码中提供了phpinfo,那么这个phpinfo就一定是有用的,没用他不会放在这里,我们查看phpinfo,可以发现里面开启了如下几个我们可以利用的功能

 

  • session.auto_start:如果 session.auto_start=On ,则PHP在接收请求的时候会自动初始化 Session,不再需要执行session_start()。但默认情况下,这个选项都是关闭的。但session还有一个默认选项,session.use_strict_mode默认值为 off。此时用户是可以自己定义 Session ID 的。比如,我们在 Cookie 里设置 PHPSESSID=ph0ebus ,PHP 将会在服务器上创建一个文件:/tmp/sess_ph0ebus”。即使此时用户没有初始化Session,PHP也会自动初始化Session。 并产生一个键值,这个键值有ini.get(“session.upload_progress.prefix”)+由我们构造的 session.upload_progress.name 值组成,最后被写入 sess_ 文件里。
  • session.save_path:负责 session 文件的存放位置,后面文件包含的时候需要知道恶意文件的位置,如果没有配置则不会生成session文件
  • session.upload_progress_enabled:当这个配置为 On 时,代表 session.upload_progress 功能开始,如果这个选项关闭,则这个方法用不了
  • session.upload_progress_cleanup:这个选项默认也是 On,也就是说当文件上传结束时,session 文件中有关上传进度的信息立马就会被删除掉;这里就给我们的操作造成了很大的困难,我们就只能使用条件竞争(Race Condition)的方式不停的发包,争取在它被删除掉之前就成功利用
  • session.upload_progress_name:当它出现在表单中,php将会报告上传进度,最大的好处是,它的值可控
  • session.upload_progress_prefix:它+session.upload_progress_name 将表示为 session 中的键名

综上所述,这种利用方式需要满足下面几个条件:

  • 目标环境开启了session.upload_progress.enable选项
  • 发送一个文件上传请求,其中包含一个文件表单和一个名字是PHP_SESSION_UPLOAD_PROGRESS的字段
  • 请求的Cookie中包含Session ID

注意的是,如果我们只上传一个文件,这里也是不会遗留下Session文件的,所以表单里必须有两个以上的文件上传 。

接着放上网上现成的Python脚本

session.upload_progress临时文件包含漏洞利用脚本