Skip to content

Instantly share code, notes, and snippets.

@sea0h7e
Created October 8, 2019 07:54
Show Gist options
  • Save sea0h7e/f5b7d2ef61969fe6599d9cc2b1b1f475 to your computer and use it in GitHub Desktop.
Save sea0h7e/f5b7d2ef61969fe6599d9cc2b1b1f475 to your computer and use it in GitHub Desktop.
InCTF2019 - cookiegen (Crypto, 951 pts, 8 solves)
from pwn import *
from Crypto.Util.number import *
import hmac
from hashlib import md5
context.log_level = 'critical'
p = 337333846325195852023465984016735747017640658020735865443882234978293187151183899366894634062588357161
def register(name, base):
con = remote('18.216.251.207', 3197)
con.recvuntil('register: ')
con.sendline('1')
con.recvuntil('Enter your username: ')
con.sendline(name)
con.recvuntil('token: ')
con.sendline(str(base))
con.recvuntil('auth token: ')
return con.recvuntil('\n', True)
def login(token):
con = remote('18.216.251.207', 3197)
con.recvuntil('register: ')
con.sendline('2')
con.recvuntil('token: ')
con.sendline(token)
con.interactive()
prefix = "cookie?username="
target = 'admin' + '=' * 10
name = '1' * 15
enc1 = register(name, 233).split(':')[0].decode('hex')
enc1 = [enc1[16 * i : 16 * i + 16] for i in range(len(enc1) // 16)]
suffix = xor(md5(enc1[1]).digest(), xor(md5(enc1[2]).digest(), target + '='))
con = remote('18.216.251.207', 3197)
enc2 = register(name + '=' + suffix, 233).split(':')[0].decode('hex')
enc2 = [enc2[16 * i : 16 * i + 16] for i in range(len(enc2) // 16)]
payload = ''.join(enc1[:2])+ enc2[3] + ''.join(enc1[1:])
'''
def TonelliShanks(p, n):
Q, S = p - 1, 0
while Q % 2 == 0:
S += 1
Q //= 2
z = 0
while True:
if pow(z, (p - 1) / 2, p) == p - 1:
break
z += 1
M = S
c = pow(z, Q, p)
t = pow(n ,Q, p)
R = pow(n, (Q + 1) / 2, p)
while True:
if t == 0:
r = 0
break
elif t == 1:
r = R
break
for i in range(M):
if pow(t, pow(2, i, p), p) == 1:
break
b = pow(c, pow(2, M - i - 1, p), p)
M = i
c = pow(b, 2, p)
t = t * c % p
R = R * b % p
return r, p - r
p = 337333846325195852023465984016735747017640658020735865443882234978293187151183899366894634062588357161
n = p - 1
a, b = TonelliShanks(p, n)
assert pow(a, 2, p) == n
assert pow(b, 2, p) == n
'''
base = 121994163782610545260245062826237002508494556869862920055894528697525559257543698142374390705394532781
pos = [1L, 215339682542585306763220921190498744509146101150872945387987706280767627893640201224520243357193824380L, 121994163782610545260245062826237002508494556869862920055894528697525559257543698142374390705394532781L, 337333846325195852023465984016735747017640658020735865443882234978293187151183899366894634062588357160L]
for i in range(4):
shared_key = long_to_bytes(pos[i])
token = hmac.new(shared_key, 'admin').hexdigest()
fake = payload.encode('hex') + ':' + long_to_bytes(base).encode("hex") + ":" + token
print fake
login(fake)
#inctf{great_j0b_with_CBC_Bit_flipping_n_small_subgroup_confinement!}
import os
import sys
from cookiegen import Service
from secret import key, iv, secret, x, flag
p = 337333846325195852023465984016735747017640658020735865443882234978293187151183899366894634062588357161
class Unbuffered(object):
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
def writelines(self, datas):
self.stream.writelines(datas)
self.stream.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)
sys.stdout = Unbuffered(sys.stdout)
print "Welcome to CookieGen service!"
print "[1] Register"
print "[2] Login"
choice = int(raw_input("Select if you want to login or register: "))
if choice == 1:
username = raw_input("Enter your username: ")
if "admin" in username:
print "[-] Invalid username!"
sys.exit(0)
base = int(raw_input("Enter your base for authentication token: "))
if base < 2 or base >= p-1:
print "[-] Invalid base value!"
sys.exit(0)
service_obj = Service(key, secret, p, x, iv)
print "Here, take your cookie and auth token: ", service_obj.register(username, base)
elif choice == 2:
session_cookie = raw_input("Enter your cookie along with auth token: ")
service_obj = Service(key, secret, p, x, iv)
username = service_obj.login(session_cookie)
if username == None:
print "Invalid session cookie or auth token!"
elif username != "admin":
print "Welcome ", username
else:
print "Welcome admin! Here, take you flag", flag
from os import urandom
from Crypto.Cipher import AES
from Crypto.Util.number import *
from hashlib import md5
import hmac
def xor(a, b):
return "".join([chr(ord(i) ^ ord(j)) for i, j in zip(a, b)])
def pad(m):
padbyte = 16 - (len(m) % 16)
return m + padbyte*chr(padbyte)
def unpad(m):
if ord(m[-1]) < 0 or ord(m[-1]) > 16:
print "[-] Incorrect padding!"
sys.exit()
lastchar = ord(m[-1])
return m[:-lastchar]
class Cipher:
def __init__(self, key):
self.key = key
def encrypt(self, plaintext, iv):
plaintext = pad(plaintext)
temp = iv
ciphertext = ""
for i in range(0, len(plaintext), 16):
aes_obj = AES.new(self.key, AES.MODE_ECB)
ciphertext_block = aes_obj.encrypt(xor(plaintext[i:i+16], temp))
ciphertext += ciphertext_block
temp = md5(ciphertext_block).digest()
return iv + ciphertext
def decrypt(self, ciphertext):
iv = ciphertext[:16]
ciphertext = ciphertext[16:]
temp = iv
plaintext = ""
for i in range(0, len(ciphertext), 16):
aes_obj = AES.new(self.key, AES.MODE_ECB)
plaintext_block = xor(aes_obj.decrypt(ciphertext[i:i+16]), temp)
plaintext += plaintext_block
temp = md5(ciphertext[i:i+16]).digest()
return unpad(plaintext)
class Service:
def __init__(self, key, secret, p, x, iv):
self.key = key
self.secret = secret
self.p = p
self.x = x
self.iv = iv
def register(self, username, base):
if "admin" in username:
return "[-] Invalid username!"
plaintext = "cookie?username=" + username + "=" + self.secret
cipher_obj = Cipher(self.key)
cookie = cipher_obj.encrypt(plaintext, self.iv)
return cookie.encode("hex") + ":" + self.gen_auth_token(username, base)
def gen_auth_token(self, username, base):
if base < 2 or base >= self.p-1:
return None
shared_key = long_to_bytes(pow(base, self.x, self.p))
return long_to_bytes(base).encode("hex") + ":" + hmac.new(shared_key, username).hexdigest()
def login(self, cookie):
cookie = cookie.split(":")
try:
assert len(cookie) == 3
except:
return None
base = bytes_to_long(cookie[1].decode("hex"))
auth_token = cookie[2]
cookie = cookie[0].decode("hex")
cipher_obj = Cipher(self.key)
try:
plaintext = cipher_obj.decrypt(cookie)
except:
return None
plaintext = plaintext.split("=")
if plaintext[0] != "cookie?username":
return None
elif plaintext[-1] != self.secret:
return None
elif self.verify_auth_token(plaintext[1], base, auth_token) != True:
return None
else:
return plaintext[1]
def verify_auth_token(self, username, base, auth_token):
if base < 2 or base >= self.p-1:
return False
shared_key = long_to_bytes(pow(base, self.x, self.p))
if hmac.new(shared_key, username).hexdigest() == auth_token:
return True
else:
return False
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment