导语:对于一个威胁情报分析师来说什么是最烦人的呢?是你有一个只能暂时工作的恶意软件吗?其实无论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把这个组件拉出来:

expire_assembly.png

很好也很容易对吧,除了放在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。

2.png

为了确保我们的过期代码在shellcode运行之前被命中,我们应该在我们的代码为shellcode分配内存之前,即在1767行完成。

3.png

为了做出改变,我们需要利用metasploit的疯狂汇编程序metasm。谢天谢地,它的语法像intel一样。 对源代码的分析表明,你不能像通常那样“调用”API。相反,你必须把一个特殊的hash加到堆栈上,然后调用'ebp'寄存器。在/external/source/shellcode/windows/x86/src/hash.py中有一个特殊的python脚本来获取这些散列。我们需要1个散列,特别是GetLocalTRime。

4.png

输出是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代码获取当前的月份和年份,并将其格式化为十六进制。

5.png

我已经通过在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上。

源链接

Hacking more

...