这篇博客是年度的12 Days of HaXmas系列博客中的第11篇。

Executable and Linkable Format ( ELF ) 是许多类Unix操作系统(如Linux,大多数现代BSD和Solaris)的基础。ELF文件有许多技巧,比如我们在our *nix Meterpreter implementation中使用的那些,但那些技巧需要使用我们的特殊 toolchain 或带有-static-pie标志的GCC 8+来构建每个可执行文件。如果环境不同怎么办呢?内核加载和运行代码时并不需要磁盘上的文件,下面我们看下如何在没有execve的情况下运行Linux可执行文件。

手工制作镜像

也许最有效的可执行格式技巧是反射加载(reflective loading)。 反射加载是后渗透阶段的一种重要技术,用于逃避检测和在受限制的环境中执行复杂命令。 它通常有三个广泛的步骤:

使代码执行(如:利用漏洞或网络钓鱼)

从某个地方抓取自己的代码

使操作系统运行你自己的代码(但是不像普通进程那样加载)

最后一步是反射加载的关键。 环境限制越来越多,普通的进程启动方式目标非常明显。 传统的防病毒会扫描磁盘上的文件,新进程启动时会进行代码签名完整性检查,行为监控会不断检查以确保进程没有恶意行为。 背后的思想是,如果攻击者无法运行任何程序,他们就无法做任何事情,系统也是安全的。这不完全正确,阻挡常见的攻击路径只是让事情变得更加困难。

特别是,对于使用可移植可执行(PE)格式的Windows环境,我们已经看到过很多关于这个主题的研究,因为Windows使用广泛,而且操作系统中内置了非常有用的反射构造模块。 事实上,它具有这类工作的黄金标准API:CreateRemoteThread及其他相关API,这不仅仅允许攻击者加载代码,而且可以将代码注入其他正在运行的进程。

Linux上的这些方法可以分为五类:

· 写入临时文件: 这与典型代码没有太大区别,但它不会留下磁盘成品文件。

· 注入ptrace:这需要一些精巧的控制,比如经典的process-hopping。

· 自修改可执行文件:dd是经典之作,它需要一些比较小的定制shellcode。

· 脚本语言中集成的FFI:Python和Ruby都可以,当前技术只能加载shellcode。

· 创建非文件系统的临时文件:这使用2014年添加的系统调用,因此它即将广泛使用。

严格的工作条件

很少有人密切关注他们的Linux机箱(如果你这样做了,那么恭喜!),但这些技术风格除了上面提到的各自的技术挑战外,还有安全/操作方面的考虑。 如果您处于安全对抗中的防守方,可以考虑用以下方式阻止远程攻击者:

临时文件

越来越常见的是查找/tmp和/dev/shm挂载了noexec(即,该树中没有文件可以执行),特别是在移动和嵌入式系统上。 说到嵌入式系统,那些嵌入式系统通常也只有只读的持久文件存储,所以你甚至无法回退来阻止别人查看磁盘。

自修改可执行文件和ptrace

访问ptrace和/proc/中的大多数有趣的自检由kernel.yama.ptrace_scope sysctl变量控制。在未用于开发的盒子上,应将其设置至少为2以删除非特权用户的访问权限。 这在许多移动和嵌入式系统上是默认的,而现代桌面/服务器发行版默认至少为1,这降低了它在跨进程中疯狂跳跃的实用性。 此外,它是特定用于Linux,所以没有可爱的BSD shells。

FFI(Foreign Function Interface)集成

Ruby的fiddle和Python的ctypes特别灵活,并且很多小东西都可以灵活的像解释型的C语言一样运行。但是,它们没有汇编程序,所以任何使用寄存器或引导到不同可执行文件的细节都需要使用shellcode来完成。 您也永远不知道目标系统会安装哪个版本的环境。

非文件系统的临时文件

