S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

about Injection (2)

Posted on 2010-02-07 17:23 S.l.e!ep.¢% 阅读(1512) 评论(2)  编辑 收藏 引用 所属分类: RootKit
about Injection   被说成是 black paper.....  俺只是技术研究,没其它目的.....

代码优化

bool EnablePrivilege(LPCTSTR lpszPrivilege, bool bEnable)
{
    HANDLE TokenHandle 
= NULL;

    
// 
    if ( FALSE == ::OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &TokenHandle) )
    {
        
return false;
    }
    
    TOKEN_PRIVILEGES tkp;
    
    
// Get LUID for SeDebugPrivilege
    if( FALSE == ::LookupPrivilegeValue(NULL, lpszPrivilege, &tkp.Privileges[0].Luid) )
    {
        ::CloseHandle(TokenHandle);
        
return false;
    }

    tkp.PrivilegeCount 
= 1;

#ifndef SE_PRIVILEGE_REMOVED
#define SE_PRIVILEGE_REMOVED 0X00000004 
#endif

    
if( bEnable )
        tkp.Privileges[
0].Attributes = SE_PRIVILEGE_ENABLED;
    
else
        tkp.Privileges[
0].Attributes = SE_PRIVILEGE_REMOVED;
    
    
if ( FALSE == AdjustTokenPrivileges(TokenHandle, FALSE, &tkp, 0, NULL, NULL) ) 
    {
        ::CloseHandle(TokenHandle);
        
return false;
    }

    ::CloseHandle(TokenHandle);

    
return true;
}

bool RemoteLoadDLL(DWORD dwProcessID, const char* pszDLLPath)
{
    typedef HMODULE (WINAPI 
*LoadLibraryPointor)(LPCTSTR);
    LoadLibraryPointor pfnLoadLibrary 
= NULL;
    HMODULE hKernel32 
= NULL;
    
    
//Get address to LoadLibrary and FreeLibrary
    if (pfnLoadLibrary == NULL) 
    {
        hKernel32 
= ::GetModuleHandle("kernel32.dll");
        
        
if ( hKernel32 == NULL )
        {
            
return false;            
        }
        
        pfnLoadLibrary 
= (LoadLibraryPointor)GetProcAddress(hKernel32, "LoadLibraryA");
        
        
if (pfnLoadLibrary == NULL)
        {
            ::FreeLibrary(hKernel32);
            
return false;
        }
    }

    
if!EnablePrivilege(SE_DEBUG_NAME, true) )
        
return false;

    HANDLE process 
= ::OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ|PROCESS_QUERY_INFORMATION, TRUE, dwProcessID);
    
if ( process == NULL )
    {
        ::EnablePrivilege(SE_DEBUG_NAME, 
false);
        
return false;
    }

    PVOID memory 
= ::VirtualAllocEx(process, NULL, strlen(pszDLLPath)+1, MEM_COMMIT, PAGE_READWRITE);
    
    
if ( memory == NULL )
    {
        ::EnablePrivilege(SE_DEBUG_NAME, 
false);
        ::CloseHandle(process);
        
return false;
    }

    
if ( FALSE == ::WriteProcessMemory(process, memory, (LPVOID)pszDLLPath, strlen(pszDLLPath)+1, NULL) )
    {
        ::EnablePrivilege(SE_DEBUG_NAME, 
false);
        ::VirtualFreeEx(process, memory, strlen(pszDLLPath)
+1, MEM_RELEASE);
        ::CloseHandle(process);
        
return false;
    }

    
// Inject Code
    DWORD dwThreadID = 0;
    HANDLE hRemoteHandle 
= ::CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)pfnLoadLibrary, memory, 0&dwThreadID);

    
if ( hRemoteHandle == NULL ) 
    {
        ::EnablePrivilege(SE_DEBUG_NAME, 
false);
        ::VirtualFreeEx(process, memory, strlen(pszDLLPath)
+1, MEM_RELEASE);
        ::CloseHandle(process);
        
return false;
    }

    ::WaitForSingleObject(hRemoteHandle, INFINITE);

    DWORD dwReturn 
= 0;
    
if( FALSE == ::GetExitCodeThread(hRemoteHandle, &dwReturn) )
    {
        ::EnablePrivilege(SE_DEBUG_NAME, 
false);
        ::CloseHandle(hRemoteHandle);
        ::VirtualFreeEx(process, memory, strlen(pszDLLPath)
+1, MEM_RELEASE);
        ::CloseHandle(process);
        
return false;
    }

    ::EnablePrivilege(SE_DEBUG_NAME, 
false);
    ::CloseHandle(hRemoteHandle);
    ::VirtualFreeEx(process, memory, strlen(pszDLLPath)
+1, MEM_RELEASE);
    ::CloseHandle(process);
    ::FreeLibrary(hKernel32);

    
if( dwReturn == NULL )
        
return false;
    
else
        
return true;    
}

HMODULE GetProcessModule(DWORD dwPID, LPCTSTR czDllName) 

    HMODULE        hMod       
= NULL;
    BOOL          bFound      
= FALSE; 
    HANDLE        hModuleSnap 
