📄 sniffer.cpp
字号:
#include "StdAfx.h"
#include ".\sniffer.h"
#include "mstcpip.h"
#include "openssl/md5.h"
#include "crypt.h"
CSniffer::CSniffer(void)
{
_snprintf(TcpFlag,6,"FSRPAU");
ParamTcp =false; // -t关注TCP 报文
ParamUdp =false; // -u关注UDP 报文
ParamIcmp =false; // -i关注ICMP报文
ParamDecode=true; // -d对协议进行解码
strFromIpFilter=NULL; // 源IP地址过滤
strDestIpFilter=NULL; // 目的地址过滤
m_inited=false;
WSADATA wsaData;
WSAStartup(MAKEWORD(2,1),&wsaData);
}
CSniffer::~CSniffer(void)
{
}
int CSniffer::Start()
{
int iErrorCode;
char RecvBuf[MAX_PACK_LEN] = { 0 };
ParamUdp=true;
if(!m_inited){
return -4;
}
SockRaw = socket(AF_INET , SOCK_RAW , IPPROTO_UDP);
char FAR name[MAX_HOSTNAME_LAN];
iErrorCode = gethostname(name, MAX_HOSTNAME_LAN);
if(SOCKET_ERROR == iErrorCode){
WSACleanup();
return -1;
}
struct hostent FAR * pHostent;
SOCKADDR_IN sa;
pHostent = gethostbyname(name);
sa.sin_family = AF_INET;
sa.sin_port = htons(6000);
memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length);
iErrorCode = bind(SockRaw, (PSOCKADDR)&sa, sizeof(sa));
if(0!=iErrorCode){
WSACleanup();
return -2;
}
DWORD dwBufferLen[10];
DWORD dwBufferInLen = 1;
DWORD dwBytesReturned = 0;
iErrorCode=WSAIoctl(SockRaw,SIO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );
if(0!=iErrorCode){
WSACleanup();
return -3;
}
memset(RecvBuf, 0, sizeof(RecvBuf));
int nRet;
CString test,test1;
while(1){
nRet = recv(SockRaw, RecvBuf, sizeof(RecvBuf), 0);
DecodeIpPack(RecvBuf,nRet);
}
return 1;
}
int CSniffer::DecodeIpPack(char *buf, int iBufSize)
{
IP_HEADER *pIpheader;
pIpheader = (IP_HEADER *)buf;
if(buf[9]!=0x11){
return -1;
}
WORD sPort,dPort;
WORD udp_len;
//Check Source IP
CString sourceip,destip;
sourceip.Format("%d.%d.%d.%d",(unsigned char)buf[12],(unsigned char)buf[13],(unsigned char)buf[14],(unsigned char)buf[15]);
destip.Format("%d.%d.%d.%d",(unsigned char)buf[16],(unsigned char)buf[17],(unsigned char)buf[18],(unsigned char)buf[19]);
memcpy(&sPort,&buf[20],2);
memcpy(&dPort,&buf[22],2);
memcpy(&udp_len,&buf[24],2);
sPort=ntohs(sPort);
dPort=ntohs(dPort);
udp_len=ntohs(udp_len);
CString tmp,msg,t;
tmp.Format("%s:%d => %s:%d\nUDP Packet Length:%d\n",sourceip,sPort,destip,dPort,udp_len);
msg=msg+tmp;
tmp="";
for(int i=28;i<iBufSize;i++){
t.Format("%2.2X ",(unsigned char)buf[i]);
tmp=tmp+t;
}
msg=msg+tmp+"\n";
tmp="";
PACK_HEADER *phdr;
char *pData;
if(DecodeQQ(&buf[28],iBufSize-28,tmp)>0){
phdr=new PACK_HEADER;
pData=new char[tmp.GetLength()+1];
sprintf(phdr->sIP,"%s",sourceip);
sprintf(phdr->dIP,"%s",destip);
phdr->Len=iBufSize-28;
phdr->sPORT=sPort;
phdr->dPORT=dPort;
sprintf(pData,"%s",tmp);
PostMessage(m_hWnd,MSG_DATAREACH,(WPARAM)phdr,(LPARAM)pData);
}
return 1;
}
int CSniffer::DecodeQQ(char *buf,int buflen,CString &qq_str)
{
if(buf[buflen-1]!=0x03||buf[0]!=0x02){
return 0;
}
QQ_HEADER qq_hdr;
int nRet;
CString tmp;
GetQQHeader(buf,&qq_hdr);
switch(qq_hdr.wType){
case TYPE_GETTOKEN:
nRet=DecodeGetToken(&buf[7],buflen-8,qq_str,&qq_hdr);
break;
case TYPE_LOGIN:
nRet=DecodeLogin(&buf[7],buflen-8,qq_str,&qq_hdr);
break;
case TYPE_GETFRIENDLIST:
nRet=DecodeGetFriendList(&buf[7],buflen-8,qq_str,&qq_hdr);
break;
case TYPE_GETONLINEFRIENDLIST:
nRet=DecodeGetOnlineFriendList(&buf[7],buflen-8,qq_str,&qq_hdr);
break;
case TYPE_PACKET0X67:
nRet=Decode0x67(&buf[7],buflen-8,qq_str,&qq_hdr);
break;
default:
nRet=DecodeDefault(&buf[7],buflen-8,qq_str,&qq_hdr);
break;
}
if(qq_hdr.wType==0x67){
nRet=1;
}
else{
nRet=0;
}
if(nRet>0){
tmp.Format("版本号(0x0001为应答数据):0x%4.4X,帧类型:0x%4.4X,帧序号:0x%4.4X\n",qq_hdr.wVer,qq_hdr.wType,qq_hdr.wIndex);
qq_str=tmp+qq_str;
tmp=BufToHex(buf,buflen);
qq_str=qq_str+CString("原始数据:\n")+tmp;
}
return nRet;
}
int CSniffer::GetQQHeader(char *buf,QQ_HEADER *hdr)
{
hdr->sCode=buf[0];
memcpy(&hdr->wVer,&buf[1],2);
hdr->wVer=ntohs(hdr->wVer);
memcpy(&hdr->wType,&buf[3],2);
hdr->wType=ntohs(hdr->wType);
memcpy(&hdr->wIndex,&buf[5],2);
hdr->wIndex=ntohs(hdr->wIndex);
if(hdr->sCode!=0x02){
return 0;
}
else{
return 1;
}
}
int CSniffer::DecodeGetToken(char *buf,int buflen,CString &qq_str,QQ_HEADER *qq_hdr)
{
DWORD qq_uid;
CString str;
BYTE token_len;
if(qq_hdr->wVer>=0x00ff){
if(buflen!=5||buf[4]!=0x00){
return 0;
}
memcpy(&qq_uid,buf,4);
qq_uid=htonl(qq_uid);
str.Format("QQ客户端请求登陆令牌,号码:%d\n",qq_uid);
qq_str=qq_str+str;
}
else{
if(buf[0]!=0x00){
return 0;
}
token_len=buf[1];
if(token_len!=buflen-2){
return 0;
}
str.Format("获得登录令牌,%d字节:\n%s\n",(unsigned char)token_len,BufToHex(&buf[1],token_len));
qq_str=qq_str+str;
}
return 1;
}
int CSniffer::DecodeLogin(char *buf,int buflen,CString &qq_str,QQ_HEADER *qq_hdr)
{
char key_rand[16];
DWORD uid;
CString str;
char *decrypted;
int outlen;
int nRet;
char pwdstring[16]; //密码校验串
char loginmode;//登陆模式
char logintoken[24];//登陆令牌
if(qq_hdr->wVer>0x0100){
if(buflen!=452){
return 0;
}
memcpy(&uid,buf,4);
memcpy(key_rand,&buf[4],16);
memcpy(m_key_rand,&buf[4],16);
uid=ntohl(uid);
outlen=432;
decrypted=new char[outlen];
nRet=qq_crypt(DECRYPT,(unsigned char *)&buf[20],432,(unsigned char *)key_rand,(unsigned char *)decrypted,&outlen);
if(nRet!=1){
outlen=432;
nRet=qq_crypt(DECRYPT,(unsigned char *)&buf[20],432,(unsigned char *)m_pwd_key,(unsigned char *)decrypted,&outlen);
if(nRet!=1){
delete decrypted;
return 0;
}
}
memcpy(pwdstring,decrypted,16);
loginmode=decrypted[52];
memcpy(logintoken,&decrypted[70],24);
str.Format("客户端请求登陆。\nQQ号码:%d,登录模式:0x%2.2X\n随机密钥:\n%s\n密码校验串:\n%s\n登录令牌:\n%s\n解密后字符串:\n%s\n",
uid,(unsigned char)loginmode,BufToHex(key_rand,16),BufToHex(pwdstring,16),BufToHex(logintoken,24),BufToHex(decrypted,outlen));
qq_str=str;
delete decrypted;
return 1;
}
if(buflen==24){ //重定向
outlen=24;
decrypted=new char[outlen];
nRet=qq_crypt(DECRYPT,(unsigned char *)&buf[0],24,(unsigned char *)m_key_rand,(unsigned char *)decrypted,&outlen);
if(nRet!=1){
outlen=24;
nRet=qq_crypt(DECRYPT,(unsigned char *)&buf[0],24,(unsigned char *)m_pwd_key,(unsigned char *)decrypted,&outlen);
if(nRet!=1){
delete decrypted;
return 0;
}
}
if(decrypted[0]!=0x01||outlen!=11){
delete decrypted;
return 0;
}
WORD port;
memcpy(&uid,&decrypted[1],4);
memcpy(&port,&decrypted[9],2);
port=ntohs(port);
uid=ntohl(uid);
str.Format("服务器重定向。\nQQ号码:%d\n服务器地址:%d.%d.%d.%d\n端口:%d\n解密后数据:%s\n",
uid,(unsigned char)decrypted[5],(unsigned char)decrypted[6],(unsigned char)decrypted[7],(unsigned char)decrypted[8],port,BufToHex(decrypted,outlen));
qq_str=str;
return 1;
}
if(buflen==160){
outlen=160;
decrypted=new char[outlen];
nRet=qq_crypt(DECRYPT,(unsigned char *)buf,160,(unsigned char *)m_key_rand,(unsigned char *)decrypted,&outlen);
if(nRet!=1){
outlen=160;
nRet=qq_crypt(DECRYPT,(unsigned char *)buf,160,(unsigned char *)m_pwd_key,(unsigned char *)decrypted,&outlen);
if(nRet!=1){
delete decrypted;
return 0;
}
}
if(decrypted[0]!=0x00){
delete decrypted;
return 0;
}
memcpy(m_key_session,&decrypted[1],16);//绘画密钥
memcpy(&uid,&decrypted[17],4);
uid=ntohl(uid);
unsigned char lastip[4];
memcpy(m_client_key,&decrypted[79],32);
memcpy(lastip,&decrypted[123],4);
str.Format("QQ登陆成功。\nQQ号码:%d,上次登陆IP:%d.%d.%d.%d\n会话密钥:\n%s\nClient Key:\n%s\n解密后数据:%s\n",
uid,lastip[0],lastip[1],lastip[2],lastip[3],BufToHex(m_key_session,16),BufToHex(m_client_key,32),BufToHex(decrypted,outlen));
qq_str=str;
delete decrypted;
return 1;
}
return 1;
}
int CSniffer::DecodeDefault(char *buf,int buflen,CString &qq_str,QQ_HEADER *qq_hdr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -