⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test.cpp

📁 一款轻量级的入侵检测系统 对于网页中的shellcode有一定的防范能力
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "test.h"
#include "markup.h"
#pragma comment(lib, "ws2_32.lib")
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#pragma comment(lib, "ws2_32.lib")
#define WIN32_LEAN_AND_MEAN
#define MAX_PACKET_SIZE        65536
#define SIO_RCVALL            _WSAIOW(IOC_VENDOR,1)
/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

using namespace std;

typedef struct content_rule//数据包payload中关键字节串检测规则
{
	CString payload;//payload中含有的关键字节串
	int depth;//检测深度,即检测到payload的第n位为止
	int offset;//检测位移,即从payload中第n位检测
	bool nocase;//是否区分大小写
	int distance;//
	bool flag;//规则生效标记
}ContentRule;

typedef struct rule//规则结构,用于保存从xml中读入的检测规则,以检测特征数据包
{
	int proto;//协议
	double sourceIP;//源ip
    long srcmask;//源掩码
	double dstIP;//目的ip
	long dstmask;//目的掩码
	int sourcePort;//源端口
	int dstPort;//目的端口
	bool direction;//发送方向方向
	int ttl;//检测数据包的ttl位
	int tos;//检测数据包的tos位
	int identity;//检测数据包的id位
	int dsize;//检测数据包payload长度
	int flags;//检测数据包flags位
	long seq;//检测数据包seq号
	long ack;//检测检测数据包ack号
	int window;//检测数据包窗口大小
	CString msg;//报警返回信息
	ContentRule content[100];//payload规则
	bool activity;//该规则是否生效
}Rule;


Rule rules[1000];//初始化1000条规则

typedef struct ip_header//ip包结构
{
    unsigned char h_verlen; 
	unsigned char tos;
	unsigned short total_len;
	unsigned short ident;
	unsigned short flag_and_flags;
	unsigned char ttl;
	unsigned char proto;
	unsigned short chksum;
	unsigned int sourceIp;
	unsigned int dstIp;

}IPHeader;

typedef struct tcp_header//tcp包结构
{
    unsigned short  sourcePort;
    unsigned short  dstPort;
    unsigned int    seqNum;
    unsigned int    ackNum;
    unsigned char  dataOff;
    unsigned char  flags;
    unsigned short window;
    unsigned short chksum;
    unsigned short urgPtr;

}TCPHeader; 

typedef struct udp_header//udp包结构
{
    unsigned short sourcePort;
	unsigned short dstPort;
	unsigned short pocketSize;
	unsigned short chksum;
}UDPHeader;




void checkdatagram(char * temp,int packetSize);//数据包检测函数
bool checkpayload(ContentRule * content,char * payload,int payloadLen);//数据包payload检测函数
char * memmem(char * source,char * dest,unsigned int sourceLen,unsigned int destLen);//在字节串中找子字节串函数
char * memlowcase(char * str,int len);//把字节串小写化
char * strtohex(CString str,char * result,int * len);//字符串转换为十六进制
char * ipconv(char * strip,unsigned int ip);//ip格式转换
void loadrule(rule * rules);//从xml文件中读入检测规则
unsigned long GetLocalIP();//得到本机ip



int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])//main
{
	int nRetCode = 0;

	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		cerr << _T("Fatal Error: MFC initialization failed") << endl;
		nRetCode = 1;
	}
	else
	{
		// TODO: code your application's behavior here.
    int nRetCode = 0;
    int nRecvBytes = 0;

	WSADATA wsaData;
	char		buf[2048];
	DWORD		dwBytes;
   // DWORD		dwFlags;
	cout<<"load rules......"<<endl;
	loadrule(rules);//读规则
	cout<<"load success......"<<endl;
	
	if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0 )
    {
        //WSAStartup Error!
        printf("WSAStartup Error!%d\n", WSAGetLastError());
        nRetCode = -1;
        return nRetCode;
    }
	


    char* pBuffer = NULL;

    SOCKET nSock = INVALID_SOCKET;
    //SOCKADDR_IN addr_in;

    //DWORD dwBufferLen[10];
    DWORD dwBufferInLen = 1;
    DWORD dwBytesReturned = 0;
	SOCKADDR_IN	if0;
	SOCKET_ADDRESS_LIST *slist=NULL;
    //define a raw socket
    nSock = WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);
    if (INVALID_SOCKET == nSock)
    {
        nRetCode = -1;
        goto Exit0;
    }
