远程代码注入

除了通常的通过DLL注入来向其他进程插入代码,还有一种方法,就是直接想目标进程插入代码,此方法与前者相比之下有以下几个优点:
1、由于不用注入DLL,所以是目标进程占用的内存更小
2、由于没有注入DLL,也使得更不容易被检测到(比如有些检测手段通过对比进程运行前后的DLL来判断是否有DLL插入)

当然这种方法也有其缺点,它编程相对复杂,不适合大量代码注入,另外在提权操作中可能有失败的情况,我亲测本方法在win10环境中,提权会失败。

#include "stdafx.h"
#include "windows.h"
#include "stdio.h"
BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) 
{
    TOKEN_PRIVILEGES tp;
    HANDLE hToken;
    LUID luid;

    if( !OpenProcessToken(GetCurrentProcess(),
                          TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, 
                          &hToken) )
    {
        printf("OpenProcessToken error: %u\n", GetLastError());
        return FALSE;
    }

    if( !LookupPrivilegeValue(NULL,           // lookup privilege on local system
                              lpszPrivilege,  // privilege to lookup 
                              &luid) )        // receives LUID of privilege
    {
        printf("LookupPrivilegeValue error: %u\n", GetLastError() ); 
        return FALSE; 
    }

    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    if( bEnablePrivilege )
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    else
        tp.Privileges[0].Attributes = 0;

    // Enable the privilege or disable all privileges.
    if( !AdjustTokenPrivileges(hToken, 
                               FALSE, 
                               &tp, 
                               sizeof(TOKEN_PRIVILEGES), 
                               (PTOKEN_PRIVILEGES) NULL, 
                               (PDWORD) NULL) )
    { 
        printf("AdjustTokenPrivileges error: %u\n", GetLastError() ); 
        return FALSE; 
    } 

    if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )
    {
        printf("The token does not have the specified privilege. \n");
        return FALSE;
    } 

    return TRUE;
}

typedef struct _THREAD_PARAM
{
    FARPROC pFunc[2];//LoadlibraryA(),GetProAddress()
    char szBuf[4][128];//"user32.dll","MessageBoxA"                     //"www.reversecore.com","RecerseCore"
}THREAD_PARAM,*PTHREAD_PARAM;

//LoadLibraryA()
typedef HMODULE (WINAPI *PFLOADLIBRARYA)
(
    LPCSTR lpLibFileName
    );
//GetProcAddress()
typedef FARPROC (WINAPI *PFGETPROCADDRESS)
    (HMODULE  hModule,
     LPCSTR lpProcName);
//MessageBox
typedef int(WINAPI *PFMESSAGEBOXA)
    (
    HWND hWnd,
    LPCSTR lpText,
    LPCSTR lpCaption,
    UINT uType
    );

//Thread Procdure
DWORD WINAPI ThreadProc(LPVOID lParam)
{
    PTHREAD_PARAM pParam   =(PTHREAD_PARAM)lParam;
    HMODULE       hMod     =NULL;
    FARPROC       pFunc    =NULL;

    //LoadLibrary("user32.dll")
    //pParam->pFunc[0]->kernel32!LoadLibraryA()
    //pParam->szBuf[0]->"user32.dll"
    hMod = ((PFLOADLIBRARYA)pParam->pFunc[0])(pParam->szBuf[0]);

    //GetProcAddress("MessageBoxA")
    //pParam->pFunc[1]->kernel32!GetProcAddress()
    //pParam->szBuf[1]->"MessageBox"
    pFunc = (FARPROC)((PFGETPROCADDRESS)pParam->pFunc[1])(hMod,pParam->szBuf[1]);

    //MessageBoxA(NULL,"www.reversecore.com","ReverseCore",MB_OK)
    //pParam->szBuf[2]->"www.reversecore.com"
    //pParam->szBuf[3]->"ReverseCore"
    ((PFMESSAGEBOXA)pFunc)(NULL,pParam->szBuf[2],pParam->szBuf[3],MB_OK);

    return 0;
}
BOOL InjectCode(DWORD dwPID)
{
    HMODULE        hMod         =   NULL;
    THREAD_PARAM   param        =   {0,};
    HANDLE         hProcess     =   NULL;
    HANDLE         hThread      =   NULL;
    LPVOID         pRemoteBuf[2]=   {0,};
    DWORD          dwSize       =   0;

    hMod = GetModuleHandleA("kernel32.dll");

    //set THREAD_PARAM
    param.pFunc[0]  =  GetProcAddress(hMod,"LoadLibraryA");
    param.pFunc[1]  =  GetProcAddress(hMod,"GetProcAddress");
    strcpy_s(param.szBuf[0],"user32.dll");
    strcpy_s(param.szBuf[1],"MessageBoxA");
    strcpy_s(param.szBuf[2],"www.reversecore.com");
    strcpy_s(param.szBuf[3],"RecerseCore");

    //open Process
    hProcess = OpenProcess(
        PROCESS_ALL_ACCESS, 
        FALSE,
        dwPID
        );
    if(hProcess==NULL)
    {
        printf("open Process  failed %d\n",GetLastError());
    }
    //Allocation for THREAD_PARAM
    dwSize = sizeof(THREAD_PARAM);
    pRemoteBuf[0] = VirtualAllocEx(
        hProcess,
        NULL,
        dwSize,       //dwSize
        MEM_COMMIT,   //flAllocationType
        PAGE_READWRITE);
    if(pRemoteBuf[0]==NULL)
    {
        printf("Allocation for THREAD_PARAM  failed\n");
    }

    WriteProcessMemory(
        hProcess,
        pRemoteBuf[0],
        (LPVOID)&param,//lpBuffer
        dwSize,
        NULL);        //lpNumberOfByteWritten

    //Allocation for ThreadProc
    /*此处的长度计算有点难以理解,实际上它的长度是因为ThreadProc和 InjectCode是1、2的关系,函数名
代表了函数起始地址,同时在本程序编译Release版本的时候,
内存地址的顺序就是函数顺序,所以可以用2-1的方式,
试想此方法并非通用,当它失效的时候,可以找到的一种方法是
直接通过调试器查看内存,来确定该函数的大小*/
    dwSize = (DWORD)InjectCode - (DWORD)ThreadProc;
    pRemoteBuf[1] = VirtualAllocEx(hProcess,
        NULL,
        dwSize,
        MEM_COMMIT,
        PAGE_EXECUTE_READWRITE);
    if(pRemoteBuf[1]==NULL)
    {
        printf("Allocation for ThreadProc  failed\n");
    }
    WriteProcessMemory(
        hProcess,
        pRemoteBuf[1],
        (LPVOID)ThreadProc,//lpBuffer
        dwSize,
        NULL);        //lpNumberOfByteWritten

    hThread = CreateRemoteThread(
        hProcess,
        NULL,
        0,
        (LPTHREAD_START_ROUTINE)pRemoteBuf[1],//lpStartAddress
        pRemoteBuf[0],//lpParameter
        0,
        NULL);
    if(hThread==NULL)
    {
        printf("hThread==NULL injection failed\n");
        printf("open hThread  failed %d\n",GetLastError());
    }
    WaitForSingleObject(hThread,INFINITE);
    CloseHandle(hThread);
    CloseHandle(hProcess);

    return TRUE;

}
int main(int argc, char* argv[])
{
    DWORD dwPID=0;
    if(argc!=2)
    {
        printf("\n USAGE %s argv[0] pid\n");
        return 1;
    }

    // change privilege
    if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )
        return 1;

    //Code Injection
    dwPID=(DWORD)atol(argv[1]);
    InjectCode(dwPID);
    return 0;
}

小结:
本程序虽然短小,但是注入思路简洁,将自定结构体作为参数和将写入远进程的缓冲区的起始地址作为创建远线程的参数的方法值得借鉴,原先让我这个不太懂编程的孩子是打破脑袋也想不到的,实为精妙,至于为什么在win10 64位运行失败,以后再来研究。
后续:
1、关于之前在WIN10上CreateRemoteThread失败返回失败码5放入情况,网上查看说是因为权限不够,32位程序在64位系统提权失败,实际上,我的提权函数也写过错误代码而并没有返回错误,说明不是提权失败,而是CreateRemoteThread这个函数在64位系统运行出错的问题,测试用此程序在自己创建的exe程序注入的时候并没有出现异常,猜想是win 10 64位对系统进程作了保护机制,究竟是什么,还是没弄清楚,待进一步查证。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值