同样是Linux特有的技巧。我能调用一对新的syscalls,它们组合起来可以绕过任何noexec标志(内核4.19.10测试通过)。 第一个系统调用是memfd_create(2),在内核3.17版本中添加,它分配一个具有默认权限的新临时文件系统,并在其中创建一个文件,除/proc目录,该文件不会显示在其他任何已挂载的文件系统中。第二个系统调用是execveat(2),在内核版本3.19中添加。它可以采用文件描述符并将其传递给内核以供执行。缺点是创建的文件可以很容易地通过find /proc/*/fd -lname '/memfd:*'找到,因为所有的memfd_create(2)文件都表示为具有常量前缀的符号链接。这个功能在普通软件中很少使用,我仅找到过一个这种用法的普通程序,那是在2016年被添加到PulseAudio中的。

回到过去,一个(Runtime)链接

不过这里有一个很大的瓶颈:要运行其他程序,所有这些技术都使用标准的execve(2)(最后一种情况调用的也是相关的execveat(2))。定制的SELinux配置文件或syscall审计的存在可以很容易进行阻拦,并且在最近的强制启用SELinux的Android版本中,确实是这样。

还有另一种叫做用户空间exec或ul_exec的技术; 然而它模仿了内核在执行execve期间是如何初始化进程的,并将控制权移交给运行时链接器:ld.so(8)。 这是该领域最早的技术之一,由grugq开创,它因为与以上技术相比较为繁琐而从未被推行过。 针对x86_64有一个优化和重写的版本,但是它实现了自己的标准库,因此很难扩展并且无法在现代的堆溢出保护环境下编译。

Linux的世界与15年前这种技术首次发布时的情况截然不同了。 现在,默认有40多位地址空间和位置独立的可执行文件,将execve进程拼凑在一起更为直接。 当然,我们对堆栈地址进行硬编码并不能保证90%以上的可用率,但程序也不再依赖于它的常量,所以我们几乎可以把它放在任何地方并且少用内存地址。 Linux环境现在也比2004年更加普遍、有价值并且受到更受保护,因此在某些情况下,这种努力还是值得的。

过程

根据执行方法和环境,模拟execve的工作可能有两个要求。 首先,我们需要页面对齐的内存分配以及在填充后使内存可执行的能力。 因为它需要JIT、内置的library加载器dlopen(3)以及一些DRM实现,所以很难从系统中完全删除。 然而,SELinux可以限制可执行内存的分配,而一些像Android这样的自包含平台使用这些限制可以很好地控制未经批准的浏览器或DRM库。 接下来,我们要求能够任意跳入所述内存。 例如在C或shellcode中,它确实需要脚本语言中的一个完整的外部函数调用接口(FFI),排除非XS的Perl实现。

grugq详述的过程以一种微妙而有趣的方式发生了改变。 即使开发已经全部完成,但整体的步骤还是一样的。 现代GNU / Linux用户空间的一个安全特性是它不太关心特定的内存地址,这使我们可以更灵活地实现我们的其他类型的安全特性。内核在辅助向量中传递给Runtime还有更多的提示,可以查找到原始数据,但大多数程序在大多数操作系统架构中都可以使用简单的方法。

工具

许多工具的没落都是因为过时了,特别是在开源和安全领域。 execve模拟器没有其他方法了出现了,大家对两个ul_exec的实现也几乎没有兴趣,(据我所知)也很少有这方面的更新。

Linux Meterpreter的实现目前不支持execute命令中常见的-m选项,这个选项在Windows上以合法的程序作为幌子,并完全在内存中执行恶意命令。使用这个和一个回退技术或者以上两个技术将为我们提供在内存运行上传的文件的功能,以及一些小窍门。例如:映射额外的合法文件,或在在将控制权交给上传的可执行文件之前更改进程名称,可以完全复制-m。一个很好的副作用是,这也将使构建和分发插件更容易,因为它们将不再需要在构建时制作成内存映像。

为了实现这一点,我正在创建一个与我们的Linux Meterpreter共存的共享链接库mettle。它不依赖于任何Meterpreter代码,但默认情况下,它将使用其toolchain进行构建。它是免费的,可以打包成你想要的任何后渗透手法。如果您有任何问题或建议,请查看pull request。

这里有一个示例,可以通过strace进行跟踪分析。使用该库。 为了减少普通跟踪调试相关输出的干扰,我们只使用%process跟踪表达式来仅查看与进程生命周期相关的调用,如fork,execve和exit。 在x86_64上,%process表达式还获取了arch_prctl系统调用,该调用仅用于x86_64,仅用于设置线程本地存储。 execve来自strace启动可执行文件,第一对arch_prctl调用来自库初始化。直到目标库启动自己的一对arch_prctl调用并打印出我们的消息。

$ strace -e trace=%process ./noexec $(which cat) haxmas.txt

execve("./noexec", ["./noexec", "/usr/bin/cat", "haxmas.txt"], 0x7ffdcbdf0bc0 /* 23 vars */) = 0

arch_prctl(0x3001 /* ARCH_??? */, 0x7fffa750dd20) = -1 EINVAL (Invalid argument)

arch_prctl(ARCH_SET_FS, 0x7f17ca7db540) = 0

arch_prctl(0x3001 /* ARCH_??? */, 0x7fffa750dd20) = -1 EINVAL (Invalid argument)

arch_prctl(ARCH_SET_FS, 0x7f17ca7f3540) = 0

Merry, HaXmas!

exit_group(0) = ?

+++ exited with 0 +++

结束

有了Mettle的这个新库,我们希望提供一种长期,隐秘的方法,可以在攻陷的Linux机器上可靠地加载程序。 如果您有任何问题或建议,请查看我的pull request的过程,我们* nix的payload,或在Slack添上加我们。

