This is a short write up since I’m a bit lazy. We didn’t solved it during the quals as it was too late (we exhausted and most of member including myself went to sleep so I only started looking into this in the morning of Monday. Didn’t have enough of time to finish it).

For pp500, ddtek gave us a pcap network dump of a remote exploit to a daemon on host 192.41.96.63, port 6913 and password to login is ‘antagonist’. Playing around with the daemon, I found out that ‘b’ command returns you back a block of 512 bytes from the binary.

Password: antagonist
? to see the menu
> ?
x - quit
d - donate entropy
r - report
b - /dev/hrnd
? - help
> b
Seed: 0
ELF     4�$4 (444�������&& l � ��/libexec/ld-elf.so.FreeBSDk5%20   .1!
                                                                      "
/)(-*>

Seed value from 0 to 19 returned the same data, 20 returned different data, 21-39 same as 20, … So I wrote a script to extract out all the blocks from the binary with seed values 0, 20, 40, 60, 80, ….. After filtered out all the duplicated blocks, there were totally 21 unique blocks.

#!/usr/bin/env python
import sys
import socket

class humpty:
        def  __init__(self, host, port):
                self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.s.connect((host, port))
                ret = self.s.recv(1024)
                print ret

        def login(self, passwd):
                self.s.send(passwd + "n")
                ret = self.s.recv(1024)
                print ret

        def getdata(self, seed):
                print seed
                cmd = "bn"
                self.s.send(cmd)
                ret = self.s.recv(1024)
                print ret
                ret = self.s.recv(1024)
                print ret

                self.s.send("%dn" % seed)
                ret = ret + self.s.recv(1024)
                ret = ret
                #print len(ret), repr(ret)
                return ret[6:518]

        def close(self):
                self.s.close()

def log(file, data):
        f = open(file, "w")
        f.write(data)
        f.close()

host = '192.41.96.63'
port = 6913

c = humpty(host, port)
a = raw_input("Enter to continue");
c.login("antagonist")

data = []
for i in range(0, 100):
        data.append(c.getdata(20*i));

data = list(set(data))
print "Total %d unique blocks" % len(data)
for i in range(0, len(data)):
        log("%d"%i, data[i])

print "Done"
c.close()

From the pcap dump session, we can find out that the size of humpty binary is 10392, which is 21 blocks of 512 bytes

-rwxr-x---  1 root  humpty  10392 May 22 19:06 humpty
-rw-r-----  1 root  humpty     21 May 22 19:01 key

The task now is to merge all the blocks in a the right order to rebuild the ELF binary. What I did was to get a sample freebsd binary which has similar size as humpty, then used `split -b512` to split it to 21 chunks of 512 bytes and then compared side by side with the 21 extracted blocks from ddtek’s pp500 server, merged it manually and used readelf to verify the merged binary. Here (or here) is the binary for pp500′s humpty.

After getting the binary, the rest of the tasks are easy since ddtek gave us out the exploit from the pcap dump. The exploit is similar to the exploit of esd2. FYI, esd2 is the original binary for pp500 which was leaked out via pp200 shell. After ddtek guys realized of this problem, they modified the esd2, changed password, strings, commands, read elf block functions, xor input, .. and named it humpty.