远程注入小记

来源:互联网 发布:电脑翻墙好用的软件 编辑:程序博客网 时间:2024/05/18 00:24

原作者连接

提权方法
64位的一定要生成64的,网上说32和64内存隔开的。

//注入程序#include "stdafx.h"#include "Remote injection.h"#include "tlhelp32.h"using namespace std;extern int ListProcess();extern int EnableDebugPriv(const WCHAR *);int _tmain(int argc, TCHAR *argv[], TCHAR *env[]){    //为了成功使用CreateRemoteThread()函数,必须:    //1.利用OpenProcess()获得远程进程的句柄    //2.利用VirtualAllocEx(),WriteProcessMemory()写入DLL路径字符串    //3.获得远程进程中LoadLibrary()的确切地址    //输入进程ID获得进程句柄    char YesNo;    printf("是否查看当前进程列表获得进程ID: Y or N?");    scanf("%c", &YesNo);    Sleep(250);    if (YesNo == 'Y' || YesNo == 'y')        ListProcess();    printf("请输入要注入的进程ID【‘’表示自身进程】:\n");    DWORD dwRemoteProcessId;    scanf("%d", &dwRemoteProcessId);    //如果输入“”表示向自身进程注入    if (dwRemoteProcessId == 0)        dwRemoteProcessId = GetCurrentProcessId();    //获得调试权限    if (EnableDebugPriv(SE_DEBUG_NAME))    {        printf("Add Privilege error\n");        return -1;    }    //调用OpenProcess()获得句柄    HANDLE hRemoteProcess;    if ((hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwRemoteProcessId)) == NULL)    {        printf("OpenProcess error\n");        printf("Error Code:%d\n", GetLastError());        system("pause");        return -2;    }    //在远程进程中分配内存,准备拷入DLL路径字符串    //取得当前DLL路径    char DllPath[260]; //Windows路径最大为    GetCurrentDirectoryA(260, DllPath);  //获取当前进程执行目录    printf("Proces***e Directory is %s\n", DllPath);    strcat(DllPath, "\\..\\Debug\\MyDLL.dll"); //链接到DLL路径    LPVOID pRemoteDllPath = VirtualAllocEx(hRemoteProcess, NULL, strlen(DllPath) + 1, MEM_COMMIT, PAGE_READWRITE);    if (pRemoteDllPath == NULL)    {        printf("VirtualAllocEx error\n");        return -3;    }    //向远程进程空间中写入DLL路径字符串    printf("DllPath is %s\n", DllPath);    DWORD Size;    if (WriteProcessMemory(hRemoteProcess, pRemoteDllPath, DllPath, strlen(DllPath) + 1, &Size) == NULL)    {        printf("WriteProcessMemory error\n");        return -4;    }    printf("WriteRrmoyrProcess Size is %d\n\n", Size);    //获得远程进程中LoadLibrary()的地址    LPTHREAD_START_ROUTINE pLoadLibrary = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");    if (pLoadLibrary == NULL)    {        printf("GetProcAddress error\n");        return -5;    }    else    {        printf("LoadLibrary's Address is 0x%x\n\n", pLoadLibrary);    }    //启动远程线程    DWORD dwThreadId;    HANDLE hThread;    hThread = CreateRemoteThread(hRemoteProcess, NULL, 0, pLoadLibrary, pRemoteDllPath, 0, &dwThreadId);    if (hThread == NULL)    {        printf("CreateRemoteThread error\n");        return -6;    }    else    {        WaitForSingleObject(hThread, INFINITE);        printf("dwThreadId is %d\n\n", dwThreadId);        printf("Inject is done\n");    }    //释放分配内存    if (VirtualFreeEx(hRemoteProcess, pRemoteDllPath, 0, MEM_RELEASE) == 0)    {        printf("VitualFreeEx error\n");        return -8;    }    //释放句柄    if (hThread != NULL) CloseHandle(hThread);    if (hRemoteProcess != NULL) CloseHandle(hRemoteProcess);    system("pause");    return 0;}int ListProcess(){    //获取系统快照    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //不要写错CreateToolhelp32Snapshot()    if (hProcessSnap == INVALID_HANDLE_VALUE)    {        printf("CreateToolHelp32Snapshot error!\n");        return -1;    }    //创建单个进程快照结构体,初始化大小    PROCESSENTRY32 pe32;    pe32.dwSize = sizeof(PROCESSENTRY32);  //务必提前初始化,否则默认的大小不一定满足要求    //初始化缓冲区    WCHAR buff[1024] = { 0 }; //PROCESSENTRY32中的szExeFile为WCHAR类型数组,此处应一致,使用Unicode码    //枚举系统快照链表中的第一个进程项目    BOOL bProcess = Process32First(hProcessSnap, &pe32);    while (bProcess)    {        //格式化进程名和进程ID,这里要使用printf的宽字符版        //格式字符串“”都需要用L转换为宽字符形式        wsprintf(buff, L"FileName:%-30sID:%-6d\r\n", pe32.szExeFile, pe32.th32ProcessID);        wprintf(L"%s\n", buff);        //缓冲区复位        memset(buff, 0, sizeof(buff));        //继续枚举下一个进程        bProcess = Process32Next(hProcessSnap, &pe32);    }    CloseHandle(hProcessSnap);    return 0;}int EnableDebugPriv(const WCHAR *name){    HANDLE hToken;   //进程令牌句柄    TOKEN_PRIVILEGES tp;  //TOKEN_PRIVILEGES结构体,其中包含一个【类型+操作】的权限数组    LUID luid;       //上述结构体中的类型值    //打开进程令牌环    //GetCurrentProcess()获取当前进程的伪句柄,只会指向当前进程或者线程句柄,随时变化    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))    {        printf("OpenProcessToken error\n");        return -8;    }    //获得本地进程name所代表的权限类型的局部唯一ID    if (!LookupPrivilegeValue(NULL, name, &luid))    {        printf("LookupPrivilegeValue 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 -9;    }    return 0;}
//Dll// MyDll.cpp : 定义 DLL 的初始化例程。//#include "stdafx.h"#include "MyDll.h"#ifdef _DEBUG#define new DEBUG_NEW#endif////TODO:  如果此 DLL 相对于 MFC DLL 是动态链接的,//      则从此 DLL 导出的任何调入//      MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到//      该函数的最前面。////      例如: ////      extern "C" BOOL PASCAL EXPORT ExportedFunction()//      {//          AFX_MANAGE_STATE(AfxGetStaticModuleState());//          // 此处为普通函数体//      }////      此宏先于任何 MFC 调用//      出现在每个函数中十分重要。  这意味着//      它必须作为函数中的第一个语句//      出现,甚至先于所有对象变量声明,//      这是因为它们的构造函数可能生成 MFC//      DLL 调用。////      有关其他详细信息,//      请参阅 MFC 技术说明 33 和 58。//// CMyDllAppBEGIN_MESSAGE_MAP(CMyDllApp, CWinApp)END_MESSAGE_MAP()void test(CString text);// CMyDllApp 构造CMyDllApp::CMyDllApp(){    // TODO:  在此处添加构造代码,    // 将所有重要的初始化放置在 InitInstance 中    test(L"2");}// 唯一的一个 CMyDllApp 对象CMyDllApp theApp;// CMyDllApp 初始化BOOL CMyDllApp::InitInstance(){    CWinApp::InitInstance();    test(L"1");    return TRUE;}void test(CString text){    text += L"DLL has been mapped!";    MessageBox(NULL, text, text, MB_OK);    FILE *fp = fopen("C:\\test.txt", "w");    fputs("一个DLL测试文本\n", fp);    fclose(fp);}
0 0