Windows 注入

平常用的最多的dll注入技术就是远程线程,刚刚逛看雪,看到有人写的面试的时候被问到的问题,其中就有dll注入的方法,我突然想到我开始面试的时候也被问了dll注入的方法,当时也是就只知道一个远程线程,答的也不好,然后就想把一些注入技术写个总结。接下来讲的注入技术,有ring3层的lld的远程线程和apc注入,还有ring0的apc注入,此外还有更为隐蔽的代码注入。

先写最广泛的,也是相对简单的注入方式,远程线程。

一 ring3 dll的远程线程

我写的涉及到x86和x64的注入,因为x64的系统本身增加了较多权限的校验,需要进行提权处理。所以先进行系统版本的校验:

typedef enum  _WIN_VERSION
{
    WindowsNT,
    Windows2000,
    WindowsXP,
    Windows2003,
    WindowsVista,
    Windows7,
    Windows8,
    WinUnknown
}WIN_VERSION;

WIN_VERSION  GetWindowsVersion()
{
    OSVERSIONINFOEX    OsVerInfoEx;
    OsVerInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    GetVersionEx((OSVERSIONINFO *)&OsVerInfoEx); // 注意转换类型
    switch (OsVerInfoEx.dwPlatformId)
    {
    case VER_PLATFORM_WIN32_NT:
        {
            if (OsVerInfoEx.dwMajorVersion <= 4 )
            {
                return WindowsNT;
            }
            if (OsVerInfoEx.dwMajorVersion == 5 && OsVerInfoEx.dwMinorVersion == 0)
            {
                return Windows2000;
            }

            if (OsVerInfoEx.dwMajorVersion == 5 && OsVerInfoEx.dwMinorVersion == 1)
            {
                return WindowsXP;
            }
            if (OsVerInfoEx.dwMajorVersion == 5 && OsVerInfoEx.dwMinorVersion == 2)
            {
                return Windows2003;
            }
            if (OsVerInfoEx.dwMajorVersion == 6 && OsVerInfoEx.dwMinorVersion == 0)
            {
                return WindowsVista;
            }

            if (OsVerInfoEx.dwMajorVersion == 6 && OsVerInfoEx.dwMinorVersion == 1)
            {
                return Windows7;
            }
            if (OsVerInfoEx.dwMajorVersion == 6 && OsVerInfoEx.dwMinorVersion == 2 )
            {
                return Windows8;
            }
            break;
        }

    default:
        {
            return WinUnknown;
        }
    }

}

获得系统版本

x86和x64的注入最主要的不同点就是对于x64的提权处理,接下来先讲x64的提权处理。

x64的提权主要就是用到了ntdll.dll中未导出的一个函数,RtlAdjustPrivilege(),这个函数的作用是很大的,之前的瞬间关机的代码就是用了这个函数进行提权。

/*
   .常量 SE_BACKUP_PRIVILEGE, "17", 公开
   .常量 SE_RESTORE_PRIVILEGE, "18", 公开
   .常量 SE_SHUTDOWN_PRIVILEGE, "19", 公开
   .常量 SE_DEBUG_PRIVILEGE, "20", 公开
*/

我们提升的权限就是SE_DEBUG_PRIVILEGE  20

//程序编译成64位可以注入64位 编译成32位可以注入32位
CWinApp theApp;
typedef enum  _WIN_VERSION
{
    WindowsNT,
    Windows2000,
    WindowsXP,
    Windows2003,
    WindowsVista,
    Windows7,
    Windows8,
    WinUnknown
}WIN_VERSION;

VOID InjectDll(ULONG_PTR ProcessID);
WIN_VERSION  GetWindowsVersion();
BOOL InjectDllByRemoteThread32(const TCHAR* wzDllFile, ULONG_PTR ProcessId);
WIN_VERSION  WinVersion = WinUnknown;

BOOL InjectDllByRemoteThread64(const TCHAR* wzDllFile, ULONG_PTR ProcessId);
typedef long (__fastcall *pfnRtlAdjustPrivilege64)(ULONG,ULONG,ULONG,PVOID);
pfnRtlAdjustPrivilege64 RtlAdjustPrivilege;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    cout<<"查看要注入进程的ID"<<endl;
    ULONG_PTR ProcessID = 0;
    WinVersion = GetWindowsVersion();
    printf("Input ProcessID\r\n");
    cin>>ProcessID;
    InjectDll(ProcessID);
    return 0;
}

VOID InjectDll(ULONG_PTR ProcessID)
{
    CString strPath32 = L"MessageBox32.dll";   //32位dll注入32位系统
    CString strPath64 = L"MessageBox64.dll";
    if (ProcessID == 0)
    {
        return;
    }
    if (PathFileExists(strPath32)&&PathFileExists(strPath64))
    {
        switch(WinVersion)
        {
        case Windows7:   //这里用的是Win7 x64 sp1
            {

                WCHAR wzPath[MAX_PATH] = {0};
                GetCurrentDirectory(260,wzPath);
                wcsncat_s(wzPath, L"\\", 2);
                wcsncat_s(wzPath, strPath64.GetBuffer(), strPath64.GetLength());//dll完整路径
                strPath32.ReleaseBuffer();
                if (!InjectDllByRemoteThread64(wzPath,ProcessID))
                    printf("Inject Fail\r\n");
                else printf ("Inject Success\r\n");
                break;
            }

        case WindowsXP:  //WinXp x86 sp3
            {
                WCHAR wzPath[MAX_PATH] = {0};
                GetCurrentDirectory(260,wzPath);
                wcsncat_s(wzPath, L"\\", 2);
                wcsncat_s(wzPath, strPath32.GetBuffer(), strPath32.GetLength());

                strPath32.ReleaseBuffer();
                if (!InjectDllByRemoteThread32(wzPath,ProcessID))
                    printf("Inject Fail\r\n");
                else printf("Inject Success\r\n");
                break;
            }
        }

    }
}

BOOL InjectDllByRemoteThread64(const TCHAR* wzDllFile, ULONG_PTR ProcessId)
{
    if (NULL == wzDllFile || 0 == ::_tcslen(wzDllFile) || ProcessId == 0 || -1 == _taccess(wzDllFile, 0))
    {
        return FALSE;
    }
    HANDLE                 hProcess = NULL;
    HANDLE                 hThread  = NULL;
    DWORD                  dwRetVal    = 0;
    LPTHREAD_START_ROUTINE FuncAddress = NULL;
    DWORD  dwSize = 0;
    TCHAR* VirtualAddress = NULL;
    //预编译,支持Unicode
#ifdef _UNICODE
    FuncAddress = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryW");
#else
    FuncAddress = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryA");
#endif

    if (FuncAddress==NULL)
    {
        return FALSE;
    }

    RtlAdjustPrivilege=(pfnRtlAdjustPrivilege64)GetProcAddress((HMODULE)(FuncAddress(L"ntdll.dll")),"RtlAdjustPrivilege");

    if (RtlAdjustPrivilege==NULL)
    {
        return FALSE;
    }
        /*
        .常量 SE_BACKUP_PRIVILEGE, "17", 公开
        .常量 SE_RESTORE_PRIVILEGE, "18", 公开
        .常量 SE_SHUTDOWN_PRIVILEGE, "19", 公开
        .常量 SE_DEBUG_PRIVILEGE, "20", 公开
        */
    RtlAdjustPrivilege(20,1,0,&dwRetVal);  //19

    hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, ProcessId);

    if (NULL == hProcess)
    {
        printf("Open Process Fail\r\n");
        return FALSE;
    }

    // 在目标进程中分配内存空间
    dwSize = (DWORD)::_tcslen(wzDllFile) + 1;
    VirtualAddress = (TCHAR*)::VirtualAllocEx(hProcess, NULL, dwSize * sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE);
    if (NULL == VirtualAddress)
    {
        printf("Virtual Process Memory Fail\r\n");
        CloseHandle(hProcess);
        return FALSE;
    }

    // 在目标进程的内存空间中写入所需参数(模块名)
    if (FALSE == ::WriteProcessMemory(hProcess, VirtualAddress, (LPVOID)wzDllFile, dwSize * sizeof(TCHAR), NULL))
    {
        printf("Write Data Fail\r\n");
        VirtualFreeEx(hProcess, VirtualAddress, dwSize, MEM_DECOMMIT);
        CloseHandle(hProcess);
        return FALSE;
    }

    hThread = ::CreateRemoteThread(hProcess, NULL, 0, FuncAddress, VirtualAddress, 0, NULL);
    if (NULL == hThread)
    {
        printf("CreateRemoteThread Fail\r\n");
        VirtualFreeEx(hProcess, VirtualAddress, dwSize, MEM_DECOMMIT);
        CloseHandle(hProcess);
        return FALSE;
    }
    // 等待远程线程结束
    WaitForSingleObject(hThread, INFINITE);
    // 清理资源
    VirtualFreeEx(hProcess, VirtualAddress, dwSize, MEM_DECOMMIT);
    CloseHandle(hThread);
    CloseHandle(hProcess);
    return TRUE;

}

