XSS姿势-文件上传XSS复现学习

0x00 前言

偶然看到国外大神brutelogic的XSS学习记录博客,博客里有许多XSS方面的干货文章,非常值得深入学习和研究,其中的一篇文章File Upload XSS,国内也有人翻译过:技术分享:如何利用文件上传执行XSS? ,所以便跟着学习一波,做一下记录。另外我一直崇拜的Black-Hole表哥也写了一个XSS的原理分析与解剖以及挖掘系列,推荐去涨一波姿势。

0x01 文件上传XSS

在说文件上传XSS之前我们先把什么是XSS这个问题搞清楚,XSS跨站脚本(Cross-Site Scripting)是一种经常出现在Web应用程序中的安全漏洞,一般是由于Web应用程序对用户的输入过滤不足或过滤被绕过而产生的。攻击者利用此类漏洞把恶意代码(通常包括HTML代码和客户端JavaScript脚本)通过各种方式注入到网页(可以是网页中其他媒体为攻击载体,如:图片)之中,当其他用户浏览被注入恶意代码的网页时,就会触发执行其中的恶意代码,从而达到受害者的Cookie被窃取、(浏览器)会话被劫持、钓鱼欺骗、传播XSS蠕虫、网页挂马或植入广告、触发受害者非自愿恶意操作如删除文章,控制受害者机器向其他浏览器发起恶意攻击、结合其他漏洞如CSRF实施进一步攻击、在渗透网站过程提升用户权限等等攻击者目的,因此通常我们称这种攻击方式为XSS跨站脚本攻击。根据XSS特性和利用方法主要分为反射型跨站脚本、持久型跨站脚本XSS、这里讲的文件上传XSS主要是反射型的,这里我所理解的文件上传XSS主要是指通过以上传的文件(形如图片文件)作为精心构造好的XSS恶意代码payload攻击载体的形式来实现XSS攻击。总的来说原理一样,不过实现的方式不一样。

0x01 文件名方式

我们知道windows与linux文件命名有所差别,windows下文件名不能包含 / \ : * ? “ < > | 字符,而linux下是可以出现除 / 字符之外的其它所有的字符,而且在Linux系统中可以使用长文件或目录名,直接利用这个特性,在上传点没有对文件名进行检测和处理的情况下就可以实现XSS攻击。

比如上传处理代码是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
$html = '';
if (!empty($_FILES['uploaded']['tmp_name'])) {
echo 'Filename Upload XSS Demo';
$target_path = "uploads/";
$target_path = $target_path . basename($_FILES['uploaded']['name']);
$uploaded_name = $_FILES['uploaded']['name'];
$uploaded_type = $_FILES['uploaded']['type'];
$uploaded_size = $_FILES['uploaded']['size'];
echo '<br>';
echo $uploaded_type;
if ($uploaded_type == "image/jpeg && $uploaded_size < 100000000") {
if (!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) {
$html .= '<pre>';
$html .= 'Your image was not uploaded.';
$html .= '</pre>';
echo $html;
} else {
$html .= '<pre>';
$html .= $target_path . ' succesfully uploaded!';
$html .= '</pre>';
echo $html;
}
} else {
echo '<pre>Your image was not uploaded.</pre>';
}
}
?>

从代码中可看出只是简单地对文件类型和文件大小进行了判断,并没有对文件名进行处理。