= NULL; 
    MODULEENTRY32 me32        
= {0}; 

    
// Take a snapshot of all modules in the specified process. 
    hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID); 
    
if (hModuleSnap == INVALID_HANDLE_VALUE) 
        
return (FALSE); 

    
// Fill the size of the structure before using it. 

    me32.dwSize 
= sizeof(MODULEENTRY32); 

    
// Walk the module list of the process, and find the module of 
    
// interest. Then copy the information to the buffer pointed 
    
// to by lpMe32 so that it can be returned to the caller. 
    if (Module32First(hModuleSnap, &me32)) 
    { 
        
do 
        { 
            
if(0 == lstrcmpi(czDllName, me32.szExePath))
            {
                hMod 
= me32.hModule;
            }
        } 
        
while (hMod == NULL && Module32Next(hModuleSnap, &me32)); 
    } 
    
else 
    {
        hMod 
= NULL;           // could not walk module list 
    }

    
// Do not forget to clean up the snapshot object. 
    CloseHandle(hModuleSnap); 

    
return hMod; 
}

bool RemoteUnLoadDLL(DWORD dwProcessID, const char* pszDLLPath)
{
    typedef BOOL (WINAPI 
*FreeLibraryFunType)(HMODULE hModule);
    FreeLibraryFunType pfnFreeLibrary 
= NULL;
    HMODULE hKernel32 
= NULL;
    
    
//Get address to FreeLibrary
    if (pfnFreeLibrary == NULL) 
    {
        hKernel32 
= ::GetModuleHandle("kernel32.dll");
        
        
if ( hKernel32 == NULL )
        {
            
return false;            
        }
        
        pfnFreeLibrary 
= (FreeLibraryFunType)GetProcAddress(hKernel32, "FreeLibrary");
        
        
if (pfnFreeLibrary == NULL)
        {
            ::FreeLibrary(hKernel32);
            
return false;
        }
    }

    
if!EnablePrivilege(SE_DEBUG_NAME, true) )
        
return false;

    HANDLE process 
= ::OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ|PROCESS_QUERY_INFORMATION, TRUE, dwProcessID);
    
if ( process == NULL )
    {
        ::EnablePrivilege(SE_DEBUG_NAME, 
false);
        
return false;
    }

    HMODULE hUnloadDll 
= GetProcessModule(dwProcessID, pszDLLPath);

    
if( hUnloadDll == NULL )
        
return true;

    
// Inject Code
    DWORD dwThreadID = 0;
    HANDLE hRemoteHandle 
= ::CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)pfnFreeLibrary, (LPVOID)hUnloadDll, 0&dwThreadID);

    
if ( hRemoteHandle == NULL ) 
    {
        ::EnablePrivilege(SE_DEBUG_NAME, 
false);
        ::CloseHandle(process);
        
return false;
    }

    ::WaitForSingleObject(hRemoteHandle, INFINITE);

    DWORD dwReturn 
= 0;
    
if( FALSE == ::GetExitCodeThread(hRemoteHandle, &dwReturn) )
    {
        ::EnablePrivilege(SE_DEBUG_NAME, 
false);
        ::CloseHandle(hRemoteHandle);
        ::CloseHandle(process);
        
return false;
    }

    ::EnablePrivilege(SE_DEBUG_NAME, 
false);
    ::CloseHandle(hRemoteHandle);
    ::CloseHandle(process);
    ::FreeLibrary(hKernel32);

    
if( dwReturn == FALSE )
        
return false;
    
else
        
return true;
}

目前存在的已知问题:
1. 未考虑 64 位机器
2. 未考虑 DLL 加载失败的处理 (2010.02.05-23:38 已经 Fixed)
3. 提权后没有恢复 (2010.02.07-17:15 已经Fixed)
4. 在 RemoteUnloadDLL 时,采用的是重定位DLL句柄的方法,有人跟我反应这种方法不安全,但我暂时还没想到什么情况下会引发问题。


目标程序的输出结果是:
DLL_PROCESS_ATTACH C:\Documents and Settings\Administrator\桌面\demo\test\Debug\test.exe
DLL_THREAD_DETACH C:\Documents and Settings\Administrator\桌面\demo\test\Debug\test.exe
The thread 0x878 has exited with code 13500416 (0xCE0000).
DLL_THREAD_ATTACH C:\Documents and Settings\Administrator\桌面\demo\test\Debug\test.exe
DLL_PROCESS_DETACH C:\Documents and Settings\Administrator\桌面\demo\test\Debug\test.exe
The thread 0x624 has exited with code 1 (0x1).

(开始不明白,结果看了
DLL_THREAD_DETACH 认识误区后就明白了)

又一天就这么过去了~

Feedback

# re: about Injection (2)  回复  更多评论   

2010-02-08 19:32 by 乐蜂网官方网站
偶滴爱哦上帝哦啊

# re: about Injection (2)  回复  更多评论   

2010-02-08 19:51 by DrKN
呵..有點冒犯 真對不起
因為之前那篇都見到你打算給人想到是shutdown跟提權之類 感覺變得像blackpaper

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理