if(SOCKET_ERROR==WSAIoctl(nSock,
		SIO_ADDRESS_LIST_QUERY,NULL,
		0,buf,2048,&dwBytes,NULL,NULL))
	{
		printf("seek failed!");
	}
	slist=(SOCKET_ADDRESS_LIST*)buf;
	
	if(slist->iAddressCount<=0)
		{
			printf("seek2 failed!");
		}
	    if0.sin_addr.s_addr=GetLocalIP();//绑定到列表中第一个接口(第一步之前声明过:SOCKADDR_IN	if0)
		if0.sin_family=AF_INET;
		if0.sin_port=htons(0);	//port0表示系统自定端口?
		if(SOCKET_ERROR==::bind(nSock,(SOCKADDR*)&if0,sizeof(if0)))
		{
		printf("bind failed!");
		}
    //socket for sniffer
    nRetCode = WSAIoctl(nSock, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen),NULL,0, &dwBytesReturned , NULL , NULL );//设定网卡为混杂状态,接受所有的数据包
    if (SOCKET_ERROR == nRetCode)
    {
        printf("WSAIOCTL Error!%d\n", WSAGetLastError());
        goto Exit0;
    }
    //start sniffing
    pBuffer = (char*)malloc(MAX_PACKET_SIZE);//接收缓冲区
    cout<<"start snnifering......"<<endl;//开始截包
    while(1)
    {

        memset(pBuffer, 0, MAX_PACKET_SIZE);
		IPHeader * pIpHeader=NULL;
		TCPHeader * pTcpHeader=NULL;
        nRecvBytes = recv(nSock, pBuffer, MAX_PACKET_SIZE, 0);//把包内容放到缓冲区
        pIpHeader = (IPHeader *)pBuffer;
        if (SOCKET_ERROR == nRetCode)
		{

            printf("RECV Error!%d\n", WSAGetLastError());
            goto Exit0;
        }
        if (nRecvBytes < 46)continue;
		char * temp =new char [MAX_PACKET_SIZE];//建立临时缓冲区
		memset(temp,0,MAX_PACKET_SIZE);
		memcpy(temp,pBuffer,nRecvBytes);//把包考入临时缓冲区
		checkdatagram(temp,nRecvBytes);//分析数据包
		if(temp !=NULL) free(temp);//释放资源
    }
Exit0://出错退出

    if (pBuffer != NULL)
        free(pBuffer);

    if (nSock != INVALID_SOCKET)
        closesocket(nSock);

    return nRetCode;
}



}


