HITCON writeup - sha1lcode
I participated in Hitcon CTF 2014 late, and didn't take it too serious as I have been busy with other things. The good CTFs always tend to come at the wrong time for me :), or maybe everytime for me is the wrong time. Anyway, we (me and a friend) have ranked around 50 by the end of the game with around 1000 pts. Solved "callme, rsbo, tarmful, sha1lcode, and vash". One of the challenges that I enjoyed solving was sha1lcode it was definitly a very creative challenge. We are provided with an ELF x86 64-bit file to exploit. I have reverse engineered the file and it looks something like
What this do is it reads number n where n < 1000 then it reads n number of strings of length 16 into a memory then it converts those strings to SHA1 hashes adding them inside code, after that input (The read strings) is zeroed and it jumps and executes the generated hashes. What we need to do here is generate the right hashes that contains useful opcodes.
To do that we have to find a random 16 bytes string that will generate a SHA1 hash that has valid opcodes. My approach was to find such strings and SHA1 hashes that has 3-4 opcodes that I want at the beginning and those opcodes should be as follow. The first onw or two bytes is whatever we want to build the payload, the second two bytes is a jump to the next hash. So we build a chained payload. Eg:
It's a little too much work to make this do something useful and it will take a while to find the right strings. The longer the opcodes the more time it will take to find them, so we stick with 3-4 bytes. I found a shortcut I noticed that it will be easier to :
- Set rax = 0 -> by push rbx, pop rax
- Set rdi = rbx -> by push rbx, pop rdi
- Set rsi = rcx -> by push rcx, pop rsi
- Do a syscall (read)
- Call rsi
We use pops and pushes since they only have one byte (easier to find). rsi contains &code which our sha1 generated hashes reside at, we zero rax because 0 is sys_read. Then we have rax = syscall_read(rsi,rdi,rdx...) This will allow us to read from stdin more data into &code and then call rsi is simply starting from the beginning of the generated hashes area, executing our next payload.
The exploit :