BOOL InjectDllByRemoteThread32(const TCHAR* wzDllFile, ULONG_PTR ProcessId)
{
    // 参数无效
    if (NULL == wzDllFile || 0 == ::_tcslen(wzDllFile) || ProcessId == 0 || -1 == _taccess(wzDllFile, 0))
    {
        return FALSE;
    }
    HANDLE hProcess = NULL;
    HANDLE hThread  = NULL;
    DWORD dwSize = 0;
    TCHAR* VirtualAddress = NULL;
    LPTHREAD_START_ROUTINE FuncAddress = NULL;
    // 获取目标进程句柄
    hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, ProcessId);
    if (NULL == hProcess)
    {
        printf("Open Process Fail\r\n");
        return FALSE;
    }
    // 在目标进程中分配内存空间
    dwSize = (DWORD)::_tcslen(wzDllFile) + 1;
    VirtualAddress = (TCHAR*)::VirtualAllocEx(hProcess, NULL, dwSize * sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE);
    if (NULL == VirtualAddress)
    {
        printf("Virtual Process Memory Fail\r\n");
        CloseHandle(hProcess);
        return FALSE;
    }
    // 在目标进程的内存空间中写入所需参数(模块名)
    if (FALSE == ::WriteProcessMemory(hProcess, VirtualAddress, (LPVOID)wzDllFile, dwSize * sizeof(TCHAR), NULL))
    {
        printf("Write Data Fail\r\n");
        VirtualFreeEx(hProcess, VirtualAddress, dwSize, MEM_DECOMMIT);
        CloseHandle(hProcess);
        return FALSE;
    }
    // 从 Kernel32.dll 中获取 LoadLibrary 函数地址
#ifdef _UNICODE
    FuncAddress = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryW");
#else
    FuncAddress = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryA");
#endif

    if (NULL == FuncAddress)
    {
        printf("Get LoadLibrary Fail\r\n");
        VirtualFreeEx(hProcess, VirtualAddress, dwSize, MEM_DECOMMIT);
        CloseHandle(hProcess);
        return false;
    }

    // 创建远程线程调用 LoadLibrary
    hThread = ::CreateRemoteThread(hProcess, NULL, 0, FuncAddress, VirtualAddress, 0, NULL);
    if (NULL == hThread)
    {
        printf("CreateRemoteThread Fail\r\n");
        VirtualFreeEx(hProcess, VirtualAddress, dwSize, MEM_DECOMMIT);
        CloseHandle(hProcess);
        return FALSE;
    }

    // 等待远程线程结束
    WaitForSingleObject(hThread, INFINITE);
    // 清理
    VirtualFreeEx(hProcess, VirtualAddress, dwSize, MEM_DECOMMIT);
    CloseHandle(hThread);
    CloseHandle(hProcess);

    return TRUE;
}

WIN_VERSION  GetWindowsVersion()
{
    OSVERSIONINFOEX    OsVerInfoEx;
    OsVerInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    GetVersionEx((OSVERSIONINFO *)&OsVerInfoEx); // 注意转换类型
    switch (OsVerInfoEx.dwPlatformId)
    {
    case VER_PLATFORM_WIN32_NT:
        {
            if (OsVerInfoEx.dwMajorVersion <= 4 )
            {
                return WindowsNT;
            }
            if (OsVerInfoEx.dwMajorVersion == 5 && OsVerInfoEx.dwMinorVersion == 0)
            {
                return Windows2000;
            }

            if (OsVerInfoEx.dwMajorVersion == 5 && OsVerInfoEx.dwMinorVersion == 1)
            {
                return WindowsXP;
            }
            if (OsVerInfoEx.dwMajorVersion == 5 && OsVerInfoEx.dwMinorVersion == 2)
            {
                return Windows2003;
            }
            if (OsVerInfoEx.dwMajorVersion == 6 && OsVerInfoEx.dwMinorVersion == 0)
            {
                return WindowsVista;
            }

            if (OsVerInfoEx.dwMajorVersion == 6 && OsVerInfoEx.dwMinorVersion == 1)
            {
                return Windows7;
            }
            if (OsVerInfoEx.dwMajorVersion == 6 && OsVerInfoEx.dwMinorVersion == 2 )
            {
                return Windows8;
            }
            break;
        }

    default:
        {
            return WinUnknown;
        }
    }

}

