Skip to content

Instantly share code, notes, and snippets.

View samueltangz's full-sized avatar
🏳️
Capture the white flag

Samuel Tang samueltangz

🏳️
Capture the white flag
View GitHub Profile
@samueltangz
samueltangz / gctf2020-oracle.md
Last active February 12, 2024 19:20
Google CTF 2020: Oracle

Google CTF 2020: Oracle

I was teamed-up with Black Bauhinia on Google CTF this time. I have solved 7 challenges alone and 3 challenges with my teammates.

In particular, Oracle is a crypto challenge with 13 solves. It has got me spending 12 hours. All in all, it was a great experience in terms of learning, but my liver hurts. This piece of writeup may be very computation intensive, just because I would like to make everything clear.

Challenge Summary

There are two parts of the challenges. In the first part, we are required to recover an internal state for AEGIS-128L given the encryption oracle. For the second part, we are required to forge a ciphertext given an error oracle from decryption.

#!/usr/env/bin python
# -*- coding: UTF-8 -*-
from gmpy2 import powmod
import random
import dlog
m = 4902227890643
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{}_'
def gcd(a, b):
while b: a, b = b, a % b
return a
a1 = 97
b1 = 60824696933898946564451801612435320499799420685700840763560112095108031899334
a2 = 98
b2 = 55380756008140998400554730883757097743477949263876721308471329268298435052112
a3 = 99
b3 = 74193339277347514708965540905420499429551183132658118576165808841075904065168
from Crypto.Cipher import AES
from Crypto.Util.number import long_to_bytes
import hashlib
from random import randint
def sha256(my_string):
m = hashlib.sha256(my_string).digest()
v = long_to_bytes(ZZ(m.encode('hex'), 16))
return v
import time
import random
from hashlib import sha256
f = open('gov_officials_PK.txt')
ns = [ int(n) for n in f.read().strip().split('\n') ]
k = 1024
b = 2*k + 128
e = 0x10001
import struct
from z3 import *
import string
def prettify(data):
return ''.join([ ('\033[1;32m%s\033[0m' % c if c in string.printable[:-5] else '\033[2;32m_\033[0m' ) if c in string.printable else ('\033[2;31m?\033[0m' if c == '\x00' else '\033[2;33m?\033[0m') for c in data ]) + '\033[0m'
s = Solver()
char = [ BitVec('char_%d' % i, 8) for i in range(260) ]
word = [ BitVec('word_%d' % i, 16) for i in range(260) ]
import os
from pwn import *
# context.log_level = 'debug'
# copy and paste
def sha(my_string):
m = hashlib.new('sha')
m.update(my_string)
def encrypt(exp, num, key):
assert key >> 512 <= 1
num = num + key
msg = bin(num)[2:][::-1]
C, i = 0, 1
for b in msg:
C += int(b) * (exp**i + (-1)**i)
i += 1
try:
enc = hex(C)[2:].rstrip('L').decode('hex')
# 0 to 9
0 == eval("-~1")
1 == eval("1")
2 == eval("-~1")
3 == eval("3")
4 == eval("-~3")
5 == eval("-~-~3")
6 == eval("~-~-8")
7 == eval("~-8")
8 == eval("8")
def laxt(expr, num):
ops = ' %&()*+-/<>^|~'
nude = expr.translate(None, ops)
try:
if set(nude) == set(num):
flag, val = True, eval(expr)
else:
flag, val = False, None
except:
flag, val = False, None