03-哈希算法实战应用
01-使用哈希进行函数调用
使用哈希隐藏API调用
代码
#include<windows.h>
#include<stdio.h>
intmain(){
MessageBoxA(NULL, "Meow-meow!","=^..^=", MB_OK);
return0;
}
编译
i686-w64-mingw32-g++ meow.c -o meow.exe -mconsole -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -Wint-to-pointer-cast -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive
查字符串
strings -n 8 meow.exe | grep MessageBox
MessageBoxA
查看导入表
使用哈希就可以隐藏API函数名
计算MessageBoxA函数哈希
# simple hashing example
def myHash(data):
hash =0x35
for i in range(0, len(data)):
hash +=ord(data[i]) + (hash << 1)
print (hash)
return hash
myHash("MessageBoxA")
运行
python3 myhash.py
17036696
通过哈希调用函数
#include<stdint.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<windows.h>
typedefUINT(CALLBACK* fnMessageBoxA)(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType
);
// MurmurHash is a non-cryptographic hash function and was written by Austin Appleby.
// unsigned int MurmurHash2A(const void *key, size_t len, unsigned int seed) {
// const unsigned int m = 0x5bd1e995;
// const int r = 24;
// unsigned int h = seed ^ len;
// const unsigned char *data = (const unsigned char *)key;
// while (len >= 4) {
// unsigned int k = *(unsigned int *)data;
// k *= m;
// k ^= k >> r;
// k *= m;
// h *= m;
// h ^= k;
// data += 4;
// len -= 4;
// }
// switch (len) {
// case 3:
// h ^= data[2] << 16;
// case 2:
// h ^= data[1] << 8;
// case 1:
// h ^= data[0];
// h *= m;
// };
// h ^= h >> 13;
// h *= m;
// h ^= h >> 15;
// return h;
// }
DWORD calcMyHash(char* data){
DWORD hash = 0x35;
for (int i = 0; i < strlen(data); i++) {
hash += data[i] + (hash << 1);
}
return hash;
}
static LPVOID getAPIAddr(HMODULE h, DWORD myHash){
PIMAGE_DOS_HEADER img_dos_header = (PIMAGE_DOS_HEADER)h;
PIMAGE_NT_HEADERS img_nt_header = (PIMAGE_NT_HEADERS)((LPBYTE)h + img_dos_header->e_lfanew);
PIMAGE_EXPORT_DIRECTORY img_edt = (PIMAGE_EXPORT_DIRECTORY)(
(LPBYTE)h + img_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
PDWORD fAddr = (PDWORD)((LPBYTE)h + img_edt->AddressOfFunctions);
PDWORD fNames = (PDWORD)((LPBYTE)h + img_edt->AddressOfNames);
PWORD fOrd = (PWORD)((LPBYTE)h + img_edt->AddressOfNameOrdinals);
for (DWORD i = 0; i < img_edt->AddressOfFunctions; i++) {
LPSTR pFuncName = (LPSTR)((LPBYTE)h + fNames[i]);
if (calcMyHash(pFuncName) == myHash) {
printf("successfully found! %s - %dn", pFuncName, myHash);
return (LPVOID)((LPBYTE)h + fAddr[fOrd[i]]);
}
}
returnnullptr;
}
intmain(){
HMODULE mod = LoadLibrary("user32.dll");
LPVOID addr = getAPIAddr(mod, 17036696);
printf("0x%pn", addr);
fnMessageBoxA myMessageBoxA = (fnMessageBoxA)addr;
myMessageBoxA(NULL, "Meow-meow!","=^..^=", MB_OK);
return0;
}
编译
i686-w64-mingw32-g++ hack.c -o hack.exe -mconsole -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -Wint-to-pointer-cast -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive
运
查看字符串信息,查看导入表
strings -n 8 hack.exe | grep MessageBox
已经没有MessageBoxA函数信息了,但是如果深入逆向分析的话还是会发现user32.dll字符串的,因为C代码里加载了user32.dll
02-MurmurHash
实战中会经常使用不知名的hash算法,比如MurmurHash
#include<stdint.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<windows.h>
typedefUINT(CALLBACK* fnMessageBoxA)(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType
);
unsignedintMurmurHash2A(constvoid *input, size_t length, unsignedint seed){
constunsignedint m = 0x5bd1e995;
constint r = 24;
unsignedint h = seed ^ length;
constunsignedchar *data = (constunsignedchar *)input;
while (length >= 4) {
unsignedint k = *(unsignedint *)data;
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
data += 4;
length -= 4;
}
switch (length) {
case3:
h ^= data[2] << 16;
case2:
h ^= data[1] << 8;
case1:
h ^= data[0];
h *= m;
};
h ^= h >> 13;
h *= m;
h ^= h >> 15;
return h;
}
static LPVOID getAPIAddr(HMODULE h, DWORD myHash){
PIMAGE_DOS_HEADER img_dos_header = (PIMAGE_DOS_HEADER)h;
PIMAGE_NT_HEADERS img_nt_header = (PIMAGE_NT_HEADERS)((LPBYTE)h + img_dos_header->e_lfanew);
PIMAGE_EXPORT_DIRECTORY img_edt = (PIMAGE_EXPORT_DIRECTORY)(
(LPBYTE)h + img_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
PDWORD fAddr = (PDWORD)((LPBYTE)h + img_edt->AddressOfFunctions);
PDWORD fNames = (PDWORD)((LPBYTE)h + img_edt->AddressOfNames);
PWORD fOrd = (PWORD)((LPBYTE)h + img_edt->AddressOfNameOrdinals);
for (DWORD i = 0; i < img_edt->AddressOfFunctions; i++) {
LPSTR pFuncName = (LPSTR)((LPBYTE)h + fNames[i]);
if (MurmurHash2A(pFuncName, strlen(pFuncName), 0) == myHash) {
printf("successfully found! %s - %dn", pFuncName, myHash);
return (LPVOID)((LPBYTE)h + fAddr[fOrd[i]]);
}
}
returnnullptr;
}
intmain(){
HMODULE mod = LoadLibrary("user32.dll");
LPVOID addr = getAPIAddr(mod, 4115069285);
printf("0x%pn", addr);
fnMessageBoxA myMessageBoxA = (fnMessageBoxA)addr;
myMessageBoxA(NULL, "Meow-meow!","=^..^=", MB_OK);
return0;
}
编译
x86_64-w64-mingw32-g++ murmurhash.c -o murmurhash.exe -s -ffunction-sections -fdata-sections -Wno-write-strings -fexceptions -fmerge-all-constants -static-libstdc++ -static-libgcc
运行
可以使用https://box.closed.ru/mu/计算函数哈希,书中的python代码计算结果不对
原文始发于微信公众号(高级红队专家):【MalDev-12】哈希算法实战应用
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论