TCP端口扫描方法整理 tcp端口扫描攻击
TCP扫描的主要原理: RFC793中TCP连接建立的三次握手过程,以及RST报文段的产生条件等
常见的TCP扫描方法有:
1.TCP connect scan
这种方法最简单,直接连到目标端口并完成一个完整的三次握手过程(SYN, SYN/ACK, 和ACK)。缺点是容易被目标系统检测到。
2.TCP SYN scan
这种扫描方式也被称为"半打开扫描"(half-open scanning)。它利用了TCP连接建立三次握手的第一步,并且没有建立一个完整的TCP连接。实现办法是向远端主机某端口发送一个只有SYN标志位的TCP报文段,如果主机反馈一个SYN|ACK数据包,那么,这个主机正在监听该端口,如果反馈的是RST数据包,说明,主机没有监听该端口。在X-Scanner扫描工具上就有SYN的选择项。
3.TCP FIN scan
这种方法向目标端口发送一个FIN分组。按RFC793的规定,对于所有关闭的端口,目标系统应该返回RST标志。这种方法通常用在基于UNIX的TCP/IP协议栈。
4.TCP ACK scan
发送一个只有ACK标志的TCP数据报给主机,如果主机反馈一个TCP RST数据报来,那么这个主机是存在的。也可以通过这种技术来确定对方防火墙是否是简单的分组过滤,还是一个基于状态的防火墙。
5.TCP SYN|ACK scan
6.TCP NULL sacn(turn off all flags)
即发送一个没有任何标志位的TCP包,根据RFC793,如果目标主机的相应端口是关闭的话,应该发送回一个RST数据包。
7.TCP Xmas Tree scan(set all flags)
向目标主机发送一个FIN+URG+PUSH分组,根据RFC793,如果目标主机的相应端口是关闭的,那么应该返回一个RST标志。
8.TCP reverse identd scanning
identd protocol (rfc1413): disclose the username of the owner of any process connected via TCP, even if that process didn't initiate the connection.
Example: connect to the http port (80), and then use identd to find out whether the server is running as root.
该方法的缺点是必须建立连接,隐蔽性较差.
下面是一个TCP SYN扫描程序.
程序有两个子线程,SendThread用于发送SYN报文段,RecvThread用于接收SYN|ACK报文段,并从中获取相应的处于LISTEN状态的端口.
//该程序通过raw socket发送TCP报文段
//开发&运行环境: VC6.0 + SDK + Win2000
#include <ws2tcpip.h>
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#define RECV_BUF_SIZE 1024; //receiving buffer size
#define SOURCE_PORT 8088 //local TCP segment source port
#define TCP_RTT 2000 //Round-trip time,in milliseconds
typedef struct _iphdr
{
unsigned char h_verlen;
unsigned char tos;
unsigned short total_len;
unsigned short ident;
unsigned short frag_and_flags;
unsigned char ttl;
unsigned char proto;
unsigned short checksum;
unsigned int sourceIP;
unsigned int destIP;
}IP_HEADER;
typedef struct _psdhdr //定义TCP伪首部
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz;
char ptcl; //协议类型
unsigned short tcpl; //TCP长度
}PSD_HEADER;
// Standard TCP flags
#define URG 0x20
#define ACK 0x10
#define PSH 0x08
#define RST 0x04
#define SYN 0x02
#define FIN 0x01
typedef struct _tcphdr //定义TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
unsigned int th_seq; //32位序列号
unsigned int th_ack; //32位确认号
unsigned char th_lenres; //4位首部长度/6位保留字
unsigned char th_flag; //6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
}TCP_HEADER;
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 useage()
{
printf("TCP SYN Port Scannern");
printf("t Email : moogates@163.netn");
printf("t Useage: *.exe Target_ip [start_port] [end_port].n");
}
SOCKET g_sock; //用于收发TCP报文段的全局socket
hostent* g_pHost;
unsigned int g_nStartPort,g_nEndPort;
void RecvThread(char* sAddr)
{
char RecvBuf[RECV_BUF_SIZE];
IP_HEADER* ip;
TCP_HEADER * tcp;
while(1)
{
int ret = recv(g_sock, RecvBuf, RECV_BUF_SIZE, 0);
if (ret > 0)
{
ip = (IP_HEADER*)RecvBuf;
tcp = (TCP_HEADER*)(RecvBuf + (ip->h_verlen&0x0f)*4);
if(ip->proto!=IPPROTO_TCP)
continue;
if( strcmp(sAddr,inet_ntoa(*(in_addr*)&ip->sourceIP) ) )
continue;
if(tcp->th_flag&SYN && tcp->th_flag&ACK)
printf("Port %6u OPEN.n",ntohs(tcp->th_sport));
}
}
}
void SendThread(char* sAddr)
{
SOCKADDR_IN addr_dst;
char szSendBuf[60] = {0};
IP_HEADER ipHeader;
TCP_HEADER tcpHeader;
PSD_HEADER psdHeader;
//要发送的目的地址
addr_dst.sin_family = AF_INET;
addr_dst.sin_addr.S_un.S_addr = inet_addr(sAddr);
//填充IP首部
ipHeader.h_verlen = (4<<4 | sizeof(ipHeader)/4);
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.sourceIP = *(int*)g_pHost->h_addr_list[0];
ipHeader.destIP = inet_addr(sAddr);
//填充TCP首部
tcpHeader.th_sport = htons( SOURCE_PORT ); //源端口号
tcpHeader.th_seq = htonl( 0x12345678 );
tcpHeader.th_ack = 0;
tcpHeader.th_lenres = (sizeof(tcpHeader)/4<<4|0);
tcpHeader.th_flag = SYN;//发送SYN报文段
tcpHeader.th_win = htons(512);
tcpHeader.th_urp = 0;
psdHeader.saddr = ipHeader.sourceIP;
psdHeader.daddr = ipHeader.destIP;
psdHeader.mbz = 0;
psdHeader.ptcl = IPPROTO_TCP;
psdHeader.tcpl = htons(sizeof(tcpHeader));
for(unsigned int nPort=g_nStartPort; nPort {
ipHeader.checksum = 0;
tcpHeader.th_sum = 0;
tcpHeader.th_dport = htons( nPort );
//计算TCP校验和
memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));
memcpy(szSendBuf+sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));
tcpHeader.th_sum = checksum((USHORT *)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader));
//计算IP校验和
memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf+sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader), 0, 4);
ipHeader.checksum = checksum((USHORT *)szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader));
memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
addr_dst.sin_port = htons( nPort );
int ret = sendto(g_sock, szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader),
0, (struct sockaddr*)&addr_dst, sizeof(addr_dst) );
}
//等待一个合适的RTT周期.RTT太小可能导致被扫描主机端口的SYN|ACK报文来不及接收
Sleep(TCP_RTT);
}
int main(int argc,char* argv[])
{
if (argc<2)
{
useage();
return 0;
}
WSADATA WSAData;
if (WSAStartup(MAKEWORD(2,2), &WSAData)!=0)
{
printf("WSAStartup Error!n");
return -1;
}
if ((g_sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)
{
printf("Socket Setup Error!n");
return -1;
}
BOOL flag = true;
//包含IP头部,即程序自己封装IP头部,接收的数据报中也包含IP头部
if (setsockopt(g_sock,IPPROTO_IP, IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR)
{
printf("setsockopt IP_HDRINCL error!n");
return -1;
}
//将本主机的IP地址赋给源IP
char sLocalName[64];
gethostname((char*)sLocalName, sizeof(sLocalName)-1);
g_pHost = gethostbyname(sLocalName);
// 填充SOCKADDR_IN结构
sockaddr_in addr_local;
addr_local.sin_addr = *(in_addr *)g_pHost->h_addr_list[0]; //绑定到本地网卡,INADDR_ANY不行
addr_local.sin_family = AF_INET;
addr_local.sin_port = htons(SOURCE_PORT);
// 把原始套接字sock 绑定到本地网卡地址上
if( bind(g_sock, (PSOCKADDR)&addr_local, sizeof(sockaddr_in))==SOCKET_ERROR )
{
printf("Bind Error:%d.n",WSAGetLastError());
WSACleanup();
return -1;
}
// 设置SOCK_RAW为SIO_RCVALL(混合模式),以便接收所有的IP包.
DWORD dwValue = 1;
ioctlsocket(g_sock, SIO_RCVALL, &dwValue); // dwValue为1时执行,0时取消
//发送超时计时
int nTimeOut = 500;
if (setsockopt(g_sock,SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOut, sizeof(nTimeOut))==SOCKET_ERROR)
{
printf("setsockopt SO_SNDTIMEO error!n");
return -1;
}
g_nStartPort= argc>=3 ? atoi(argv[2]) : 1;
g_nEndPort = argc>=4 ? atoi(argv[3]) : 65535;
printf("Scanning %s from port %d to %d...n",argv[1],g_nStartPort,g_nEndPort);
HANDLE threads[2];
threads[0] = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)RecvThread,
(LPVOID)argv[1],
0,
NULL);
threads[1] = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)SendThread,
(LPVOID)argv[1], //destination IP address
0,
NULL);
WaitForMultipleObjects(2,threads,FALSE,INFINITE);
printf("Scan complete.n",argv[1],g_nStartPort,g_nEndPort);
closesocket(g_sock);
WSACleanup();
return 0;
}
更多阅读
解决:此Apple ID尚未在App(或iTunes) Store使用 此id尚未在itunes使用
解决:此Apple ID尚未在App(或iTunes) Store使用——简介 遇到这问题的朋友,应该大多和我一样,是在apple官网注册的账号。 我想将苹果本本,直接升级至巨浪(Mavericks)版,但就被这问题纠缠了我昨日一整天。 网上找的方法,要么不
[技术贴]怎样清除电脑里面的快压软件 wps里面清除格式
[方法整理于网络,个人血泪经验。。。(┬_┬) ]这里说的清除方法是针对当你明明在控制面板、控制面板、金山卫士、360安全卫士、QQ电脑管家各种删除程序软件上删除了,当你明明在控制面板、控制面板、金山卫士、360安全
全国医保卡余额查询(上海_北京_深圳_重庆) 深圳医保卡余额为0
国家健康保险卡余额查询方法 (整理)最新的注意:应该大多数的用户了解卫生保健信息迫切,医疗查询整理,如果有错误请联系客服来纠正;北京卫生保健卡余额查询在线北京暂时还没有开放查询在网上,可以选择电话咨询和门北京医疗保险定点医
如何选择架子鼓 架子鼓买什么样的好
打击乐作为音乐里越来越特别的一种形式,在全世界越来越受重视,同时,打击乐器也越来越讲究和追求高品质多样化。我们国家的打击乐发展相对还较为缓慢和落后一些。下面的资料是通过长期的资料搜集,结合亲身体会,看到,听到,摸索到的经验,用了7
骨髓穿刺术的操作方法 骨髓穿刺
2011-04-22 15:33 来源 爱爱医分享到: 骨髓穿刺术的操作方法是临床医师实践技能考试要求掌握的内容,也是临床常用的基本技能,临床人员应掌握,现将骨髓穿刺术的操作方法整理如下,以供执考人员参考:1.选择穿刺部位①髂前上棘穿刺点:位于髂前