The
setting for this scenario was DefCon 20 “Capture The Flag” in Las Vegas. Each server was set up with a spanning port
so that each team could see traffic for their server, and we had a notification
system set up so that if we saw one of our secret keys going off the wire, our
packet capture system would dump the last minute of traffic into a PCAP file
for analysis. We will focus on an
exploit that was detected against a service named “coney”.
Once
the exploit was seen on the wire, the packet captures revealed the following:
(The red is sent from the
attacker and the blue is the server response.)
The key is the 32-byte ASCII sequence on the 5th from the
bottom line, which is what triggered the notification system that the service
was being exploited. So, analyzing the
packet capture, there is a question response system:
ATTACKER: “I’m internet
famous!\n” (authentication)
SERVER: 16-byte key
SERVER: “enter ip:”
ATTACKER: “dc20:c7f:2012:f:0:0:0:22” (attacker’s IP for the server to connect back to)
ATTACKER: “dc20:c7f:2012:f:0:0:0:22” (attacker’s IP for the server to connect back to)
SERVER: “knock knock!”
ATTACKER: 32-byte key
(authentication)
ATTACKER: (exploit)
SERVER: key + adjacent RAM
The
first problem to overcome is that the server gives the client a 16-byte key,
but expects a 32 byte one in order to reach the vulnerable code-path. Upon observation, the keys change every
connection, governed by /dev/urandom.
Running this shows that the server is kind enough to send 2 UDP packets
24 bytes long to the IPv6 address specified by the attacker. Each UDP packet has the same 16-byte key that
was in the original connection, but appended
is another 8 bytes. Concatenated
together {original 16 byte key} + {8 byte key from UDP1} + {8 byte key from
UDP2} == 32-byte key to get to the exploitable code. Unfortunately, the UDP packets sent to the
attacker are sent to random addresses.
The potential for guessing the ports is one pathway to pursue to solve this
problem, but the easy (and most quickly implemented) is to listen on all UDP
ports 1-65535. We now know how to reach
the exploitable code path and can go about dis-assembling the exploit!
From
just a cursory look, the exploit is sandwiched in-between a NOP sled and a
bunch of return addresses. The many
0xBA’s result in 5-byte instructions “0xBA 0xBABABABA”, in assembly: mov dx,
0xBABABABA. We can assume this is a sled
for EIP to hit once the overflow happens, and the 0x16ce9595’s at the end are
the part of an overflow that overwrites a return address and causes execution
to land in the sled.
Note,
the theme of the contest is “everything sheep”, and so the creators of the
exploit paid homage to the contest organizers with their “BA BA” sled.
The
next step is to extract the exploit and analyze it. Sometimes this is not the simplest process,
as most exploits rely on weird little tricks to compensate for the lack of
knowledge about where they are in memory space.
Here is a sample disassembly in IDA:
and since I don't have a big monitor and it chopped the bottom:
Without looking those far
jumps and calls, we can assume the following:
1.
Since the exploit
has its strings imbedded in it, it needs to get a reference to the stack so it
can use them for function calls. The
string at 0x03e4 -> 0x03f7 could be such a string.
2.
The exploit has
to either get references to the import table so that it can call functions that
the program uses, or it has to call absolute addresses to do things. In this case, it looks like it is using an
absolute reference to the programs function table.
3.
From the packet
capture, the key is printed out, and then some RAM. This could be two things: the key has been
read into memory adjacent to the exploit’s reference to the key file or the key file has been referenced by
the program and the exploit is just using a reference to the string to call a
read. We will assume the former, and not
the latter (for the moment).
The
first jump is most likely a call to a reference giving instruction inside of
the programs TEXT segment to get the address of the stack. The next two calls we can determine by the
following criteria: The exploit does not have another string of bytes inside of
it (indicating it doesn’t overwrite our key), so we can assume the exploits
goal is to print out the key file in the current working directory, and the key
is 32-bytes long (0x20 hex). It then
needs to print out this key on the current socket. So, the following calls are needed:
1.
file_handle = OPEN(“/home/coney/key”,
“r”)
2.
storage_area =
READ(file_handle, 32 bytes)
3.
WRITE(socket_handle,
&storage_area)
4.
Exit / crash
Near
the bottom of the exploit listing, there are 3 interesting adds: 0x4f474542 +
0x4f444549 + 0x81534f41. The potential
exists that, despite IDA saying that those instructions are valid, it is
actually a string. Pulling the last 32
bytes and brute force xor’ing them revealed that following about the last 15
bytes: “^EBEGO^EIEDOS^EAOS” xor 0x2a == “/home/coney/key”. That would be the string needed for the OPEN
call.
Re-analyzing
the program in light of this in IDA reveals the following:
With
this understanding, we can see that the program jumps down to the bottom
(0x000003e4) to get a reference to the stack, then back to the decryption
section in the middle of the program, the decryption section xors the encrypted
“/home/coney/key” string, then jumps to the OPEN call (0x000003a4), which then
follows on to the read call (0x00003ac), then to the WRITE(socket, data) call
(0x00003c5).
Now
that the exploit is fully understood, re-using it is trivial. Since the exploit is kind enough to re-use
the socket file handle and write the key back onto it, there is no need to
alter it in order to immediately start exploiting other team’s servers! Overwriting their keys or gaining a shell is
the next step, and since we know where code execution begins within the
exploit, all we have to do is substitute the existing shell code with our own,
making sure to respect the correct offsets and space requirements.





As a farmer with livestock, I rely on tractors for tasks like feeding and managing manure. The john deere 4440 stands out as a compelling option, but I’m also looking at the john deere 5020 for more intensive fieldwork. For tillage, the john deere 4640 appears to be an excellent fit, whereas the kubota b7100 might be suitable for everyday tasks. Finally, I’m weighing whether the john deere 1010 would offer the best value for multi-purpose use on my farm. Which one do you recommend I get?
ReplyDelete