文章作者:SystEm32
/********************************************************************************
/*Tween Code by SystEm32
/*Zf35#citiz.net
/********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h> //I hacked winsock2.h ,add SIO_RCVALL to it,
//SIO_RCVALL always in mstcpip.h
#include <ws2tcpip.h>
#pragma comment(lib,"ws2_32")
#define SOURCE_PORT 6500
#define MAX_RECEIVEBYTE 255
#define xmalloc(s) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,(s))
typedef struct ip_hdr //定义IP首部
{
unsigned char h_verlen; //4位首部长度,4位IP版本号 1
unsigned char tos; //8位服务类型TOS 1
unsigned short total_len; //16位总长度(字节) 2
unsigned short ident; //16位标识 2
unsigned short frag_and_flags; //3位标志位 2
unsigned char ttl; //8位生存时间 TTL 1
unsigned char proto; //8位协议 (TCP, UDP 或其他) 1 //看上去为char,其实质是8bit的数字,最大255
unsigned short checksum; //16位IP首部校验和 2
unsigned int sourceIP; //32位源IP地址 4
unsigned int destIP; //32位目的IP地址 4
}IPHEADER; //总长度:20
typedef struct psd_hdr //定义TCP伪首部
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz;
char ptcl; //协议类型
unsigned short tcpl; //TCP长度
}PSDHEADER;
typedef struct tcp_hdr //定义TCP首部
{
USHORT th_sport; //16位源端口 2
USHORT th_dport; //16位目的端口 2
unsigned int th_seq; //32位序列号 4
unsigned int th_ack; //32位确认号 4
unsigned char th_lenres; //4位首部长度/6位保留字 1
unsigned char th_flag; //6位标志位/syn/ack/urg... 1
USHORT th_win; //16位窗口大小 2
USHORT th_sum; //16位校验和 2
USHORT th_urp; //16位紧急数据偏移量 2
}TCPHEADER; //总长度:20
//CheckSum:计算校验和的子函数
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);
}
DWORD dwBufferLen[10];
DWORD dwBufferInLen = 1;
DWORD dwBytesReturned = 0;
HANDLE bindthread;
char my_ip[30]={0};
int fport;
void Usage()
{
printf("Tween created by SystEm32 2003.8.30\n");
printf("Email:
SystEm32@hackbase.com\n");
printf("Usage: Tween -tcp -syn/ack <traget ip> <port> (/badcrc) \n");
}
DWORD WINAPI sniffer(PVOID no)
{
//int packsize = SNIFFER_ICMP_SIZE;
SOCKET socksniffer;
struct sockaddr_in dest,from;
struct hostent * hp;
int sread;
int fromlen = sizeof(from);
unsigned char LocalName[256];
char *recvbuf;
IPHEADER *Sip_hdr;
TCPHEADER *Stcp_hdr;
char R_FLAG[20]={0};
// 创建一个原始socket, 接受所有接收的包(sniffer)
if ((socksniffer = WSASocket(AF_INET, SOCK_RAW, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("WSASocket() failed: %d\n", WSAGetLastError());
return -1;
}
// 取得本地ip地址
gethostname((char*)LocalName, sizeof(LocalName)-1);
if((hp = gethostbyname((char*)LocalName)) == NULL)
{
return -1;
}
memset(&dest,0,sizeof(dest));
memcpy(&dest.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length);
//lstrcpy(my_ip,inet_ntoa(dest.sin_addr));
dest.sin_family = AF_INET;
dest.sin_port = htons(6666); // 指定任意端口
// socket bind
bind(socksniffer, (PSOCKADDR)&dest, sizeof(dest));
// 设置socket为接受所有包
WSAIoctl(socksniffer,SIO_RCVALL,&dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );
// 分配socket接收缓冲区大小为MAX_PACKET
recvbuf = (char *)xmalloc(1000);
//printf("Sniffer ok!");
// 循环监听包的大小
while(1)
{
// 读数据
//RtlZeroMemory(recvbuf,sizeof recvbuf);
sread = recvfrom(socksniffer, recvbuf, 1000, 0, (struct sockaddr*)&from, &fromlen);
// 如果读数据出错
if (sread == SOCKET_ERROR || sread < 0)
{
if (WSAGetLastError() == WSAETIMEDOUT)
{ printf("time out\n");
continue;
}
return -1;
}
// 如果读到数据的ipheader(20 bytes)+13偏移处为syn||ack(equ 18)
else if( (Sip_hdr->sourceIP) == dest.sin_addr.s_addr )
{
Sip_hdr = (IPHEADER *)(recvbuf);
if( IPPROTO_TCP == Sip_hdr->proto )
{
Stcp_hdr = (TCPHEADER *)(recvbuf+sizeof(TCPHEADER));
if(((Stcp_hdr->th_flag) & 64) == 64) lstrcat(R_FLAG,"E");
else lstrcat(R_FLAG,"_");
if(((Stcp_hdr->th_flag) & 32) == 32) lstrcat(R_FLAG,"U");
else lstrcat(R_FLAG,"_");
if(((Stcp_hdr->th_flag) & 16) == 16) lstrcat(R_FLAG,"A");
else lstrcat(R_FLAG,"_");
if(((Stcp_hdr->th_flag) & 8 ) == 8 ) lstrcat(R_FLAG,"P");
else lstrcat(R_FLAG,"_");
if(((Stcp_hdr->th_flag) & 4 ) == 4 ) lstrcat(R_FLAG,"R");
else lstrcat(R_FLAG,"_");
if(((Stcp_hdr->th_flag) & 2 ) == 2 ) lstrcat(R_FLAG,"S");
else lstrcat(R_FLAG,"_");
if(((Stcp_hdr->th_flag) & 1 ) == 1 ) lstrcat(R_FLAG,"F");
else lstrcat(R_FLAG,"_");
printf("PacketLen:%d IP:%s Tos:%u Port:%d\nflags=%s seq=%u ask=%u ttl=%d win=%d\n",
sread,inet_ntoa(from.sin_addr),Sip_hdr->tos,ntohs(Stcp_hdr->th_sport),
R_FLAG,ntohl(Stcp_hdr->th_seq),
ntohl(Stcp_hdr->th_ack),Sip_hdr->ttl,ntohs(Stcp_hdr->th_win));
RtlZeroMemory(R_FLAG,sizeof R_FLAG);
} //if( IPPROTO_TCP == Sip_hdr->proto) END
} //else END
} //while END
return 1;
}
////////////////////////////
int main(int argc, char* argv[])
{
WSADATA WSAData;
SOCKET sock;
SOCKADDR_IN addr_in,dest;
IPHEADER ipHeader;
TCPHEADER tcpHeader;
PSDHEADER psdHeader;
unsigned long threadrid;
USHORT countPort=1;
char host_ip[30]={0},host_name[30]={0};
struct hostent *hp2,*hp;
char szSendBuf[60]={0};
unsigned char LocalName[256];
BOOL flag;
int rect,nTimeOver;
char *fs;
//useage();
//argc==5是-UDP,argc==6是tcp
if (argc < 5 || argc >6)
{ Usage();
return false; }
if (WSAStartup(MAKEWORD(2,2), &WSAData)!=0)
{
printf("WSAStartup Error!\n");
return false;
}
//sniffer线程开始,Sleep(330)是为了在第一个包发出去之前,Sniffer能够开始工作
CreateThread(NULL,0,sniffer,NULL,0,&threadrid);
Sleep(330);
if ((sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)
{
printf("Socket Setup Error!\n");
return false;
}
flag=true;
if (setsockopt(sock,IPPROTO_IP, IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR)
{
printf("setsockopt IP_HDRINCL error!\n");
return false;
}
nTimeOver=1000;
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver))==SOCKET_ERROR)
{
printf("setsockopt SO_SNDTIMEO error!\n");
return false;
}
addr_in.sin_family=AF_INET;
//addr_in.sin_port=htons(atoi(argv[2]));
if(lstrcmp(argv[1],"-tcp") ==0 )
{
if( INADDR_NONE != inet_addr(argv[3]) )
{
lstrcpy(host_ip,argv[3]);
addr_in.sin_addr.S_un.S_addr=inet_addr(argv[3]);
//hp2 = gethostbyaddr(argv[3],4,AF_INET);
//lstrcpy(host_name,hp2->h_name);
}
else
{
printf("ssaa");
lstrcpy(host_name,argv[3]);
if((hp2 = gethostbyname((char*)argv[3])) == NULL)
{
printf("can't find host.\n");
return -1;
}
memcpy(host_ip, hp2->h_addr_list[0], hp2->h_length);
addr_in.sin_addr.S_un.S_addr=inet_addr(host_ip);
}
}
//
//
//填充IP首部
ipHeader.h_verlen=(4<<4 | sizeof(ipHeader)/sizeof(unsigned long));
// ipHeader.tos=0;
ipHeader.total_len=htons(sizeof(ipHeader)+sizeof(tcpHeader));
ipHeader.ident=1;
ipHeader.frag_and_flags=0;
ipHeader.ttl=128;
ipHeader.proto=IPPROTO_TCP;
ipHeader.checksum=0;
/////////////////////////////////////////////////////////
///////
gethostname((char*)LocalName, sizeof(LocalName)-1);
if((hp = gethostbyname((char*)LocalName)) == NULL)
{
return -1;
}
memset(&dest,0,sizeof(dest));
memcpy(&dest.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); // TCP嗅探选项
lstrcpy(my_ip,inet_ntoa(dest.sin_addr));
ipHeader.sourceIP=inet_addr(my_ip);
if(lstrcmp(argv[1],"-tcp") == 0) ipHeader.destIP=inet_addr(argv[3]);
if(lstrcmp(argv[1],"-udp") == 0) ipHeader.destIP=inet_addr(argv[2]);
//add other option here,just like -ICMP
//填充TCP首部
if(lstrcmp(argv[1],"-tcp") == 0)
{
tcpHeader.th_dport=htons(atoi(argv[4]));
tcpHeader.th_sport=htons(SOURCE_PORT); //源端口号
tcpHeader.th_seq=htonl(0x12345678); //seq,随便填
tcpHeader.th_ack=0;
tcpHeader.th_lenres=(sizeof(tcpHeader)/4<<4|0);
//根据选项实现不同的标志位探测,2是SYN,1是FIN...等等
if (lstrcmp(argv[2],"-fin") == 0) {tcpHeader.th_flag=1;fs="F";}
else if(lstrcmp(argv[2],"-syn") == 0) {tcpHeader.th_flag=2;fs="S";}
else if(lstrcmp(argv[2],"-rst") == 0) {tcpHeader.th_flag=4;fs="R";}
else if(lstrcmp(argv[2],"-psh") == 0) {tcpHeader.th_flag=8;fs="P";}
else if(lstrcmp(argv[2],"-ack") == 0) {tcpHeader.th_flag=16;fs="A";}
else if(lstrcmp(argv[2],"-urg") == 0) {tcpHeader.th_flag=32;fs="U";}
else if(lstrcmp(argv[2],"-res") == 0) {tcpHeader.th_flag=64;fs="E";}
else {printf("Bad Option: Must be fin/syn/rst/psh/ack/urg/res \n");}
tcpHeader.th_win=htons(512);
tcpHeader.th_urp=0;
tcpHeader.th_sum=0;
psdHeader.saddr=ipHeader.sourceIP;
psdHeader.daddr=ipHeader.destIP;
psdHeader.mbz=0;
psdHeader.ptcl=IPPROTO_TCP;
psdHeader.tcpl=htons(sizeof(tcpHeader));
memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));
memcpy(szSendBuf+sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));
//计算tcp校验和,如果设置了badCRC选项,则填充错误的CRC校验和
if(lstrcmp(argv[5],"/badcrc") == 0)
tcpHeader.th_sum=10;
else
tcpHeader.th_sum=checksum((USHORT *)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader));
memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf+sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader), 0, 4);
//计算ip校验和,如果设置了badCRC选项,则填充错误的CRC校验和
if(lstrcmp(argv[5],"/badcrc") == 0)
ipHeader.checksum=10;
else
ipHeader.checksum=checksum((USHORT *)szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader));
memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
rect=sendto(sock, szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader), 0, (struct sockaddr*)&addr_in, sizeof(addr_in));
if (rect==SOCKET_ERROR)
{
printf("send error!:%d\n",WSAGetLastError());
return -1;
}
else
{ printf("Sneie %s (rl0 %s): %s set,40 headers + 0 data bytes\n",
host_ip,host_name,fs);
}
}//if(lstrcmp(argv[1],"-tcp") == 0) END
//if( ....-udp) addcode here
Sleep(1000);
closesocket(sock);
WSACleanup();
return 0;
}