Add summary, fixups, and brain meme
This commit is contained in:
parent
b7a8a80350
commit
e0173f270b
|
@ -1,5 +1,16 @@
|
||||||
# Google CTF 2020 Write-up: Sprint
|
# Google CTF 2020 Write-up: Sprint
|
||||||
|
|
||||||
|
In this challenge, we're given a binary to reverse engineer. We find
|
||||||
|
that it's an interpreter for a Turing-complete language made entirely
|
||||||
|
of `sprintf` format strings, along with a program in this language.
|
||||||
|
We write a disassembler for this language, and use it to
|
||||||
|
reverse engineer the embedded program. We find that the embedded
|
||||||
|
program is a game, and map out a series of moves to win the game.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Picking apart the binary
|
## Picking apart the binary
|
||||||
|
|
||||||
We're given a single binary file. Running it through `objdump`, we
|
We're given a single binary file. Running it through `objdump`, we
|
||||||
|
@ -149,7 +160,7 @@ In order:
|
||||||
to by vararg 3. That is, it writes it to the lower two bytes of
|
to by vararg 3. That is, it writes it to the lower two bytes of
|
||||||
`regs[0]`.
|
`regs[0]`.
|
||||||
3. `%1$65498s` writes 65498 spaces, so the total number of spaces so
|
3. `%1$65498s` writes 65498 spaces, so the total number of spaces so
|
||||||
far is 65536, or `0x10000`.
|
far is 65536, or `0x10000`.
|
||||||
4. `%1$28672s` writes 28672 spaces, or `0x7000` spaces.
|
4. `%1$28672s` writes 28672 spaces, or `0x7000` spaces.
|
||||||
5. `%9$hn` counts the number of characters written so far, and writes
|
5. `%9$hn` counts the number of characters written so far, and writes
|
||||||
it to the `short int` pointed to by vararg 9. That is, the lower
|
it to the `short int` pointed to by vararg 9. That is, the lower
|
||||||
|
@ -346,7 +357,7 @@ Now we can see the output:
|
||||||
### Using `gdb`
|
### Using `gdb`
|
||||||
|
|
||||||
Now we have yet another chunk of assembly to reverse. It will be
|
Now we have yet another chunk of assembly to reverse. It will be
|
||||||
useful to be able to use `gdb` to step through this code, so lets
|
useful to be able to use `gdb` to step through this code, so let's
|
||||||
understand how to do that. The call to `sprintf` is at `main+555`, so
|
understand how to do that. The call to `sprintf` is at `main+555`, so
|
||||||
by putting a breakpoint there, we can step through the embedded code
|
by putting a breakpoint there, we can step through the embedded code
|
||||||
one instruction at a time. To view the 10 registers, we can examine
|
one instruction at a time. To view the 10 registers, we can examine
|
||||||
|
@ -404,7 +415,9 @@ but I'll leave that out for brevity.
|
||||||
|
|
||||||
We'll jump straight to the first place where we read the user input.
|
We'll jump straight to the first place where we read the user input.
|
||||||
Instead of picking apart the code before that, we can just use `gdb`
|
Instead of picking apart the code before that, we can just use `gdb`
|
||||||
to examine the state of the program at this point.
|
to examine the state of the program at this point. Since the earlier
|
||||||
|
code doesn't reference the user input, the state here will always be
|
||||||
|
the same.
|
||||||
|
|
||||||
0374: mov 0xe000, %r2 # Address of user input
|
0374: mov 0xe000, %r2 # Address of user input
|
||||||
039a: mov 0x0, %r3 # Counter, initialized to 0
|
039a: mov 0x0, %r3 # Counter, initialized to 0
|
||||||
|
@ -444,7 +457,7 @@ Next we load some data into registers
|
||||||
0536: mov 0x0, %r2
|
0536: mov 0x0, %r2
|
||||||
0558: mov 0x0, %r3
|
0558: mov 0x0, %r3
|
||||||
057b: mov 0xf100, %r1
|
057b: mov 0xf100, %r1
|
||||||
05a1: mov (%r1), %r4 # Read from 0xf100, value = 0x11
|
05a1: mov (%r1), %r4 # Read from 0xf100, value = 0x11
|
||||||
05c6: mov 0x1, %r5
|
05c6: mov 0x1, %r5
|
||||||
05e9: mov 0x0, %r9
|
05e9: mov 0x0, %r9
|
||||||
|
|
||||||
|
@ -588,7 +601,7 @@ can't ever enter an invalid direction, and we can't ever step on
|
||||||
nonzero terrain. We also see that we need to step on exactly nine
|
nonzero terrain. We also see that we need to step on exactly nine
|
||||||
checkpoints.
|
checkpoints.
|
||||||
|
|
||||||
The register `%r9` appears to hold a "reason code" for why we lose.
|
The register `%r9` appears to hold a reason code for why we lose.
|
||||||
This could be useful for debugging later.
|
This could be useful for debugging later.
|
||||||
|
|
||||||
There's still more code after, but for now our task is clear: we need
|
There's still more code after, but for now our task is clear: we need
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 253 KiB |
Loading…
Reference in New Issue