导语:对于一个威胁情报分析师来说什么是最烦人的呢?是你有一个只能暂时工作的恶意软件吗?其实无论C&C服务器是否启动,大多数恶意软件都是可以直接使用的。
对于一个威胁情报分析师来说什么是最烦人的呢?是你有一个只能暂时工作的恶意软件吗?其实无论C&C服务器是否启动,大多数恶意软件都是可以直接使用的。那么就让我们来试着做出一些改变吧,比如使我们的payloads失效!
需要我们怎么做呢?其实只是需要一些简单的API调用,一些程序集,一些ruby,一些时间。
首先我们使用C进行如下的操作:
#include <windows.h> WORD month = 12; WORD year = 2017; int main(void) { SYSTEMTIME lt; GetLocalTime(<); if(month == lt.wMonth && year == lt.wYear) { FatalAppExit(0,"cock!"); } else { __asm { push 0 Call ExitProcess } } }
然后我们用IDA把这个组件拉出来:
很好也很容易对吧,除了放在AX寄存器中的2个WORD值。这些来自数据部分,我们需要把它放到一个组装项目中,并使其独立。为什么呢?因为screw只读内存。这意味着会动态分配一块内存,并将其分配给我们的SYSTIME结构,该结构的大小为16字节。
.486 .model flat, stdcall option casemap :none include c:\masm32\include\windows.inc include c:\masm32\include\kernel32.inc include c:\masm32\include\user32.inc includelib c:\masm32\lib\kernel32.lib includelib c:\masm32\lib\user32.lib ;SYSTEMTIME STRUCT ; wYear WORD ? ; wMonth WORD ? ; wDayOfWeek WORD ? ; wDay WORD ? ; wHour WORD ? ; wMinute WORD ? ; wSecond WORD ? ; wMilliseconds WORD ? ;SYSTEMTIME ENDS ; 16 bytes ; first 2 words are checked ; we dont need a data section ; .data ; DAY = 0Eh ; MONTH = 0Ch ; YEAR = 7E1h .code ;sysTime SYSTEMTIME <> start: ; lets figure out how to do this with PIC ; is now PIC push ebp mov ebp, esp ;sub esp, 10h push 40h ; PAGE_EXECUTE_READWRITE push 1000h ; MEM_COMMIT push 10h ; 16 bytes needed push 0h ; NULL as we dont care where the allocation is. call VirtualAlloc mov ebx, eax ; Store allocated address in ebx lea eax, [ebx] push eax call GetLocalTime mov ax, 0Ch ; MONTH cmp ax, [ebx+2] jnz short exitpart mov ax, 7E1h ; YEAR cmp ax, [ebx] jz short continue exitpart: push 0 call ExitProcess continue: push 0 push 65706f6eh call FatalAppExitA ; shellcode start end start
现在我们来使用汇编代码,使用masm来编译它,可能都不到一个KB。 那么现在,我们如何把它实现到metasploit中呢? 所有的payloads都通过这个类/lib/msf/util/exe.rb进行处理和封装。
在1632行,我们有主代码位负责分配一个读/写/可执行的内存块并复制内部的shellcode。
为了确保我们的过期代码在shellcode运行之前被命中,我们应该在我们的代码为shellcode分配内存之前,即在1767行完成。
为了做出改变,我们需要利用metasploit的疯狂汇编程序metasm。谢天谢地,它的语法像intel一样。 对源代码的分析表明,你不能像通常那样“调用”API。相反,你必须把一个特殊的hash加到堆栈上,然后调用'ebp'寄存器。在/external/source/shellcode/windows/x86/src/hash.py中有一个特殊的python脚本来获取这些散列。我们需要1个散列,特别是GetLocalTRime。
输出是0xD92CE33e。这里是我们对exe.rb文件的补充:
;======================================== ; need chunk of memory for SYSTIME struct push 40h ; PAGE_EXECUTE_READWRITE push 1000h ; MEM_COMMIT push 10h ; 16 bytes needed push 0h ; NULL as we dont care where the allocation is. push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" ) call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); mov ebx, eax ; Store allocated address in ebx lea eax, [ebx] push eax push 0xD92CE33e ; GetLocalTime with chunk from VirtualAlloc call ebp mov ax,cx ; curtime = Time.new mov cx, 0x#{curtime.month.to_s(16)} ; MONTH converted to hex cmp cx, [ebx+2] jnz short exitpart mov cx, 0x#{curtime.year.to_s(16)} ; YEAR converted to hex cmp cx, [ebx] jz short wegood exitpart: push 0 push 0x56A2B5F0 call ebp ; ExitProcess wegood: ; passed checks, can start shellcode now ;=====================================
这样看起来还不错,我们现在通过ruby代码获取当前的月份和年份,并将其格式化为十六进制。
我已经通过在exe.rb中创建“win32_rwx_exec”的重复函数来完成这项工作。 我的想法是否会被初始化主要依赖于一个选项。 这意味着需要将选项添加到lib\msf\core\exploit\exe.rb的第19行。
if opts[:expire] payload = win32_rwx_exec_expire(code) end
现在剩下的事情就是提交给MSF,看看他们是否把它收回或者进口。 如果你想使用它,请在这里下载'exe.rb'文件并将它放在你的[INSTALL_DIR] / lib / msf / util /文件夹中。 在这里可以下载http://www.gironsec.com/blog/wp-content/uploads/2018/01/exe.zip。
我知道这可能会使你们中的一些人感到不安,不过这只是在Windows上的,但是我已经完成了第二部分。请继续关注第二部分,看我如何将Linux附加到我的metasploit上。