精品成品源码网站,网站全屏视频怎么做,平面设计用到的软件有哪些,客户网站留言7 类主流的 Linux 恶意软件反分析/检测躲避技术 反调试#xff08;Anti-Debug#xff09;: 软件调试是恶意软件分析的常⽤⼿段之⼀#xff0c;但恶意软件可以通过识别调试器特征#xff0c;实现⾃⾝恶意⾏为的隐藏#xff0c;或导致调试失败#xff0c;从⽽规避分析与检测…7 类主流的 Linux 恶意软件反分析/检测躲避技术 反调试Anti-Debug: 软件调试是恶意软件分析的常⽤⼿段之⼀但恶意软件可以通过识别调试器特征实现⾃⾝恶意⾏为的隐藏或导致调试失败从⽽规避分析与检测反内存转储Anti-Memory-Dump内存转储是恶意软件取证分析的重要⼿段但恶意软件可通过更改代码数据结构实现⾃⾝恶意⾏为的隐藏或导致内存转储失败从⽽规避分析检测反模拟执⾏Anti-Emulation⼆进制程序模拟执⾏是恶意软件深度分析的常⽤技术之⼀但恶意软件可以针对常⽤模拟器(如 QEMU)的某些指纹特征实现⾃⾝恶意⾏为的隐藏或导致模拟执⾏失败从⽽规避分析检测反代码插桩Anti-Instrumentation⼆进制程序代码插桩DBI技术通常采⽤ JIT 编译器实现运⾏时代码插桩是重要的恶意软件分析与检测⼿段但恶意软件也可以通过比较插桩前后差异如特定寄存器探测到执⾏环境异常实现⾃⾝恶意⾏为隐藏或导致插桩执⾏失败从⽽规避分析检测代码注入Code Injection恶意软件可将⾃⾝注入合法进程实现攻击⾏为隐藏从⽽规避分析检测实现⽆文件攻击和攻击持久化等⽬标迟滞代码Stalling Code恶意软件通过迟滞恶意⾏为导致动态分析检测沙箱超时从⽽规避检测运⾏环境测量Runtime Measurement通过测量特定⾏为如指令、API 调⽤等执⾏时间探测当前执⾏环境中是否存在检测探针例如采⽤ API hookVM/Emulator 的检测⽅法
反代码插桩Anti-Instrumentation
**代码插桩Code Instrumentation**是一种在程序代码中插入额外指令或代码片段的技术。这通常是为了收集执行时的信息、监控程序行为、调试代码或进行性能分析。 ⼆进制程序代码插桩DBI技术通常采⽤ JIT 编译器实现运⾏ 时代码插桩是重要的恶意软件分析与检测⼿段但恶意软件也可以通过比较插桩前后差异如特定寄 存器探测到执⾏环境异常实现⾃⾝恶意⾏为隐藏或导致插桩执⾏失败从⽽规避分析检测
代码加密和压缩
使用加密和压缩技术对恶意代码进行加密和压缩使代码难以解析和识别从而阻止了动态检测
插桩检测(Instrumentation detection)
恶意软件检查程序的代码部分是否已被修改。如果修改则更改程序的执行并异常退出
抵制调试(Resist debugging)
“Resist debugging”抵抗调试是一种在软件中采取措施以防止被调试的技术。当程序被调试时调试器debugger可以访问程序的内部状态、内存内容和执行路径这为逆向工程和分析提供了便利。因此一些软件开发者或软件保护方案可能会采取措施以抵抗调试增加对逆向工程的难度。 这些技术的目标是增加逆向工程的难度以保护软件免受未经授权的分析和修改。然而反调试技术并不是绝对的有经验的逆向工程师通常能够找到方法来绕过这些保护机制
真实的恶意软件示例Mirai:
简介: Mirai 是一种恶意软件最初在2016年首次被发现。它专门针对物联网IoT设备例如网络摄像头、路由器和智能家居设备。Mirai 的主要目标是通过感染这些设备来创建一个庞大的僵尸网络该网络可以被用于发起分布式拒绝服务攻击DDoS 攻击。 它发布后被攻击者开源可以在Github上直接访问源代码示例 这是几个C语言中用于信号处理的函数,用来定义程序接收到特定信号时的行为sigemptyset(sigs);
sigaddset($set, SIGINT);
sigprocmask(SIG_BLOCK, sigs, NULL);
signal(SIGCHLD, SIG_IGN);
signal(SIGTRAP, anti_gdb_entry);sigemptyset(sigs); 作用 该函数用于初始化一个信号集将指定的信号集 sigs 清空即将其中的所有信号都设置为未阻塞。 参数 sigs 是指向信号集的指针。sigaddset($set, SIGINT); 作用 该函数用于向信号集中添加一个特定的信号此处是将 SIGINT中断信号添加到 $set 信号集中。 参数 $set 是一个信号集。sigprocmask(SIG_BLOCK, sigs, NULL); 作用 此函数用于修改当前进程的信号屏蔽集。在这里它将 sigs 中的信号添加到当前进程的信号屏蔽集中即将这些信号设置为被阻塞使得它们在阻塞状态下不会被处理。 参数 SIG_BLOCK 表示将信号集添加到当前信号屏蔽集sigs 是要添加的信号集最后一个参数为 NULL 表示不保存原来的信号屏蔽集。 4. signal(SIGCHLD, SIG_IGN); 作用 该函数用于指定对信号 SIGCHLD子进程状态改变信号的处理方式。在这里通过设置为 SIG_IGN表示忽略 SIGCHLD 信号即子进程终止时不会创建僵尸进程。 参数 SIGCHLD 是要设置处理方式的信号SIG_IGN 表示忽略。signal(SIGTRAP, anti_gdb_entry); 作用 该函数用于指定对信号 SIGTRAP调试中断信号的处理方式这里将其设置为调用 anti_gdb_entry 函数。 参数 SIGTRAP 是要设置处理方式的信号anti_gdb_entry 是处理该信号时调用的函数。
使用sigemptyset和sigaddset分别清除和添加信号集并将SIGINT信号添加到信号集。使用sigprocmask函数来阻止信号集以防止程序运行时其他进程或信号处理程序将其发送到此进程。使用signal函数设置信号处理程序设置要忽略的SIGCHLD信号并设置要由反gdb-entry函数处理的SIGTRAP信号。CPU将在硬件断点处触发中断信号SIGTRAP并暂停程序的执行。
Mirai使用了一系列技术,通过信号攻击来防止被调试器检测和分析
修改中断信号处理功能 Mirai 修改了中断信号如SIGTRAP的处理方式将其指向一个自定义的函数 anti_gdb_entry()。这样当调试器如 GDB尝试对被感染的程序进行调试时会调用这个自定义的函数。检查调试符号表和调试信息表 在 anti_gdb_entry() 方法中Mirai 进行检查以确认是否存在调试符号表和调试信息表。这是为了识别是否有调试工具正在尝试分析程序。使用特殊指令检查调试器状态 Mirai 使用特殊指令检查调试器的运行状态。这可能涉及检查调试器标志或执行特殊的指令以确定是否在调试模式下运行。修改CPU寄存器中的指令指针 如果检测到调试器正在运行Mirai 将修改 CPU 寄存器中的指令指针使其指向下一条指令的地址。这样当程序在调试器中停止时Mirai 能够通过跳过断点等措施继续执行防止被调试器检测到。输出大量无用信息 当 GDB 连接到被感染的程序并停止其运行时Mirai 会通过输出大量的空格字符和 ANSI 转义序列到控制台使 GDB 输出窗口充满大量无用的信息。这增加了分析者在调试过程中的困难使输出窗口难以阅读。
DBI工具检测
Dynamic Binary Instrumentation (DBI) 工具用于在运行时分析和修改二进制程序的行为。这类工具常用于调试、性能分析、安全研究等领域。然而一些恶意软件或反分析技术可能会尝试检测 DBI 工具的存在以防止被分析。
反调试
许多恶意代码使用反调试技术来识别它们是否正在被调试或禁用调试器。恶意代码编写者意识到分析人员经常使用调试器来观察恶意代码的操作因此他们使用反调试技术来尽可能延长恶意代码的分析时间。为了防止调试器进行分析当恶意代码意识到它正在被调试时它可能会更改正常执行路径或修改自己的程序以崩溃从而增加调试时间和复杂性。
插入int3
int3是一种用于在x86架构上触发调试中断的汇编指令。它实际上是一条中断指令它引发的是中断号为3的中断。在Intel x86体系结构中中断号3通常用于调试目的。 int3 指令的作用是在程序执行过程中插入一个软中断这可以被调试器如GDB捕获。一旦中断被触发操作系统或调试器会停止程序的执行并将控制权传递给调试器以便进行相应的调试操作。 当调试器想要在某一点停止即设置断点或断点时它将使用“int3”0xcc。在旧版本的gdb中我们可以通过识别这个字符来判断它是否处于调试状态但在新版本中它无法工作。但是我们可以尝试在代码中插入“int3”字符来破坏程序。 在一些恶意软件分析和逆向工程的情境中int3 指令有时被用来干扰调试工具的运行例如通过检测调试器的存在或动态修改代码来绕过调试。 在这个例子中我们捕获SigTrap信号这样程序在正常操作过程中就不会崩溃并启动一个“int3”它以类似于断点的方式在调试器中触发SigTrap 如
// Insert ’int3 ’
#include stdio.h
#include stdlib.h
#include signal.h// 信号处理器对 SIGTRAP 信号的处理函数
void handler(int signo) {}// 在函数中插入 int3 指令的函数
void PassByInt3() {// 设置对 SIGTRAP 信号的处理函数为 handlersignal(SIGTRAP, handler);// 在汇编中插入 nop 和 int3 指令asm(nop\n\t int3\n\t);// 这条语句将在 int3 执行成功后被打印printf(Code executes successfully\n);
}int main(int argc, char *argv[]) {// 调用函数插入 int3 指令PassByInt3();return 0;
}
使用ptrace()
ptrace系统调用用于进程跟踪。它为父进程提供了观察和控制其子进程执行的能力并允许父进程检查和替换子进程内核映像包括寄存器的值。许多调试工具都是基于此功能进行调试的。但是每个进程只能调用一个ptrace。只要我们试图在代码中跟踪自己就会出现错误
进程识别
交互进程有一个标识符称为会话的“Leader”进程即SID。我们可以通过父进程PPID和引导进程SID之间的差异来判断执行应用程序时是否存在中间程序也就是我们的调试工具。通过关注getsid、getppid、getpgid和getpgrp的值我们可以检测调试器当前是否正在运行。
参数和环境变量
从bash-shell解释文档中我们可以看到环境变量“-”的值将包含已运行的每个应用程序的全名。在正常环境中此变量的值应等于/path/argv[0]。但是在调试器中这个变量的值经常被修改因此我们可以通过比较这两个值来知道它当前是否处于调试环境中
运行时检测Runtime detection
当程序处于调试状态时由于调试期间的断点、内存检查和其他操作运行时间通常比正常时间长得多。因此如果程序运行时间过长可能是由于正在调试。具体来说当程序启动时通过警报设置计时器当计时器到达时程序终止。但是对于一些调试器如gdb我们可以设置gdb处理信号的方式。如果我们选择忽略SIGALRM而不是将其传递给程序则不会执行alarmHandler。我们需要考虑其他实时检测运行时的方法。
进程插入
使用Ptrace
Ptrace是Unix系列系统的系统调用之一。它的主要功能是跟踪过程。对于目标进程执行流量控制读取和写入用户寄存器值以及读取和修改内存。这个特性非常适合编写实现和远程代码注入。大多数病毒都会使用它来实现自用空间注入、rip位置直接注入以及文本和数据段之间的间隙注入。
使用LD PRELOAD
LD PRELOAD是Linux/Unix系统的一个环境变量。它会影响程序的运行时链接器。它允许在程序运行之前定义要首先加载的动态链接库。该函数主要用于在不同的动态链接库中选择性地加载相同的函数。通过这个环境变量我们可以在主程序与其动态链接库之间加载其他动态链接库甚至可以覆盖正常的函数库
使用Proc文件系统
Proc是一个虚拟文件系统安装在Linux系统中的/Proc目录上。Proc具有多种功能包括允许用户访问内核信息或使用它进行故障排除。其中一个非常有用的功能是能够以文本流的形式访问进程信息这在Linux中变得更加独特。在Proc中有两个伪文件即Proc/pid/maps和Proc/pid/mem。
proc/pid/mem提供了进程使用的完整内存空间的稀疏架构并结合从maps文件获得的偏移量mem文件可以用于读取和写入进程的内存空间。如果偏移量不正确或者从起始位置按顺序读取文件则会返回读写错误因为这相当于读取无法访问的未分配内存。
通过这两个文件可以定位目标进程中的函数。使用这些函数地址可以替换当前堆栈上的正常返回地址并完成进程注入。
失速代码
特点
指令序列在分析环境中的运行速度比在真实(本地)主机上慢得多他整个执行必须花费不可忽略的时间
在这里,不可忽略的必须与分配给程序自动分析的总时间联系起来
运行时间测量
恶意软件的运行时度量是指在程序运行时收集信息的行为。这些信息可能包括系统配置、进程信息、文件系统结构、网络连接等。这些信息可以帮助恶意软件适应不同的环境或者帮助它们在感染计算机后进行更多攻击。通过编译语言插入我们可以获得CPU品牌、供应商、版本和Hypervisor模式状态等信息。
反仿真 anti-emulation
许多恶意代码使用反仿真技术来阻止研究人员在沙盒中检查程序。反仿真技术包括硬件检查、环境检查和时间分析三种方法
硬件检测
从字面上看硬件检查就是检查模拟器不支持的硬件命令和行为。这是因为虚拟机/模拟器对某些指令的实现与物理机不同。首先官方arm手册对某些指令的返回值有所保留未定义的返回值由处理器制造商自行返回。第二种是qemu等模拟器在执行特殊指令时可能与arm手册不一致包括arm自己的fvp试剂盒该试剂盒也与手册不一致。因此通过检查指令的特性它不仅有助于识别它是否在模拟器中运行而且有助于确定它在哪个模拟器中运行。
环境检测
环境检查是恶意软件检测系统环境中是否存在模拟器相关内容的地方。通常模拟器中的环境变量会与物理机器不同例如硬盘、NIC信息和制造商。
时序分析
时序分析是检测程序是否在模拟器中执行的常用方法。在物理机器上一些与加密、解密、媒体编码和解码相关的指令由硬件加速。然而在模拟器中指令不是由硬件加速的而是由CPU计算的这导致了执行时间的指数差。通过这种方式恶意软件可以很容易地检测它是否在模拟器中执行。
反内存转储 Anti-Memory-Dump
“反内存转储”Anti-Memory Dumping是指一类技术和手段旨在防止或干扰对程序内存的转储操作。在计算机安全领域内存转储是指将程序的内存内容写入文件通常是为了进行分析、调试或逆向工程。反内存转储技术旨在对抗这种操作使得攻击者难以获取敏感信息或分析程序的内部结构
反内存转储是用于防止恶意代码分析的常用方法。通常恶意软件实际上无法阻止我们转储物理内存但恶意软件可以对代码进行模糊处理并加密只有在代码执行时才能解密。恶意软件通常会虚拟化指令并使用虚拟指令解释器。重新配置寄存器和指令以重新模拟CPU的本机指令并形成一个虚拟指令集该虚拟指令集依赖解释器将它们解释为本机指令以供执行解释器只处理当前获取的指令。