0%

msfvenom_01

messagebox

最终修改: 2021.02.18
初稿日期: 2021.02.01
msf 版本: 6.0.28
本地系统: Kali-Linux-2020.4-vmware-amd64
目标系统: windows x86
文档描述: 第一篇先从 MessageBox 开始吧

msfvenom 生成的 messagebox shellcode

1
$ msfvenom -a x86 --platform windows -p windows/messagebox TEXT="MSFU Example" -f raw > messageBox

初始化部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
D9 EB           fldpi                   ; 载入圆周率/激活浮点寄存器
9B D9 74 24 F4 fstenv byte ptr [esp-0Ch] ; 把 FpuSaveState 结构体保存在 [esp-0Ch] 处
31 D2 xor edx, edx ; edx 清零
B2 77 mov dl, 77h ; 'w' ; dl 置位 77h
31 C9 xor ecx, ecx ; ecx 清零
64 8B 71 30 mov esi, fs:[ecx+30h] ; 从 TEB 中得到 PEB 结构地址,存入 esi
8B 76 0C mov esi, [esi+0Ch] ; 获取 PEB_LDR_Data 结构地址,存入 esi
8B 76 1C mov esi, [esi+1Ch] ; PLD 中 1c 位置的 InInitializationOrderLinks 存入 esi

next_module:
8B 46 08 mov eax, [esi+8] ; eax = [esi+8]
8B 7E 20 mov edi, [esi+20h] ; edx = [esi+20]
8B 36 mov esi, [esi] ; esi = [esi]
38 4F 18 cmp [edi+18h], cl ; 判断下一项是否为空
75 F3 jnz short loc_17 ; 不为空则继续循环
59 pop ecx ; ecx = 0018FCF4 = shellcode 起始地址
01 D1 add ecx, edx ; ecx = 0018FD6B = sub_77
FF E1 jmp ecx ; 跳转到 shellcode 入口

寻找目标模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
; find_function
60 pusha
8B 6C 24 24 mov ebp, [esp+24h] ; 将要加载模块的基地址放入EBP
8B 45 3C mov eax, [ebp+3Ch] ; 跳过 DOS 头
8B 54 28 78 mov edx, [eax+ebp+78h] ; 找到导出表, 并将其相对地址放入EDX
01 EA add edx, ebp ; 将相对地址(EDX)与基地址(EBP)相加, 得到导出表的绝对地址, 存入 EDX
8B 4A 18 mov ecx, [edx+18h] ; 设置计数器 ECX
8B 5A 20 mov ebx, [edx+20h] ; 将 名称表 的相对偏移存入 EBX
01 EB add ebx, ebp ; 得到 名称表 的绝对地址, 存入EBX

fund_function_l oop:
E3 34 jecxz short loc_75 ; find_function_finished, 如果 ECX 为 0, 并且最后一个函数被验证过了
; 正常情况下不应执行这个跳转
; 执行这个跳转说明函数没找到
49 dec ecx ; ECX - 1
8B 34 8B mov esi, [ebx+ecx*4] ; 获取当前函数的名称的相对偏移, 并存入 ESI
01 EE add esi, ebp ; 相对地址 + 基地址 获得 绝对地址
; compute_hash :
31 FF xor edi, edi ; EDI 清零
31 C0 xor eax, eax ; EAX 清零
FC cld ; 清空标志位

compute_hash_again:
AC lodsb ; 获取当前的函数名(ESI 中存储地址处的字符串)
84 C0 test al, al ; 检查是否为所要找的函数名
74 07 jz short compute_hash_finished ; 找到了执行该跳转
C1 CF 0D ror edi, 0Dh ; 把 hash 循环右移13位
01 C7 add edi, eax ; 把当前函数名的 Character 加入到 hash
EB F4 jmp short compute_hash_again ; 继续找

compute_hash_finished:
3B 7C 24 28 cmp edi, [esp+28h] ; 检查当前hash是否匹配所要找的函数的hash
75 E1 jnz short fund_function_loop ; 不匹配, 继续找
8B 5A 24 mov ebx, [edx+24h] ; 取出序号表的相对地址,放入 EBX
01 EB add ebx, ebp ; 得到绝对地址
66 8B 0C 4B mov cx, [ebx+ecx*2] ; 获取当前符号序号
8B 5A 1C mov ebx, [edx+1Ch] ; 获取相对地址放入EBX
01 EB add ebx, ebp ; 获取绝对地址
8B 04 8B mov eax, [ebx+ecx*4] ; 获取函数偏移
01 E8 add eax, ebp ; 得到函数的实际地址
89 44 24 1C mov [esp+1Ch], eax ; 把函数地址存入 esp+1Ch

popa:
61 popa
C3 retn
; find_function endp

shellcode正文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
; start_main
B2 08 mov dl, 8
29 D4 sub esp, edx ; 分配栈空间
89 E5 mov ebp, esp ; 将 ebp 设置为 相对偏移 的 帧ptr
89 C2 mov edx, eax ; 将 kernel32 的基地址保存在 edx 中
68 8E 4E 0E EC push 0EC0E4E8Eh ; 获取 LoadLibrary 函数 ptr
52 push edx
E8 9F FF FF FF call find_function ; eax = 77574907 = LoadLibraryA
89 45 04 mov [ebp+4], eax
BB 7E D8 E2 73 mov ebx, 73E2D87Eh
87 1C 24 xchg ebx, [esp]
52 push edx
E8 8E FF FF FF call find_function ; eax = 77577a10 = ExitProcess
89 45 08 mov [ebp+8], eax
68 6C 6C 20 41 push 'A ll'
68 33 32 2E 64 push 'd.23'
68 75 73 65 72 push 'resu'
30 DB xor bl, bl
88 5C 24 0A mov [esp+0Ah], bl
89 E6 mov esi, esp
56 push esi
FF 55 04 call dword ptr [ebp+4] ; eax = 765b00 = user32.dll
89 C2 mov edx, eax
50 push eax
BB A8 A2 4D BC mov ebx, 0BC4DA2A8h
87 1C 24 xchg ebx, [esp]
52 push edx
E8 5F FF FF FF call find_function ; eax = 7661fd1e = MessageBoxA
68 6F 78 58 20 push ' Xxo'
68 61 67 65 42 push 'Bega'
68 4D 65 73 73 push 'sseM' ; 18fc70
31 DB xor ebx, ebx
88 5C 24 0A mov [esp+0Ah], bl
89 E3 mov ebx, esp ; ebx = 18fc70
68 58 20 20 20 push ' X'
68 6D 70 6C 65 push 'elpm'
68 20 45 78 61 push 'axE '
68 4D 53 46 55 push 'UFSM' ; 18fc60
31 C9 xor ecx, ecx
88 4C 24 0C mov [esp+0Ch], cl
89 E1 mov ecx, esp ; ecx = 18fc60
31 D2 xor edx, edx ; edx = 0
52 push edx ; uType
53 push ebx ; lpCaption
51 push ecx ; lpText
52 push edx ; hWnd
FF D0 call eax ; MessageBox
31 C0 xor eax, eax
50 push eax
FF 55 08 call dword ptr [ebp+8]
; start_main endp
参考资料
  1. msf 中 MsgBox 的源码
  2. 通过Hash查找API函数地址
  3. msf 中通过 Hash 查找 API 函数地址的源码