基本二进制利用方法论

Reading time: 10 minutes

tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)

支持 HackTricks

ELF 基本信息

在开始利用任何东西之前,了解 ELF 二进制文件 的结构是很有趣的:

ELF Basic Information

利用工具

Exploiting Tools

栈溢出方法论

有这么多技术时,拥有一个方案来确定每种技术何时有用是很好的。请注意,相同的保护措施会影响不同的技术。您可以在每个保护部分找到绕过保护的方法,但在此方法论中找不到。

控制流程

您可以通过不同的方式控制程序的流程:

  • 栈溢出 通过覆盖栈中的返回指针或 EBP -> ESP -> EIP。
  • 可能需要利用 整数溢出 来导致溢出
  • 或通过 任意写入 + 写入什么到哪里执行
  • 格式字符串: 利用 printf 在任意地址写入任意内容。
  • 数组索引: 利用设计不良的索引来控制某些数组并获得任意写入。
  • 可能需要利用 整数溢出 来导致溢出
  • bof 到 WWW 通过 ROP: 利用缓冲区溢出构造 ROP 并能够获得 WWW。

您可以在以下位置找到 写入什么到哪里执行 技术:

Write What Where 2 Exec

永久循环

需要考虑的一点是,通常 仅仅利用一次漏洞可能不足以 执行成功的利用,特别是某些保护需要被绕过。因此,讨论一些选项以 使单个漏洞在同一二进制执行中可利用多次 是很有趣的:

  • ROP 链中写入 main 函数 的地址或发生 漏洞 的地址。
  • 控制一个合适的 ROP 链,您可能能够在该链中执行所有操作
  • 在 GOT 中写入 exit 地址(或二进制在结束前使用的任何其他函数)到 返回漏洞
  • .fini_array中所述, 在这里存储 2 个函数,一个用于再次调用漏洞,另一个用于调用 __libc_csu_fini,它将再次调用 .fini_array 中的函数。

利用目标

目标:调用现有函数

  • ret2win: 代码中有一个函数需要调用(可能带有一些特定参数)以获取标志。
  • 没有 PIE canary 的常规 bof 中,您只需在存储在栈中的返回地址中写入地址。
  • 在带有 PIE 的 bof 中,您需要绕过它
  • 在带有 canary 的 bof 中,您需要绕过它
  • 如果您需要设置多个参数以正确调用 ret2win 函数,您可以使用:
  • 如果有足够的 gadgets,可以使用 ROP **链来准备所有参数
  • SROP(如果您可以调用此系统调用)来控制许多寄存器
  • 来自 ret2csuret2vdso 的 gadgets 来控制多个寄存器
  • 通过 写入什么到哪里,您可以利用其他漏洞(不是 bof)来调用 win 函数。
  • 指针重定向: 如果栈包含指向将要调用的函数或将要被有趣的函数(system 或 printf)使用的字符串的指针,则可以覆盖该地址。
  • ASLRPIE 可能会影响地址。
  • 未初始化变量: 你永远不知道。

目标:RCE

通过 shellcode,如果 nx 被禁用或将 shellcode 与 ROP 混合:

  • (栈) Shellcode: 这对于在覆盖返回指针之前或之后在栈中存储 shellcode 并然后 跳转到它 执行是有用的:
  • 在任何情况下,如果有 canary 在常规 bof 中,您需要绕过(泄漏)它
  • 没有 ASLR nx,可以跳转到栈的地址,因为它不会改变
  • ASLR,您需要使用 ret2esp/ret2reg 等技术来跳转到它
  • nx,您需要使用一些 ROP 来调用 memprotect 并使某些页面 rwx,然后 在其中存储 shellcode(例如调用 read)并跳转到那里。
  • 这将把 shellcode 与 ROP 链混合。

通过系统调用

  • Ret2syscall: 有用的调用 execve 来运行任意命令。您需要能够找到 调用特定系统调用的 gadgets 及其参数
  • 如果启用了 ASLRPIE,您需要击败它们 以便使用二进制文件或库中的 ROP gadgets
  • SROP 可以用于准备 ret2execve
  • 来自 ret2csuret2vdso 的 gadgets 来控制多个寄存器

通过 libc

  • Ret2lib: 有用的调用库中的函数(通常来自 libc),如 system,并带有一些准备好的参数(例如 '/bin/sh')。您需要二进制文件 加载库 以调用您想要的函数(通常是 libc)。
  • 如果 静态编译且没有 PIEsystem/bin/sh地址 不会改变,因此可以静态使用它们。
  • 没有 ASLR 并且知道加载的 libc 版本system/bin/sh地址 不会改变,因此可以静态使用它们。
  • ASLR 但没有 PIE 的情况下,知道 libc 并且二进制文件使用 system 函数,可以ret 返回到 GOT 中 system 的地址,并将 '/bin/sh' 的地址作为参数(您需要弄清楚这一点)。
  • ASLR 但没有 PIE,知道 libc 并且 没有二进制文件使用 system
  • 使用 ret2dlresolve 来解析 system 的地址并调用它
  • 绕过 ASLR 并计算 system'/bin/sh' 在内存中的地址。
  • ASLR PIE 并且不知道 libc:您需要:
  • 绕过 PIE
  • 找到使用的 libc 版本(泄漏几个函数地址)
  • 检查 与 ASLR 相关的先前场景 以继续。

通过 EBP/RBP

  • 栈转移 / EBP2Ret / EBP 链接: 控制 ESP 以通过存储在栈中的 EBP 控制 RET。
  • 对于 off-by-one 栈溢出很有用
  • 作为控制 EIP 的替代方法,同时利用 EIP 在内存中构造有效负载,然后通过 EBP 跳转到它

其他

  • 指针重定向: 如果栈包含指向将要调用的函数或将要被有趣的函数(system 或 printf)使用的字符串的指针,则可以覆盖该地址。
  • ASLRPIE 可能会影响地址。
  • 未初始化变量: 你永远不知道。

tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)

支持 HackTricks