void checkdatagram(char * temp,int packetSize)//数据包分析
{  
	IPHeader * pipheader=(IPHeader *)temp;
	if(pipheader->proto==IPPROTO_TCP)//包协议为tcp
	{
	    TCPHeader * ptcpheader=(TCPHeader *)(temp+sizeof(IPHeader));
	    char * payload=temp+sizeof(IPHeader)+sizeof(TCPHeader);
	    int payloadLen=packetSize-(sizeof(IPHeader)+sizeof(TCPHeader));
		for(int count=0;count<1000;count++)
		{
           if(rules[count].activity!=true)break;
	       if(rules[count].proto>0)
		   {
		       if(rules[count].proto!=IPPROTO_TCP)continue;//检查协议是否符合rule定义
		   }
	       if(rules[count].sourceIP>0)
		   {   
		       unsigned int tempip=rules[count].sourceIP;//检查源地址是否符合rule定义
			   if(rules[count].srcmask!=-1)//是否指定了掩码
			   {
				   if(((pipheader->sourceIp)&(rules[count].srcmask))!=(tempip&(rules[count].srcmask)))continue;
			   }
		       else if(pipheader->sourceIp!=tempip)continue;
		   }
	       if(rules[count].dstIP>0)//检查目的地址是否符合rule定义
		   {
		       unsigned int tempip=rules[count].dstIP;
			   if(rules[count].dstmask!=-1)//是否指定了掩码
			   {
				   if(((pipheader->dstIp)&(rules[count].dstmask))!=(tempip&(rules[count].dstmask)))continue;
			   }
		       else if(pipheader->dstIp!=tempip)continue;
		   }
	       if(rules[count].direction==true)//是否检反方向数据包
		   {
		      if(rules[count].sourceIP>0)
			  {   
		          unsigned int tempip=rules[count].sourceIP;
				  if(rules[count].srcmask!=-1)
				  {
                      if(((pipheader->dstIp)&(rules[count].srcmask))!=(tempip&(rules[count].srcmask))&&((pipheader->sourceIp)&(rules[count].srcmask))!=(tempip&(rules[count].srcmask)))continue;
				  }
		          else if(pipheader->dstIp!=tempip&&pipheader->sourceIp!=tempip)continue;
			  }
		     if(rules[count].dstIP>0)
			 {   
		          unsigned int tempip=rules[count].dstIP;
				  if(rules[count].dstmask!=-1)
				  {
                      if(((pipheader->sourceIp)&(rules[count].dstmask))!=(tempip&(rules[count].dstmask))&&((pipheader->dstIp)&(rules[count].dstmask))!=(tempip&(rules[count].dstmask)))continue;
				  }
		          else if(pipheader->sourceIp!=tempip&&pipheader->dstIp!=tempip)continue;
			 }
		   }
	       if(rules[count].sourcePort>0)//检查源端口是否符合rule定义
		   {
		       if(ntohs(ptcpheader->sourcePort)!=rules[count].sourcePort)continue;
		   }
	       if(rules[count].dstPort>0)//检查目的端口是佛符合rule定义
		   {
		       if(ntohs(ptcpheader->dstPort)!=rules[count].dstPort)continue;
		   }
	       if(rules[count].direction==true)//相反反方向数据包
		   {
	           if(rules[count].dstPort>0)
			   {
		           if(ntohs(ptcpheader->dstPort)!=rules[count].dstPort&&ntohs(ptcpheader->dstPort)!=rules[count].sourcePort)continue;
			   }
	           if(rules[count].sourcePort>0)
			   {
		           if(ntohs(ptcpheader->sourcePort)!=rules[count].sourcePort&&ntohs(ptcpheader->sourcePort)!=rules[count].dstPort)continue;
			   }

		   }	
	      if(rules[count].ttl>0)//检查ttl是否符合rule定义
		  {
		      if(pipheader->ttl!=rules[count].ttl)continue;
		  }
	      if(rules[count].tos>0)//检查tos是否符合rule定义
		  {
		      if(pipheader->tos!=rules[count].tos)continue;
		  }
	
	      if(rules[count].identity>0)//检查id是否符合rule定义
		  {
		      if(pipheader->ident!=rules[count].identity)continue;
		  }
	      if(rules[count].dsize>0)//检查payload长度是否符合rule定义
		  {
		      int payloadLen=packetSize-sizeof(IPHeader)-sizeof(TCPHeader);
		      if(payloadLen!=rules[count].dsize)continue;
		  }
	      if(rules[count].flags>0)//检查flags位是否符合rule定义
		  {
		      if(ptcpheader->flags!=rules[count].flags)continue;
		  }
	      if(rules[count].seq>0)//检查seq号是否符合rule定义
		  {
		      long tempSeq=ntohl(ptcpheader->seqNum);
		      if(tempSeq!=rules[count].seq)continue;
		  }
	      if(rules[count].ack>0)//检查ack号是否符合rule定义
		  {
		      if(rules[count].ack!=ptcpheader->ackNum)continue;
		  }
	      if(rules[count].window>0)//检查窗口大小是否符合rule定义
		  {
		      if(ntohs(ptcpheader->window)!=rules[count].window)continue;
		  }
          if(checkpayload(rules[count].content,payload,payloadLen)!=true)continue;//进入payload检查函数
	    //匹配规则后,报警
		  char srcip[20];
		  char dstip[20];
		  ipconv(srcip,pipheader->sourceIp);
		  ipconv(dstip,pipheader->dstIp);
		  CTime currenttime = CTime::GetCurrentTime();
	      CString time=currenttime.Format("(%#Y/%#m/%#d/%#H:%#M:%#S)");
          cout<<time.GetBuffer(time.GetLength())<<"alert:"<<rules[count].msg.GetBuffer(rules[count].msg.GetLength())<<"  "<<srcip<<" to "<<dstip<<endl;
	      CFile alertFile;
	      alertFile.Open("alert.txt",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
	      alertFile.Seek(0,CFile::end);
	      alertFile.Write(time.GetBuffer(time.GetLength()),time.GetLength());
	      alertFile.Write("alert:  ",8);
	      alertFile.Write(rules[count].msg.GetBuffer(rules[count].msg.GetLength()),rules[count].msg.GetLength());
		  alertFile.Write("   ",3);
		  alertFile.Write(srcip,strlen(srcip));
		  alertFile.Write(" to ",4);
		  alertFile.Write(dstip,strlen(dstip));
	      alertFile.Write("\r\n",2);//txt记录警报
	      alertFile.Flush();
	      alertFile.Close();
	   //alert
		}
	}
	else if(pipheader->proto==IPPROTO_UDP)//包协议为udp
	{
		UDPHeader * pudpheader=(UDPHeader *)(temp+sizeof(IPHeader));
		char * payload=temp+sizeof(IPHeader)+sizeof(UDPHeader);
		int payloadLen=packetSize-(sizeof(IPHeader)+sizeof(UDPHeader));
        for(int count=0;count<1000;count++)//检查数据包
		{
           if(rules[count].activity!=true)break;
	       if(rules[count].proto>0)
		   {
		       if(rules[count].proto!=IPPROTO_UDP)continue;//检查包协议
		   }
	       if(rules[count].sourceIP>0)//检查源地址是否符合rule定义
		   {   
		       unsigned int tempip=rules[count].sourceIP;
			   if(rules[count].srcmask!=-1)//是否指定了掩码
			   {
				   if(((pipheader->sourceIp)&(rules[count].srcmask))!=(tempip&(rules[count].srcmask)))continue;
			   }
		       else if(pipheader->sourceIp!=tempip)continue;
		   }
	       if(rules[count].dstIP>0)//检查目的地址是否符合rule定义
		   {
		       unsigned int tempip=rules[count].dstIP;
			   if(rules[count].dstmask!=-1)
			   {
				   if(((pipheader->dstIp)&(rules[count].dstmask))!=(tempip&(rules[count].dstmask)))continue;
			   }
		       else if(pipheader->dstIp!=tempip)continue;
		   }
	       if(rules[count].direction==true)//是否指定检查反方向数据包
		   {
		      if(rules[count].sourceIP>0)
			  {   
		          unsigned int tempip=rules[count].sourceIP;
				  if(rules[count].srcmask!=-1)
				  {
                      if(((pipheader->dstIp)&(rules[count].srcmask))!=(tempip&(rules[count].srcmask))&&((pipheader->sourceIp)&(rules[count].srcmask))!=(tempip&(rules[count].srcmask)))continue;
				  }
		          else if(pipheader->dstIp!=tempip&&pipheader->sourceIp!=tempip)continue;
			  }
		     if(rules[count].dstIP>0)
			 {   
		          unsigned int tempip=rules[count].dstIP;
				  if(rules[count].dstmask!=-1)
				  {
                      if(((pipheader->sourceIp)&(rules[count].dstmask))!=(tempip&(rules[count].dstmask))&&((pipheader->dstIp)&(rules[count].dstmask))!=(tempip&(rules[count].dstmask)))continue;
				  }
		          else if(pipheader->sourceIp!=tempip&&pipheader->dstIp!=tempip)continue;
			 }
		   }
	       if(rules[count].sourcePort>0)//检查源端口是否符合规则定义
		   {
		       if(ntohs(pudpheader->sourcePort)!=rules[count].sourcePort)continue;
		   }
	       if(rules[count].dstPort>0)//检查目的端口是否符合规则定义
		   {
		       if(ntohs(pudpheader->dstPort)!=rules[count].dstPort)continue;
		   }
	       if(rules[count].direction==true)//是否检查反方向数据包
		   {
	           if(rules[count].dstPort>0)
			   {
		           if(ntohs(pudpheader->dstPort)!=rules[count].dstPort&&ntohs(pudpheader->dstPort)!=rules[count].sourcePort)continue;
			   }
	           if(rules[count].sourcePort>0)
			   {
		           if(ntohs(pudpheader->sourcePort)!=rules[count].sourcePort&&ntohs(pudpheader->sourcePort)!=rules[count].dstPort)continue;
			   }

		   }
		   if(rules[count].dsize>0)//检查payload长度是否符合rule定义
		   {
               if(payloadLen!=rules[count].dsize)continue;
		   }
           if(checkpayload(rules[count].content,payload,payloadLen)!=true)continue;//按照payload规则检查数据包的payload
	       //匹配规则,alert
		  char srcip[20];
		  char dstip[20];
		  ipconv(srcip,pipheader->sourceIp);
		  ipconv(dstip,pipheader->dstIp);
		  CTime currenttime = CTime::GetCurrentTime();
	      CString time=currenttime.Format("(%#Y/%#m/%#d/%#H:%#M:%#S)");
          cout<<time.GetBuffer(time.GetLength())<<"alert:"<<rules[count].msg.GetBuffer(rules[count].msg.GetLength())<<"  "<<srcip<<" to "<<dstip<<endl;
	      CFile alertFile;
	      alertFile.Open("alert.txt",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
	      alertFile.Seek(0,CFile::end);
	      alertFile.Write(time.GetBuffer(time.GetLength()),time.GetLength());
	      alertFile.Write("alert:  ",8);
	      alertFile.Write(rules[count].msg.GetBuffer(rules[count].msg.GetLength()),rules[count].msg.GetLength());
		  alertFile.Write(srcip,strlen(srcip));
		  alertFile.Write("   ",3);
		  alertFile.Write(" to ",4);
		  alertFile.Write(dstip,strlen(dstip));
	      alertFile.Write("\r\n",2);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -