java 开发工具eli

0x00 —前言
在本系列文章中我将详细介绍不同类型的二进制漏洞利用程序解释它们是什么它们如何工作其背后的技术以及针对它们的一些防御措施。 在本系列中我将尽一切可能以从初学者到1337 h4x0r都可以理解的方式来解释这些攻击防御技术和概念。
请注意虽然我将添加一些关键的先决条件知识部分以期使这些攻击的更多技术解释更容易理解但是本系列文章不会涉及精通该领域的所有信息/概念/技术。二元开发。
在本文中我们将介绍
0x01。 必备知识应用程序内存 0x02。 必备知识堆栈 0x03。 先决条件知识函数调用和返回 0x04。 攻击堆栈缓冲区溢出 0x05。 攻击返回libcret2libc攻击
单击下面的该系列的下一部分
二进制开发ELI5-第2部分
0x01—先决条件知识应用程序内存
执行时会将应用程序加载到内存中但是众所周知计算机具有有限的内存量因此在将内容加载到计算机中时必须格外小心以免覆盖任何其他应用程序。 要做到这一点计算机使用称为虚拟内存的概念它可以完美地总结了使用从21世纪初的电视节目现场德雷克和乔希 其中德雷克和乔希采取工作的组织寿司到容器中
在现场Drake和Josh获得了一份工作他们将通过传送带送来的寿司拿走然后将寿司片整理成容器。 此外尽管所有的寿司容器看起来完全相同但至关重要的是每个容器只能容纳一种寿司。因此让我们将类推分解为虚拟内存的概念
寿司传送带如上所述计算机在将应用程序数据存储在内存中的位置时必须非常小心和精确这样才能覆盖任何内容。 尽管计算机可以简单地将应用程序小心地放在物理内存中但这最终会导致问题因为应用程序碎片会很快填满整个空间。 在上面的示例中单个寿司块可以看作是应用程序的碎片或应用程序分配的内存块而整个寿司集每个容器6个可以看作应用程序本身。
德雷克和乔什为了避免用单个寿司片填满传送带的问题德雷克和乔什将它们组织成单独的容器然后允许它们沿传送带向下移动。 与Drake和Josh一样您的计算机也将应用程序组织并设置到容器中这些容器称为虚拟内存位置。 这些虚拟内存位置或虚拟地址空间 使应用程序相信它具有对整个内存范围的完全控制权。 但是当应用程序调用某个位置或尝试在其虚拟地址空间中分配内存而不是被授予访问任意物理内存的权限时您计算机CPU中央处理单元中一个很小但非常重要的硬件即MMU 内存管理单元将应用程序的调用映射到物理内存的特定区域并促进任何内存操作。 通过这种内存映射计算机可以通过集中组织的查找表来组织和处理具有动态内存需求的多个应用程序。

同样重要的是要注意尽管应用程序的所有代码都包含在其虚拟地址空间中但应用程序通常使用动态链接库DLL例如libc或kernel32。 这些DLL只是外部程序 不存储在应用程序的地址空间中系统应用程序或程序从中导入代码的其他自定义应用程序。 以下面的代码为例

如您所见在这6行程序中我实际上没有定义printf是什么。 但是该程序仍然可以正常运行并打印出“ Hello World”。 这是因为printf函数是libc标准C库中定义的系统函数。 在编译过程中 libc从外部链接到可执行文件。 在Linux系统上可以使用ldd命令查看程序的共享库依赖关系。

如果您正在查看上面的屏幕截图并想知道0xb7e99000到底是什么 那是内存中libc库的地址。 内存地址以十六进制格式表示。 请单击此处以获取有关十六进制数字系统的更多信息 。
0x02—必备知识堆栈
堆栈只是一个大型数据结构用于在运行时存储应用程序信息和数据。 可以通过以下类推简单地说明堆栈的功能
鲍勃Bob是一家高档餐厅的洗碗工鲍勃Bob每晚都有一堆盘子要洗。 此外整夜中每当清理桌子时都可以将更多的盘子添加到Bob的堆栈中。 如果鲍勃从栈顶以外的任何地方拿起盘子那么上面的所有盘子都会掉落并折断。现在代替鲍勃和一堆盘子只需想象一台计算机和一堆数据对象。 每当东西被压入堆栈中它被添加到堆栈的顶部并且无论何时东西被弹出栈它从堆栈的顶部除去使其A L AST I N 开始步骤øUTLIFO 机制。
程序使用堆栈来保存各种东西例如函数指针函数在内存中的位置和变量。
0x03 —必备知识函数调用和返回
看下面的代码

在此代码段中我们看到函数add接受2个称为A和B的整数类型参数。 在主函数中我们可以看到我们调用Add时 参数A的数字为1参数B的数字为2。 如果将这些代码分解为基础机器代码则会看到

