TCP端口扫描方法整理 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
TCP端口扫描方法整理 tcp端口扫描攻击

#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;

}

  

爱华网本文地址 » http://www.413yy.cn/a/25101011/63147.html

更多阅读

[技术贴]怎样清除电脑里面的快压软件 wps里面清除格式

[方法整理于网络,个人血泪经验。。。(┬_┬) ]这里说的清除方法是针对当你明明在控制面板、控制面板、金山卫士、360安全卫士、QQ电脑管家各种删除程序软件上删除了,当你明明在控制面板、控制面板、金山卫士、360安全

如何选择架子鼓 架子鼓买什么样的好

打击乐作为音乐里越来越特别的一种形式,在全世界越来越受重视,同时,打击乐器也越来越讲究和追求高品质多样化。我们国家的打击乐发展相对还较为缓慢和落后一些。下面的资料是通过长期的资料搜集,结合亲身体会,看到,听到,摸索到的经验,用了7

骨髓穿刺术的操作方法 骨髓穿刺

2011-04-22 15:33 来源 爱爱医分享到: 骨髓穿刺术的操作方法是临床医师实践技能考试要求掌握的内容,也是临床常用的基本技能,临床人员应掌握,现将骨髓穿刺术的操作方法整理如下,以供执考人员参考:1.选择穿刺部位①髂前上棘穿刺点:位于髂前

声明:《TCP端口扫描方法整理 tcp端口扫描攻击》为网友号少年分享!如侵犯到您的合法权益请联系我们删除