linux 下怎么将可执行文件做成镜像 开机就能运行这个可执行文件,圣诞老人的ELFs:在没有execve的情况下运行Linux可执行文件...相关推荐

  1. 混合模式程序集是针对“v1.1.4322”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。

    看到一个kinect大牛编写的一个水果忍者的体感游戏版本,让我为自己一直以来只用现有的网页游戏来模拟kinect体感游戏控制感到惭愧,没办法,我还是菜鸟.学习一段后自己模仿星际大战这个游戏,自己写了一 ...

  2. VS2010 混合模式程序集是针对v1.1.4322版的运行时生成的 在没有配置其他信息的情况下 无法再4.0运行中

    VS报错,百度之解决方案:原文出处 http://www.cnblogs.com/zcftech/archive/2013/03/22/2976385.html 看到一个kinect大牛编写的一个水果 ...

  3. Java不用main方法运行_如何在不定义main方法的情况下运行Java程序?

    我正在查看一些Java源代码,并注意到main方法没有定义. Java如何编译源代码而不知道从哪里开始? main方法仅在Java虚拟机执行代码时使用.没有main方法就无法执行代码,但仍然可以编译代 ...

  4. 线程池中运行的线程,当等待队列未满的情况下,一定不大于核心线程数吗

    通过<线程池内运行的线程抛异常,线程池会怎么办>了解到当线程执行的任务出现异常时,会将当前线程移出线程池,并新增一个线程到线程池中,我们先来回顾一下线程池的运行原理: 从原理图中可以看到只 ...

  5. 把一个运行的Docker容器做成镜像

    文章目录 有时候仓库提供的镜像可能不符合我们的需求,我们需要定制属于自己的镜像 一种方式是使用Dockerfile,另一种方式可以先把容器运行起来,然后进入容器,把容器改造成我们需要的样子,然后再把这 ...

  6. 原来BIOS放电是要在断电的情况下进行的

    新春佳节,走亲访友或接待亲朋好友.一天,几个朋友前来探访,在朋友到达之前就在网上下载了高清电影到客厅的HTPC电脑上,试播了一下,一切正常,没关电脑,但它不知何时自动关了.晚饭后,朋友说试试高清电影的 ...

  7. 最好最坏和平均情况下的性能分析

    最好最坏和平均情况下的性能分析 现在有一个问题,对于所有的输入来说,前面得到的结果是否都成立呢?第二种排序法在少量字符串的时候性能也许是最好的.但是,输入数据有很多地方可能变化: 输入数据可能有1 0 ...

  8. 在京东、天猫、淘宝都存在情况下,为什么聚美还能崛起?

    咖友提问:在京东,天猫,淘宝都存在情况下,为什么聚美还能起来啊?能崛起根本原因是啥? ▍刘百万 烘焙家 CEO 电商的精髓在于长尾,供应链.如果你是做o2o那就是玩刚需.高频次,最后1km.话说回来, ...

  9. 使用nginx代理的情况下获取用户真实IP

    ##1.背景知识 1.1. 前提知识点: 还有nginx中的几个变量: remote_addr 代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站 ...

最新文章

  1. concealing 706 DC, 706 AC, 706 MV errors in P frame
  2. Android Studio的git功能的使用
  3. Java多线程编程那些事:volatile解惑--转
  4. 用c语言读取固定大小的raw格式图像并统计灰度值
  5. HDU2515 Yanghee 的算术
  6. 原生APP与移动Web App的比较
  7. 深入理解JavaScript系列(18):面向对象编程之ECMAScript实现
  8. 网站用户修改密码源码(邮箱版)
  9. redis 是哪个厂家的_redis 基本数据类型-字符串(String)
  10. Bill Gates 2007年哈佛演讲(中/英文)
  11. python实现用户登录界面代码_python编辑用户登入界面的实现代码
  12. ESP8266/ESP8285 启动报错 csum err ets_main.c 解决办法
  13. aliez歌词_aLIEz FULL歌词【假名 罗马音】
  14. 【金蝶】金蝶KIS专业版9.1清理用户名密码
  15. Web 2.0 创业神器为何天生敏捷?
  16. 顶点计划2-2调研报告
  17. 解决本地新建项目推送到码云失败的问题
  18. 给CheckBox换样式
  19. css 权重及!important
  20. shell的循环运用

热门文章

  1. cmd下载远程linux的文件,Java利用ssh协议实现从远程Linux服务器下载文件和文件夹...
  2. 实用技巧| 电脑系统提升20%上网速度,记得学会拿去装X哈
  3. 安卓android BMI体质指数测试项目
  4. 开源工具:OpenPR
  5. 软工1816 · Alpha冲刺(4/10)
  6. 你必须牢记的*.Config-配置文件
  7. java时间,日期,毫秒值,String的相互转换总结
  8. 计算机网络自顶向下--运输层
  9. 移动互联应用阶段学习
  10. app测试、web测试-怎么测?