二 ring3 apc注入

APC注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,其具体流程如下:
    1)当EXE里某个线程执行到SleepEx()或者WaitForSingleObjectEx()时,系统就会产生一个软中断。
    2)当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数。
    3)利用QueueUserAPC()这个API可以在软中断时向线程的APC队列插入一个函数指针,如果我们插入的是Loadlibrary()执行函数的话,就能达到注入DLL的目的。

#define _WIN32_WINNT 0x0400
#include <windows.h>
#include <TlHelp32.h>

#include <iostream>
#include <string>
using namespace std;

#define DEF_BUF_SIZE 1024

typedef long (__fastcall *pfnRtlAdjustPrivilege64)(ULONG,ULONG,ULONG,PVOID);
pfnRtlAdjustPrivilege64 RtlAdjustPrivilege;

// 用于存储注入模块DLL的路径全名
char szDllPath[DEF_BUF_SIZE] = {0} ;

// 使用APC机制向指定ID的进程注入模块
BOOL InjectModuleToProcessById ( DWORD dwProcessId )
{
    DWORD    dwRet = 0 ;
    BOOL    bStatus = FALSE ;
    LPVOID    lpData = NULL ;
    UINT    uLen = strlen(szDllPath) + 1;
#ifdef _WIN64   // x64 OpenProcess提权操作
     RtlAdjustPrivilege=(pfnRtlAdjustPrivilege64)GetProcAddress((HMODULE)(FuncAddress(L"ntdll.dll")),"RtlAdjustPrivilege");

    if (RtlAdjustPrivilege==NULL)
    {
        return FALSE;
    }
        /*
        .常量 SE_BACKUP_PRIVILEGE, "17", 公开
        .常量 SE_RESTORE_PRIVILEGE, "18", 公开
        .常量 SE_SHUTDOWN_PRIVILEGE, "19", 公开
        .常量 SE_DEBUG_PRIVILEGE, "20", 公开
        */
    RtlAdjustPrivilege(20,1,0,&dwRetVal);  //19
#endif
    // 打开目标进程
    HANDLE hProcess = OpenProcess ( PROCESS_ALL_ACCESS, FALSE, dwProcessId ) ;
    if ( hProcess )
    {
        // 分配空间
        lpData = VirtualAllocEx ( hProcess, NULL, uLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE ) ;
        if ( lpData )
        {
            // 写入需要注入的模块路径全名
            bStatus = WriteProcessMemory ( hProcess, lpData, szDllPath, uLen, &dwRet ) ;
        }
        CloseHandle ( hProcess ) ;
    }

    if ( bStatus == FALSE )
        return FALSE ;

    // 创建线程快照
    THREADENTRY32 te32 = { sizeof(THREADENTRY32) } ;
    HANDLE hThreadSnap = CreateToolhelp32Snapshot ( TH32CS_SNAPTHREAD, 0 ) ;
    if ( hThreadSnap == INVALID_HANDLE_VALUE )
        return FALSE ; 

    bStatus = FALSE ;
    // 枚举所有线程
    if ( Thread32First ( hThreadSnap, &te32 ) )
    {
        do{
            // 判断是否目标进程中的线程
            if ( te32.th32OwnerProcessID == dwProcessId )
            {
                // 打开线程
                HANDLE hThread = OpenThread ( THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID ) ;
                if ( hThread )
                {
                    // 向指定线程添加APC
                    DWORD dwRet = QueueUserAPC ( (PAPCFUNC)LoadLibraryA, hThread, (ULONG_PTR)lpData ) ;
                    if ( dwRet > 0 )
                        bStatus = TRUE ;
                    CloseHandle ( hThread ) ;
                }
            } 

        }while ( Thread32Next ( hThreadSnap, &te32 ) ) ;
    }

    CloseHandle ( hThreadSnap ) ;
    return bStatus;
}

int _tmain(int argc, _TCHAR* argv[])
{
    // 取得当前工作目录路径
    GetCurrentDirectoryA ( DEF_BUF_SIZE, szDllPath ) ;

    // 生成注入模块DLL的路径全名
    strcat ( szDllPath, "\\DLLSample.dll" ) ;

    DWORD dwProcessId = 0 ;
    // 接收用户输入的目标进程ID
    while ( cout << "请输入目标进程ID:" && cin >> dwProcessId && dwProcessId > 0 )
    {
        BOOL bRet = InjectModuleToProcessById ( dwProcessId ) ;
        cout << (bRet ? "注入成功!":"注入失败!") << endl ;
    }
    return 0;
}

