# 二进制基础渗透方法论
从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS Red Team Expert) 支持HackTricks的其他方式: * 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)! * 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com) * 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们的独家[NFT](https://opensea.io/collection/the-peass-family)收藏品 * **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或在**Twitter**上关注我们 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**。** * 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
## ELF基础信息 在开始利用任何东西之前,了解**ELF二进制文件**的结构的一部分是很有趣的: {% content-ref url="elf-tricks.md" %} [elf-tricks.md](elf-tricks.md) {% endcontent-ref %} ## 利用工具 {% content-ref url="tools/" %} [tools](tools/) {% endcontent-ref %} ## 栈溢出方法论 有这么多技术,有一个方案在何时使用每种技术会很有帮助。请注意,相同的保护措施会影响不同的技术。您可以在每个保护部分找到绕过保护的方法,但在此方法论中没有提及。 ## 控制流程 有不同的方法可以控制程序的流程: * [**栈溢出**](../stack-overflow/) 覆盖栈上的返回指针或 EBP -> ESP -> EIP。 * 可能需要滥用[**整数溢出**](../integer-overflow.md) 来引发溢出 * 或通过**任意写入 + 写入何处执行**来实现 * [**格式化字符串**](../format-strings/)**:**滥用 `printf` 在任意地址写入任意内容。 * [**数组索引**](../array-indexing.md):滥用设计不良的索引以控制某些数组并进行任意写入。 * 可能需要滥用[**整数溢出**](../integer-overflow.md) 来引发溢出 * **bof to WWW via ROP**:滥用缓冲区溢出构建ROP,从而能够获得WWW。 您可以在以下位置找到**写入何处执行**技术: {% content-ref url="../arbitrary-write-2-exec/" %} [arbitrary-write-2-exec](../arbitrary-write-2-exec/) {% endcontent-ref %} ## 永久循环 需要考虑的一点是通常**仅利用漏洞一次可能不足以执行成功的利用**,特别是需要绕过某些保护措施。因此,有趣的是讨论一些选项,**使单个漏洞在二进制文件的同一执行中可多次利用**: * 在**ROP**链中写入**`main`函数的地址**或漏洞发生的地址。 * 通过控制正确的ROP链,您可能能够执行该链中的所有操作 * 在**GOT中的`exit`地址**(或二进制文件在结束前使用的任何其他函数)中写入返回到漏洞的地址 * 如[**.fini\_array**](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini\_array.md#eternal-loop)所述,这里存储2个函数,一个用于再次调用漏洞,另一个用于调用**`__libc_csu_fini`**,后者将再次调用`.fini_array`中的函数。 ## 利用目标 ### 目标:调用现有函数 * [**ret2win**](./#ret2win):代码中有一个需要调用的函数(可能带有一些特定参数)以获取标志。 * 在没有[**PIE**](../common-binary-protections-and-bypasses/pie/)和[**canary**](../common-binary-protections-and-bypasses/stack-canaries/)的常规bof中,只需在栈中存储的返回地址中写入地址。 * 在带有[**PIE**](../common-binary-protections-and-bypasses/pie/)的bof中,您将需要绕过它 * 在带有[**canary**](../common-binary-protections-and-bypasses/stack-canaries/)的bof中,您将需要绕过它 * 如果需要设置多个参数以正确调用**ret2win**函数,您可以使用: * 如果有足够的gadgets,可以使用[**ROP**](./#rop-and-ret2...-techniques)链来准备所有参数 * [**SROP**](../rop-return-oriented-programing/srop-sigreturn-oriented-programming.md)(如果可以调用此系统调用)来控制许多寄存器 * 来自[**ret2csu**](../rop-return-oriented-programing/ret2csu.md)和[**ret2vdso**](../rop-return-oriented-programing/ret2vdso.md)的gadgets来控制多个寄存器 * 通过[**Write What Where**](../arbitrary-write-2-exec/),您可以滥用其他漏洞(非bof)来调用**`win`**函数。 * [**指针重定向**](../stack-overflow/pointer-redirecting.md):如果栈包含指向将要调用的函数或将要被有趣函数(system或printf)使用的字符串的指针,可以覆盖该地址。 * [**ASLR**](../common-binary-protections-and-bypasses/aslr/)或[**PIE**](../common-binary-protections-and-bypasses/pie/)可能会影响地址。 * [**未初始化变量**](../stack-overflow/uninitialized-variables.md):您永远不知道。 ### 目标:RCE #### 通过shellcode,如果nx被禁用或将shellcode与ROP混合: * [**(Stack) Shellcode**](./#stack-shellcode):这对于在覆盖返回指针之前或之后在栈中存储shellcode,然后**跳转到它**以执行它非常有用: * **在任何情况下,如果有** [**canary**](../common-binary-protections-and-bypasses/stack-canaries/)**,在常规bof中您将需要绕过(泄漏)它 * **没有** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **和** [**nx**](../common-binary-protections-and-bypasses/no-exec-nx.md),可以跳转到栈的地址,因为它永远不会改变 * **有** [**ASLR**](../common-binary-protections-and-bypasses/aslr/),您将需要使用技术,如[**ret2esp/ret2reg**](../rop-return-oriented-programing/ret2esp-ret2reg.md)来跳转到它 * **有** [**nx**](../common-binary-protections-and-bypasses/no-exec-nx.md),您将需要使用一些[**ROP**](../rop-return-oriented-programing/) **来调用`memprotect`**,使某些页面`rwx`,然后**在那里存储shellcode**(例如调用read)然后跳转到那里。 * 这将混合shellcode与ROP链。 #### 通过syscalls * [**Ret2syscall**](../rop-return-oriented-programing/rop-syscall-execv.md): 用于调用`execve`以运行任意命令。您需要能够找到**调用特定syscall的gadgets及其参数**。 * 如果启用了[**ASLR**](../common-binary-protections-and-bypasses/aslr/)或[**PIE**](../common-binary-protections-and-bypasses/pie/),您需要打败它们,**以便使用二进制文件或库中的ROP gadgets**。 * [**SROP**](../rop-return-oriented-programing/srop-sigreturn-oriented-programming.md)可用于准备**ret2execve**。 * 来自[**ret2csu**](../rop-return-oriented-programing/ret2csu.md)和[**ret2vdso**](../rop-return-oriented-programing/ret2vdso.md)的gadgets可用于控制多个寄存器。 #### 通过libc * [**Ret2lib**](../rop-return-oriented-programing/ret2lib/): 用于调用库中的函数(通常是**`libc`**)如**`system`**并带有一些准备好的参数(例如`'/bin/sh'`)。您需要二进制文件**加载包含要调用的函数的库**(通常是libc)。 * 如果**静态编译且没有**[**PIE**](../common-binary-protections-and-bypasses/pie/),则`system`和`/bin/sh`的**地址**不会改变,因此可以静态使用它们。 * **没有**[**ASLR**](../common-binary-protections-and-bypasses/aslr/) **且知道加载的libc版本**,`system`和`/bin/sh`的**地址**不会改变,因此可以静态使用它们。 * 具有[**ASLR**](../common-binary-protections-and-bypasses/aslr/) **但没有**[**PIE**](../common-binary-protections-and-bypasses/pie/)**,知道libc并且二进制文件使用`system`**函数时,可以**`ret`到GOT中system的地址**,参数为`'/bin/sh'`的地址(您需要弄清楚这一点)。 * 具有[ASLR](../common-binary-protections-and-bypasses/aslr/)但没有[PIE](../common-binary-protections-and-bypasses/pie/),知道libc但**二进制文件不使用`system`**: * 使用[**`ret2dlresolve`**](../rop-return-oriented-programing/ret2dlresolve.md)解析`system`的地址并调用它。 * **绕过**[**ASLR**](../common-binary-protections-and-bypasses/aslr/)并计算内存中`system`和`'/bin/sh'`的地址。 * 具有[**ASLR**](../common-binary-protections-and-bypasses/aslr/) **和** [**PIE**](../common-binary-protections-and-bypasses/pie/) **但不知道libc版本**:您需要: * 绕过[**PIE**](../common-binary-protections-and-bypasses/pie/) * 找到使用的**`libc`版本**(泄漏几个函数地址) * 检查**具有ASLR的先前情况**以继续。 #### 通过EBP/RBP * [**Stack Pivoting / EBP2Ret / EBP Chaining**](../stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md): 控制ESP以通过堆栈中存储的EBP控制RET。 * 用于**off-by-one**堆栈溢出 * 作为控制EIP的替代方式,滥用EIP在内存中构造有效负载,然后通过EBP跳转到它 #### 其他 * [**Pointers Redirecting**](../stack-overflow/pointer-redirecting.md): 如果堆栈包含将要调用的函数或将要被有趣函数(如system或printf)使用的字符串的指针,可以覆盖该地址。 * [**ASLR**](../common-binary-protections-and-bypasses/aslr/)或[**PIE**](../common-binary-protections-and-bypasses/pie/)可能会影响地址。 * [**Uninitialized variables**](../stack-overflow/uninitialized-variables.md): 永远不知道。