如何用C++编写简易端口扫描器(要详细步骤)
#includewinsock2.h
#includestdio.h
#include time.h//计时需要用到的头文件
#pragma comment(lib,"ws2_32.lib")
#include time.h//计时需要用到的头文件
clock_t start,end;//程序运行的起始和结束时间
float costtime;//程序耗时
void usage(void)
{
printf("\tusage: tcpscan RemoteIP StartPort-EndPort\n");
printf("\tExample: tcpscan 192.168.1.1 80-100\n");
}
int main(int argc,char **argv)
{
char *host;
int startport,endport;
char *p;
if(argc!=3)
{
usage();
return 0;
}
p=argv[2];//处理端口参数
if(strstr(argv[2],"-"))
{ startport=atoi(argv[2]);
for(;*p;)
if(*(p++)=='-')break;
endport=atoi(p);
if(startport1 || endport65535)
{ printf("Port Error!\n");
return 0;
}
}
host=argv[1];
WSADATA ws;
SOCKET s;
struct sockaddr_in addr;
int result;
long lresult;
lresult=WSAStartup(MAKEWORD(1,1), ws);
addr.sin_family =AF_INET;
addr.sin_addr.s_addr =inet_addr(host);
start=clock();//开始计时
for (int i=startport;iendport;i++)
{
s=socket(AF_INET, SOCK_STREAM, 0);
addr.sin_port = htons(i);
if(s==INVALID_SOCKET)break;
result=connect(s, (struct sockaddr*)addr,sizeof(addr));
if(result==0)
{
printf("%s %d\n",host,i);
closesocket(s);
}
}
end=clock();//计时结束
costtime= (float)(end - start) / CLOCKS_PER_SEC; //转换时间格式
printf("Cost time:%f second",costtime);//显示耗时
WSACleanup();
}
一段IP地址端口的扫描用C#怎么写代码
就你给的这点分,也想要问这样的问题....
这样的问题,得要给很多分的....
---------------
我也没有现成的代码,我给你说一下思路吧。
首先用线程实现。跟据你的任务数量。为每个线程分配任务(每个线程扫描多少个IP)。写一个公共的 *** 。这个 *** 里面就是你扫描的实现代码。至于你想扫描什么就写什么的代码。比如说你要PING远程就可以用PING类,测试远程计算机与你机机的连接。。
写完了,用线程调用这个 *** 就可以了。。
大概思路就是这样。
100分求linux下C语言端口扫描代码
linux tcp udp 端口扫描源程序
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h
#include unistd.h
#include errno.h
#include netdb.h
#include stdio.h
#include string.h
#include netinet/ip_icmp.h
#include stdlib.h
#include signal.h
#include libxml/parser.h
#include libxml/tree.h
#define TRUE 1
#define FALSE 0
#define UDP "UDP"
#define TCP "TCP"
#define tcp "tcp"
#define udp "udp"
typedef struct _GsSockStru{
int fd;
int len;
struct sockaddr_in addr;
}GsSockStru;
static int tcptest( char ip[32], char port[20]);
static int udptest( char ip[32], char port[20]);
void sig_alrm( int signo );
static GsSockStru test_sock;
int
main( int argc, char** argv)
{
char string[64];
char port[20];
char pro[20];
char ip[32];
int res;
int i = 0;
int k = 0;
if( argc2 || argc2 )
{
printf("鍙傛暟涓嶆纭?-1\n");
return ( -1 );
}
strcpy( string, argv[1]);
while( *string )
{
if( string[i] == ':' )
break;
pro[k] = string[i];
k++;
i++;
}
pro[k] = '\0';
i++;
k = 0;
while( *string )
{
if( string[i] == ':')
break;
ip[k] = string[i];
k++;
i++;
}
ip[k] = '\0';
i++;
k=0;
while( *string )
{
if( string[i] == '\0')
break;
port[k] = string[i];
k++;
i++;
}
port[k] = '\0';
i++;
memset( test_sock, 0, sizeof( test_sock ) );
if ( ( strcmp( TCP, pro) != 0 ) ( strcmp( UDP, pro) != 0 ) ( strcmp( tcp, pro) != 0 ) ( strcmp( udp, pro) != 0 ))
{
printf ( "鍙傛暟涓嶆纭?锛?\n" );
return (-1);
}
if ( strcmp( TCP, pro) == 0 || strcmp( tcp, pro) == 0 )
res = tcptest( ip, port );
if ( strcmp( UDP, pro) == 0 || strcmp( udp, pro) == 0 )
res = udptest( ip, port );printf("%d\n",res);
return ( res );
}
int
tcptest( char ip[32], char port[20])
{
int res;
struct timeval tv;
test_sock.fd = socket( AF_INET, SOCK_STREAM, 0 );
if ( test_sock.fd 0 )
{
printf( "create socket failed -3 \n" );
return ( -3 );
}
memset( ( test_sock.addr ), 0, sizeof( test_sock.addr ) );
test_sock.addr.sin_family = AF_INET;
test_sock.addr.sin_port = htons( atoi( port ) );
inet_pton( AF_INET, ip, test_sock.addr.sin_addr );
test_sock.len = sizeof( struct sockaddr );
tv.tv_sec = 10;
tv.tv_usec = 0;
setsockopt( test_sock.fd, SOL_SOCKET, SO_RCVTIMEO,
(const char *)tv, sizeof( tv ) );
res = connect( test_sock.fd,
( struct sockaddr * )( ( test_sock.addr ) ),
test_sock.len );
if ( res 0 )
{
fprintf( stderr, "connect failed 0\n" );
close( test_sock.fd );
return FALSE;
}
close( test_sock.fd );
return TRUE;
}
int udptest( char ip[32], char port[20])
{
struct icmphdr *icmp_header;
struct sockaddr_in target_info;
int target_info_len;
fd_set read_fd;
int scan_port;
char recvbuf[5000];
struct sockaddr_in target_addr;
int icmp_socket;
int udp_socket;
struct timeval tv;
icmp_header = (struct icmphdr *)(recvbuf+sizeof(struct iphdr));
scan_port = atoi( port );
target_addr.sin_family = AF_INET;
inet_pton( AF_INET, ip, target_addr.sin_addr );
target_addr.sin_port = htons(scan_port);
if ((udp_socket=socket(AF_INET,SOCK_DGRAM,0))==-1)
{
printf("create socket failed -3\n");
return -3;
}
if ((icmp_socket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))==-1)
{
printf("Create raw socket failed -3\n");
return -3;
}
sendto(udp_socket,NULL,0,0,(void *)target_addr,sizeof(target_addr));
FD_ZERO(read_fd);
FD_SET(icmp_socket,read_fd);
tv.tv_sec = 1;
tv.tv_usec = 0;
select(FD_SETSIZE,read_fd,NULL,NULL,tv);
for (;;){
if (FD_ISSET(icmp_socket,read_fd))
{
target_info_len = sizeof(target_info);
recvfrom(icmp_socket,recvbuf,5000,0,
(struct sockaddr *)target_info,target_info_len);
if (target_info.sin_addr.s_addr == target_addr.sin_addr.s_addr
icmp_header-type == 3 icmp_header-code=12)
{
printf("Port %d : Close\n",scan_port);
return (0);
}
}
return (1) ;
}
}
用C++编写端口扫描程序
#include stdio.h
#include winsock.h
#define NETWORK_ERROR -1
#define NETWORK_OK 0
#define PORT_MIN 1
#define PORT_MAX 65535
HANDLE hThread;
DWORD hID;
char hostname[30];
int starting_port = 0;
int ending_port = 0;
int nopen = 0;
DWORD portscan();
int main(){
int ret;
WSADATA dat;
DWORD version;
version = MAKEWORD(2,2);
ret = WSAStartup(version,dat);
if(ret != 0){
printf("Error initializing Winsock.\n");
WSACleanup();
return NETWORK_ERROR;
}
if(ret == 0){
printf("Enter hostname:");
scanf("%s",hostname);
printf("Enter starting port:");
scanf("%d",starting_port);
if(starting_port PORT_MIN){
printf("Invalid port number.\n");
WSACleanup();
return NETWORK_ERROR;
}
printf("Enter ending port:");
scanf("%d",ending_port);
if(ending_port PORT_MAX){
printf("Invalid port number.\n");
WSACleanup();
return NETWORK_ERROR;
}
printf("\nScanning [%s]...\n",hostname);
hThread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)portscan,0,0,hID);
if(hThread == 0){
printf("Failed to create thread.\n");
WSACleanup();
return NETWORK_ERROR;
}
sleep(-1);
}
WSACleanup();
return NETWORK_OK;
}
DWORD portscan(){
int i,nret;
SOCKET thesocket;
LPHOSTENT hostent;
thesocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
hostent = gethostbyname((hostname));
for(i = starting_port;i ending_port+1;++i){
SOCKADDR_IN hostinfo;
hostinfo.sin_family = AF_INET;
hostinfo.sin_addr=*((LPIN_ADDR)*hostent-h_addr_list);
hostinfo.sin_port = htons(i);
nret = connect(thesocket,(LPSOCKADDR)hostinfo,sizeof(hostinfo));
if(nret == 0){
printf("\n\t%d\n",i);
++nopen;
}
}
printf("\nScan complete.\n\n");
printf("Number of ports opened = %d\n",nopen);
closesocket(thesocket);
}
渗透测试之端口扫描
端口扫描:端口对应 *** 服务及应用端程序
服务端程序的漏洞通过端口攻入
发现开放的端口
更具体的攻击面
UDP端口扫描:
如果收到ICMP端口不可达,表示端口关闭
如果没有收到回包,则证明端口是开放的
和三层扫描IP刚好相反
Scapy端口开发扫描
命令:sr1(IP(dst="192.168.45.129")/UDP(dport=53),timeout=1,verbose=1)
nmap -sU 192.168.45.129
TCP扫描:基于连接的协议
三次握手:基于正常的三次握手发现目标是否在线
隐蔽扫描:发送不完整的数据包,不建立完整的连接,如ACK包,SYN包,不会在应用层访问,
僵尸扫描:不和目标系统产生交互,极为隐蔽
全连接扫描:建立完整的三次握手
所有的TCP扫描方式都是基于三次握手的变化来判断目标系统端口状态
隐蔽扫描:发送SYN数据包,如果收到对方发来的ACK数据包,证明其在线,不与其建立完整的三次握手连接,在应用层日志内不记录扫描行为,十分隐蔽, *** 层审计会被发现迹象
僵尸扫描:是一种极其隐蔽的扫描方式,实施条件苛刻,对于扫描发起方和被扫描方之间,必须是需要实现地址伪造,必须是僵尸机(指的是闲置系统,并且系统使用递增的IPID)早期的win xp,win 2000都是递增的IPID,如今的LINUX,WINDOWS都是随机产生的IPID
1,扫描者向僵尸机发送SYN+ACY,僵尸机判断未进行三次握手,所以返回RST包,在RST数据包内有一个IPID,值记为X,那么扫描者就会知道被扫描者的IPID
2,扫描者向目标服务器发送SYN数据包,并且伪装源地址为僵尸机,如果目标服务器端口开放,那么就会向僵尸机发送SYN+ACK数据包,那么僵尸机也会发送RST数据包,那么其IPID就是X+1(因为僵尸机足够空闲,这个就为其收到的第二个数据包)
3,扫描者再向僵尸机发送SYN+ACK,那么僵尸机再次发送RST数据包,IPID为X+2,如果扫描者收到僵尸机的IPID为X+2,那么就可以判断目标服务器端口开放
使用scapy发送数据包:首先开启三台虚拟机,
kali虚拟机:192.168.45.128
Linux虚拟机:192.168.45.129
windows虚拟机:192.168.45.132
发送SYN数据包:
通过抓包可以查看kali给linux发送syn数据包
linux虚拟机返回Kali虚拟机SYN+ACK数据包
kali系统并不知道使用者发送了SYN包,而其莫名其妙收到了SYN+ACK数据包,便会发RST包断开连接
也可以使用下列该命令查看收到的数据包的信息,收到对方相应的SYN+ACK数据包,scapy默认从本机的80端口往目标系统的20号端口发送,当然也可以修改
如果向目标系统发送一个 随机端口:
通过抓包的获得:1,kali向linux发送SYN数据包,目标端口23456,
2,Linux系统由自己的23456端口向kali系统的20号端口返回RST+ACK数据包,表示系统端口未开放会话结束
使用python脚本去进行scapy扫描
nmap做隐蔽端口扫描:
nmap -sS 192.168.45.129 -p 80,21,110,443 #扫描固定的端口
nmap -sS 192.168.45.129 -p 1-65535 --open #扫描该IP地址下1-65535端口扫描,并只显示开放的端口
nmap -sS 192.168.45.129 -p --open #参数--open表示只显示开放的端口
nmap -sS -iL iplist.txt -p 80
由抓包可知,nmap默认使用-sS扫描,发送SYN数据包,即nmap=nmap -sS
hping3做隐蔽端口扫描:
hping3 192.168.45.129 --scan 80 -S #参数--scan后面接单个端口或者多个端口.-S表示进行SYN扫描
hping3 192.168.45.129 --scan 80,21,25,443 -S
hping3 192.168.45.129 --scan 1-65535 -S
由抓包可得:
hping3 -c 100 -S --spoof 192.168.45.200 -p ++1 192.168.45.129
参数-c表示发送数据包的数量
参数-S表示发送SYN数据包
--spoof:伪造源地址,后面接伪造的地址,
参数-p表示扫描的端口,++1表示每次端口号加1,那么就是发送SYN从端口1到端口100
最后面跟的是目标IP
通过抓包可以得知地址已伪造,但对于linux系统(192.168.45.129)来说,它收到了192.168.45.200的SYN数据包,那么就会给192.168.45.200回复SYN+ACK数据包,但该地址却是kali伪造的地址,那么要查看目标系统哪些端口开放,必须登陆地址为kali伪造的地址即(192.168.45.200)进行抓包
hping3和nmap扫描端口的区别:1,hping3结果清晰明了
2,nmap首先对IP进行DNS反向解析,如果没成功,那么便会对其端口发送数据包,默认发送SYN数据包
hping3直接向目标系统的端口发送SYN数据包,并不进行DNS反向解析
全连接端口扫描:如果单独发送SYN数据包被被过滤,那么就使用全连接端口扫描,与目标建立三次握手连接,结果是最准确的,但容易被入侵检测系统发现
response=sr1(IP(dst="192.168.45.129")/TCP(dport=80,flags="S"))
reply=sr1(IP(dst="192.168.45.129")/TCP(dport=80,flags="A",ack=(response[TCP].seq+1)))
抓包情况:首先kali向Linux发送SYN,Linux回复SYN+ACK给kali,但kali的系统内核不清楚kali曾给linux发送给SYN数据包,那么kali内核莫名其妙收到SYN+ACK包,那么便会返回RST请求断开数据包给Linux,三次握手中断,如今kali再给Linux发ACK确认数据包,Linux莫名其妙收到了ACK数据包,当然也会返回RST请求断开数据包,具体抓包如下:
那么只要kali内核在收到SYN+ACK数据包之后,不发RST数据包,那么就可以建立完整的TCP三次握手,判断目标主机端口是否开放
因为iptables存在于Linux内核中,通过iptables禁用内核发送RST数据包,那么就可以实现
使用nmap进行全连接端口扫描:(如果不指定端口,那么nmap默认会扫描1000个常用的端口,并不是1-1000号端口)
使用dmitry进行全连接端口扫描:
dmitry:功能简单,但功能简便
默认扫描150个最常用的端口
dmitry -p 192.168.45.129 #参数-p表示执行TCP端口扫描
dmitry -p 192.168.45.129 -o output #参数-o表示把结果保存到一个文本文档中去
使用nc进行全连接端口扫描:
nc -nv -w 1 -z 192.168.45.129 1-100: 1-100表示扫描1-100号端口
参数-n表示不对Ip地址进行域名解析,只把其当IP来处理
参数-v表示显示详细信息
参数-w表示超时时间
-z表示打开用于扫描的模式
0条大神的评论