三ring3层的远程线程的代码注入

代码是成功,但是每次运行就explorer直接崩溃。我开始还以为是我程序写的有问题,后来用WinDbg Attach到explorer进程调试,才发现问题,就是函数调用的问题,在汇编中call调用函数时不是绝对地址,机器码是相对偏移,这就涉及到函数的便宜重新重定位的问题,得不偿失,代价太大。仅仅以学习为目的的话,可以考虑用0day中非常经典的类似于GetProcAddress()函数实现的191个字节的shellcode来获取函数地址。先放上代码吧,在Windbg中对explorer中的RemoteCodeAddr下断点,是可以执行到那的,然后执行到call MessageBox就崩溃,就是函数的偏移的问题。

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

typedef long (__fastcall *pfnRtlAdjustPrivilege64)(ULONG,ULONG,ULONG,PVOID);
pfnRtlAdjustPrivilege64 RtlAdjustPrivilege;

static DWORD WINAPI MyFunc (LPVOID pData)
{
    //do something
    //...
    //pData输入项可以是任何类型值
//    ::MessageBoxA(NULL,(char*)pData,"INJECT",0); //不能直接调用
    //调用函数时要考虑call RVA  都是相对的偏移,
    return *(DWORD*)pData;
}

static void AfterMyFunc (void) {
}

int _tmain(int argc, _TCHAR* argv[])
{
    DWORD cbCodeSize = (ULONG_PTR)AfterMyFunc-(ULONG_PTR)MyFunc +0x100;
    DWORD ProcessId = 0;
    cin>>ProcessId;

#ifdef _WIN64   // x64 OpenProcess提权操作
     RtlAdjustPrivilege=(pfnRtlAdjustPrivilege64)GetProcAddress((HMODULE)(GetModuleHandle(L"ntdll.dll")),"RtlAdjustPrivilege");

    if (RtlAdjustPrivilege==NULL)
    {
        return FALSE;
    }
        /*
        .常量 SE_BACKUP_PRIVILEGE, "17", 公开
        .常量 SE_RESTORE_PRIVILEGE, "18", 公开
        .常量 SE_SHUTDOWN_PRIVILEGE, "19", 公开
        .常量 SE_DEBUG_PRIVILEGE, "20", 公开
        */
    DWORD dwReturnVal;
    RtlAdjustPrivilege(20,1,0,&dwReturnVal);  //19
#endif
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, ProcessId);
    //申请放置代码的内存
    PVOID RemoteCodeAddr = (PVOID)VirtualAllocEx( hProcess, 0, cbCodeSize,
        MEM_COMMIT,
        PAGE_EXECUTE_READWRITE );
    WriteProcessMemory( hProcess, RemoteCodeAddr, &MyFunc, cbCodeSize, NULL);

    char szBuffer[] = "HelloWorld";
    PVOID RemoteDataAddr = (PVOID)VirtualAllocEx( hProcess, 0, sizeof(szBuffer),
        MEM_COMMIT,
        PAGE_READWRITE );
    WriteProcessMemory( hProcess, RemoteDataAddr, szBuffer, sizeof(szBuffer), NULL);

    HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0,
        (LPTHREAD_START_ROUTINE) RemoteCodeAddr,
        RemoteDataAddr, 0 , NULL);
    DWORD h;
    if (hThread)
    {
        ::WaitForSingleObject( hThread, INFINITE );
        ::CloseHandle( hThread );
    }
    //cout<<dwSizeOfMyFunc<<endl;
    return 0;
}

明天再把ring0的apc注入写上。

时间: 2024-10-27 02:41:05

Windows 注入的相关文章

远程线程注入方法CreateRemoteThread

最近在整理学习Windows注入方面的知识,这个远程注入前面早写过,现在看看人家博客的理解整理,整理, 需要源码的可以到我的github上下载. 链接是  https://github.com/Arsense/WindowsCode 首先先来说说什么是注入,为什么要注入 0x00 Baise 注入就是把自己的Dll注入到人家的代码中,被注入的DLL拥有目标进程内存的访问权限,所以我们可以通过该 向某个进程注入DLL时的方法主要有以下三种: 创建远程线程(CreateRemoteThread()

Android 注入详解

