Stumbled across a writeup on the Google CTF 2020 event. Found it interesting that although the team used pwntools, they made it over-complicated by writing the shellcode in C and then extracted the assembly code for the exploit injection. Isn't it the whole point of using pwntools is to help you generate the shellcode assembly?
Anyway, I looked up the challenge and found source code for the challenge itself and an implementation of a clean (official?) exploit. Here are the results of me playing with that code. Changes include:
- modified the Dockerfile so I can run the challenge locally. Used socat to expose the executable via port 1337 of the container
- as for the actual exploit, instead of doing a complete shellcode injection, I modified to code to just dump the flag file.
- this modification also avoided overwriting the child code with bunch of NOPs. It injects code precisely at the start of the infinite loop of the child thread (check_flag+0x8). This can be found by looking at the end of the disassembled code of the check_flag function:
4022d9: bf 01 00 00 00 mov $0x1,%edi
4022de: e8 fd cf 04 00 callq 44f2e0 <__sleep>
4022e3: e9 52 ff ff ff jmpq 40223a <check_flag+0x8>
- commands used to build the docker image, disassembling child's function, and running the exploit etc can be found in the Makefile
Detailed description of the challenge and complete source code available on github.