如您所见在调用带有参数的函数时程序首先将两个参数都压入堆栈然后执行调用语句。 此调用语句重定向的是程序的指令指针指令指针就像用来记录正在读取的单词的小铅笔。指令指针始终指向将要执行的指令即将被执行的单词。读取到被调用函数的地址。 但是在导航到被调用函数之前 call语句将其下一条指令的地址压入堆栈以便当add函数返回时它将知道从何处继续进行处理。 函数应返回到的位置的地址称为函数返回指针 。
0x04 —攻击堆栈缓冲区溢出
在讨论什么是堆栈缓冲区溢出及其工作原理的技术细节之前让我们看一下一种快速易于理解的类比
爱丽丝和鲍勃曾经约会但爱丽丝最终与鲍勃分手。 随着时间的流逝爱丽丝继续前进但鲍勃从未真正度过伤心欲绝。 现在爱丽丝Alice与鲍勃Bob的大仇敌罗伯特·哈克曼Robert Hackerman结婚。 鲍勃是个令人毛骨悚然的怪人他通过秘密访问爱丽丝的电子邮件帐户来监视爱丽丝的所有婚礼计划。 鲍勃Bob看到爱丽丝Alice聘请了一位著名的婚礼蛋糕设计师他希望爱丽丝Alice根据自己的口味喜好编辑食谱的一部分。 设计师给了爱丽丝一份推荐的配料清单但说他会做任何她想做的事情。 鲍勃打开了设计者电子邮件中附带的文档发现配方的自定义行如下所示…然后我们将通过添加______为糖霜添加风味。 之后我们将添加一些巧克力…。
Bob注意到如果您在该行中输入“ Banana”则文本如下所示…然后我们将通过添加香蕉为糖霜增添风味。 之后我们将添加一些巧克力...
但是如果Bob在行中输入“ Strawberry”则文本如下所示…然后我们将通过添加草莓酱来增加糖霜的味道然后添加一些巧克力…
鲍勃意识到这将是破坏爱丽丝婚礼的完美方法他要做的就是用自己的令人反感的版本覆盖食谱的其余部分 在爱丽丝的婚礼那天设计师终于露出了自己做的蛋糕-蛋糕上覆盖着小虫是用冷冻的蛋黄酱做成的类似于Bob的攻击堆栈缓冲区溢出会覆盖开发人员不打算覆盖的数据从而可以完全控制程序及其输出。
所以现在让我们在现实世界中看到它。 看一下exploit-exercises.com的以下代码

在上面的函数中我们看到创建了一个称为buffer的字符类型数组其大小为64。然后我们看到了修改后的变量设置为0并且以buffer变量作为参数调用了gets函数。 最后我们看到一个IF语句用于检查是否修改的值不为0。显然在此应用程序中没有将修改后的变量设置为除0之外的任何值的方式那么我们将如何对其进行更改
好吧让我们首先看一下gets函数文档


如您所见 gets函数仅接受用户输入。 但是该函数不会检查用户输入是否真正适合我们要存储在其中的数据结构在这种情况下为buffer 因此我们能够溢出数据结构并影响其他变量/数据。堆栈。 此外由于我们知道所有变量都存储在堆栈中并且知道修改后的变量是0因此我们要做的就是输入足够的输入以覆盖修改后的变量。 让我们看一下图

如您所见如果恶意用户只是输入太多文本他们就可以覆盖修改后的变量以及堆栈中的所有其他内容包括返回指针。 这意味着如果恶意代理能够控制程序堆栈则它们可以有效地控制整个程序并使之执行所需的操作。 他们可以简单地将函数在堆栈上的返回指针覆盖为指向某个恶意负载的自定义指针。
0x05 —攻击ret2libc
在讨论Return-to-libcret2libc攻击之前让我们花一点时间讨论一下libc 。
众所周知从0x01节开始 libc是标准的C库。 这意味着它包含C编程语言中包含的所有通用系统功能。 现在如果恶意用户能够控制程序以执行其中一些功能该怎么办
好吧这与ret2libc差不多。 Matrix系列是ret2libc后果的一个完美比喻。 回想一下经典的“枪支很多枪支”场景。 操作员Tank能够完全绕过矩阵并对矩阵进行重新编程以使一吨枪无处不在。
您可以这样想回到libc我们可以控制矩阵标准C库并使它做我们想要的任何事情。
从根本上说ret2libc攻击实际上是基于堆栈缓冲区溢出的。 回想一下我在0x04部分末尾所说的内容如果恶意代理可以覆盖堆栈上的数据则他们可以简单地覆盖返回指针以指向libc中的特定函数并传递传递有效负载所需的任何参数。
用于ret2libc攻击的最常见功能之一是系统功能。 让我们看一下它的文档

如您所见系统命令仅执行shell命令 shell是linux命令行。 此外如果我们仔细阅读说明就会发现系统仅执行/ bin / sh -c / bin / sh是实际的shell命令并且该命令通过参数传递给函数。
因此要获得对易受攻击的应用程序正在运行的计算机的 命令行访问 我们要做的就是将“ / bin / sh”作为参数推入堆栈然后将return或call指针替换为该内存的地址。系统功能以便使用/ bin / sh作为参数来调用该功能启动外壳程序并授予我们对系统的完全访问权限。
漏洞利用很多漏洞利用。
0x06 —第1部分结论
在本文中我们介绍了
0x01。 虚拟内存以及如何在内存中处理应用程序 0x02。 动态链接库和libc 0x03。 堆栈 0x04。 如何调用函数以及如何从函数返回 0x05。 堆栈缓冲区溢出 0x06。 返回libcret2libc攻击
希望本文对您有所帮助。 单击下面的内容继续进行本系列的第2部分
二进制开发ELI5-第2部分
另外如果您对逆向工程感兴趣请查阅我的BOLO逆向工程文章系列
BOLO逆向工程—第1部分基本编程概念 BOLO逆向工程—第2部分高级编程概念
而且如果您正在寻找更多ELI5内容请查看我的《 解释幽灵》和《像我一样融化5》一文。
推“谢谢” 推动“为” 通话阅读
翻译自: https://hackernoon.com/binary-exploitation-eli5-part-1-9bc23855a3d8
java 开发工具eli