Android下的注入的效果是类似于Windows下的dll注入,关于Windows下面的注入可以参考这篇文章Windows注入术.而Android一般处理器是arm架构,内核是基于linux,因此进程间是弱相互作用,不存在Windows下类似于CreateRemoteThread 作用的函数,可以在其他进程空间内创建线程来加载我们的.so文件,所以我们所采用的方法就是依赖于linux下的ptrace()函数,将目标进程作为我们进程的子进程操作目标进程的寄存器和内存来运行我们加载.so文件的代码

Windows API参考大全新编

书名:新编Windows API参考大全 作者:本书编写组 页数:981页 开数:16开 字数:2392千字 出版日期:2000年4月第二次印刷 出版社:电子工业出版社 书号:ISBN 7-5053-5777-8 定价:98.00元 内容简介 作为Microsoft 32位平台的应用程序编程接口,Win32 API是从事Windows应用程序开发所必备的.本书首先对Win32 API函数做完整的概述:然后收录五大类函数:窗口管理.图形设备接口.系统服务.国际特性以及网络服务:在附录部分,讲解如何

小白日记46:kali渗透测试之Web渗透-SqlMap自动注入(四)-sqlmap参数详解- Enumeration,Brute force,UDF injection,File system,OS,Windows Registry,General,Miscellaneous

sqlmap自动注入 Enumeration[数据枚举] --privileges -U username[CU 当前账号] -D dvwa -T users -C user --columns  [指定数据库,表,列] --exclude-sysdbs [排除系统层的库] ******************************************************************************* #查具体数据 [前提:当前数据库用户有权读取informatio

Windows x86/ x64 Ring3层注入Dll总结

0x01.前言 提到Dll的注入,立马能够想到的方法就有很多,比如利用远程线程.Apc等等,这里我对Ring3层的Dll注入学习做一个总结吧. 我把注入的方法分成六类,分别是:1.创建新线程.2.设置线程上下背景文,修改寄存器.3.插入Apc队列.4.修改注册表.5.挂钩窗口消息.6.远程手动实现LoadLibrary. 那么下面就开始学习之旅吧! 0x02.预备工作 在涉及到注入的程序中,提升程序的权限自然是必不可少的,这里我提供了两个封装的函数,都可以用于提权.第一个是通过权限令牌来调整权限

【windows核心编程】使用远程线程注入DLL

前言 该技术是指通过在[目标进程]中创建一个[远程线程]来达到注入的目的. 创建的[远程线程]函数为LoadLibrary, 线程函数的参数为DLL名字, 想要做的工作在DLL中编写.  示意图如下:  相关API 1.创建远程线程 //该函数除了第一个参数为目标进程句柄外 //其他参数均和CreateThread一样 HANDLE hThread = CreateRemoteThread( __in HANDLE hProcess, //目标进程句柄 __in_opt LPSECURITY_A

Windows系统的dll注入

声明:这篇博客原为本人在CSDN上发布的,但是CSDN这个网站违背了本人的分享和开源精神,另外CSDN的广告满天飞.审核重重(所有的下载必须使用CSDN下载,而下载需要积分,这严重违背本人的无私分享精神.开源精神.),即使审核通过也会不定时进行重新审核,CSDN的这些操作严重影响了本人的博客管理.因此,本着无私分享精神.开源精神.轻松使用原则,本人摒弃了CSDN,并将博文重新编辑并发布在博客园网站上,而原博文作删除处理! 一.什么是dll注入 在Windows操作系统中,运行的每一个进程都生活在

在windows系统和kali中通过sqlmap注入

第1章 在windows系统中通过sqlmap注入 1.1 环境搭建 Sqlmap是目前功能最强大,使用最为广泛的注入类工具,是一个开源软件,被集成于kaliLinux, 由于sqlmap是基于Python编写,所以需要在系统中先安装好2.7.x版本的Python,然后将下载好的sqlmap放在Python2.7目录下,这里Python安装我就不一一截图了,因为都是使用默认安装,只是安装的时候根据需要可以修改下安装路径. 在Windows下首先把下载好的sqlmap放在Python路径下 然后我

Windows dll注入

概念 DLL注入(英语:DLL injection)是一种计算机编程技术,它可以强行使另一个进程加载一个动态链接库以在其地址空间内运行指定代码[1].在Windows操作系统上,每个进程都有独立的进程空间,即一个进程是无法直接操作另一个进程的数据的(事实上,不仅Windows,许多操作系统也是如此).但是DLL注入是用一种不直接的方式,来实现操作其他进程的数据.假设我们有一个DLL文件,里面有操作目标进程数据的程序代码逻辑,DLL注入就是使目标进程加载这个DLL,加载后,这个DLL就成为目标进程