hacktricks/linux-hardening/bypass-linux-shell-restrictions/ddexec.md
2023-08-03 19:12:22 +00:00

6.5 KiB
Raw Blame History

DDexec

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

上下文

在Linux中为了运行一个程序它必须存在为一个文件并且必须通过文件系统层次结构的某种方式进行访问这就是execve()的工作原理。这个文件可以存在于磁盘上或者内存中tmpfsmemfd但你需要一个文件路径。这使得在Linux系统上控制要运行的内容变得非常容易它可以轻松检测到威胁和攻击者的工具或者防止他们尝试执行任何自己的内容例如不允许非特权用户在任何地方放置可执行文件

但是这种技术可以改变这一切。如果你无法启动你想要的进程... 那么你就劫持一个已经存在的进程

这种技术允许你绕过常见的保护技术如只读、noexec、文件名白名单、哈希白名单...

依赖

最终的脚本依赖于以下工具才能工作,它们需要在你攻击的系统中可访问(默认情况下,你可以在任何地方找到它们):

dd
bash | zsh | ash (busybox)
head
tail
cut
grep
od
readlink
wc
tr
base64

技术

如果您能任意修改进程的内存,那么您就可以接管它。这可以用于劫持已存在的进程并用另一个程序替换它。我们可以通过使用ptrace()系统调用需要您具备执行系统调用的能力或在系统上有gdb可用或者更有趣的是写入/proc/$pid/mem来实现。

文件/proc/$pid/mem是进程的整个地址空间的一对一映射例如在x86-64中从0x00000000000000000x7ffffffffffff000)。这意味着在偏移量x处从该文件读取或写入与在虚拟地址x处读取或修改内容是相同的。

现在,我们需要解决四个基本问题:

  • 通常只有root用户和文件的程序所有者才能修改它。
  • ASLR。
  • 如果我们尝试读取或写入未映射到程序地址空间的地址将会收到I/O错误。

这些问题有解决方案,虽然它们不是完美的,但是很好:

  • 大多数shell解释器允许创建文件描述符然后将其继承给子进程。我们可以创建一个指向shell的mem文件的具有写权限的文件描述符...因此使用该文件描述符的子进程将能够修改shell的内存。
  • ASLR甚至不是一个问题我们可以检查shell的maps文件或procfs中的任何其他文件以获取有关进程的地址空间的信息。
  • 因此,我们需要在文件上执行lseek()。从shell中除非使用臭名昭著的dd,否则无法执行此操作。

更详细地说

这些步骤相对简单,不需要任何专业知识来理解它们:

  • 解析我们想要运行的二进制文件和加载器,找出它们需要的映射。然后编写一个"shell"代码,它将执行与内核在每次调用execve()时执行的相同步骤(广义上):
  • 创建这些映射。
  • 将二进制文件读入其中。
  • 设置权限。
  • 最后,使用程序的参数初始化堆栈,并放置辅助向量(加载器所需)。
  • 跳转到加载器并让它完成剩下的工作(加载程序所需的库)。
  • syscall文件中获取进程在执行系统调用后将返回的地址。
  • 用我们的shellcode通过mem,我们可以修改不可写的页面)覆盖该位置,该位置将是可执行的。
  • 将我们想要运行的程序传递给进程的stdin将由上述"shell"代码read())。
  • 此时,由加载器负责加载我们程序所需的库并跳转到它。

请查看https://github.com/arget13/DDexec中的工具

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