求IP端口扫描器的VB源码
'4个TEXTBOX控件,2个COMMANDBUTTON控件,一个WINSOCK控件
Dim portnum As Long
Dim start As String
Sub scanningports()
Dim porttwo As Long
portnum = Text1.Text
porttwo = Text2.Text
Command2.Enabled = True
On Error GoTo viriio
Do
portnum = portnum + 1
DoEvents
If start = True Then
'关闭当前WINSOCK
Winsock1.Close
'防止系统冻结
DoEvents
Winsock1.LocalPort = portnum
DoEvents
Text3.Text = portnum
Winsock1.Listen
DoEvents
Else
portnum = 0
Command1.Enabled = True
Text1.Locked = False
Text2.Locked = False
Exit Sub
End If
Winsock1.Close
DoEvents
Loop Until portnum = porttwo
portnum = 0
Command1.Enabled = True
logport.Text = logport.Text vbCrLf "Scanning Ports Done!" vbCrLf
Text1.Locked = False
Text2.Locked = False
viriio:
If Err.Number = 10048 Then
logport.Text = logport.Text vbCrLf "端口" Winsock1.LocalPort " 开启中"
Resume Next
End If
End Sub
Private Sub Command1_Click()
Command2.Enabled = True
If Text1.Text = "" Then
MsgBox "你必须指定开始端口号!"
Exit Sub
End If
If Text2.Text = "" Then
MsgBox "你必须指定一个结束端口号"
Exit Sub
End If
Text1.Locked = True
Text2.Locked = True
Command1.Enabled = False
Winsock1.Close
start = True
Call scanningports
logport.Text = logport.Text vbCrLf "端口" Text1.Text "- " Text3.Text " 已经成功扫描!"
End Sub
Private Sub Command2_Click()
Command2.Enabled = False
start = False
End Sub
fscan:一键自动化、全方位漏洞扫描的开源工具
fscan 是一个内网综合扫描工具,方便一键自动化、全方位漏洞扫描。
它支持主机存活探测、端口扫描、常见服务的爆破、ms17010、redis批量写公钥、计划任务反弹shell、读取win网卡信息、web指纹识别、web漏洞扫描、netbios探测、域控识别等功能。
源码链接:
1.信息搜集:
2.爆破功能:
3.系统信息、漏洞扫描:
4.Web探测功能:
5.漏洞利用:
6.其他功能:
简单用法
其他用法
编译命令
完整参数
这个项目的开发者参考的开源项目有这些:
那里有端口扫描器的源代码程序
#include string.h
#include winsock.h
#include windows.h
#include iostream.h
#pragma comment (lib,"ws2_32.lib")
int main (int argc, char *argv[])
{
int iportFrom,iportTo;
int testsocket;
int iopenedport = 0;
struct sockaddr_in target_addr;
WSADATA wsaData;
WORD wVersionRequested=MAKEWORD(1,1);
if (argc = 3)
{
cout "使用格式 : " argv[0] " 主机IP地址 开始端口号 结束端口号\n" endl;
exit(1);
}
if (atoi (argv[2]) atoi (argv[3]))
{
cout "错误!开始端口号必须小于结束端口号" endl;
exit(1);
}
else
{
if (WSAStartup (wVersionRequested , wsaData) )
{
cout "连接socket库失败,请检查版本号是否为1.1\n" endl;
exit(1);
}
iportFrom=atoi (argv[2]);
iportTo=atoi (argv[3]);
for (int i=iportFrom; i = iportTo; i++)
{
cout "正在建立socket................................" endl;
if ((testsocket=socket (AF_INET,SOCK_STREAM,0) ) == INVALID_SOCKET)
{
cout "Socket建立失败!" endl;
exit(0);
}
target_addr.sin_family = AF_INET;
target_addr.sin_port = htons(i);
target_addr.sin_addr.s_addr = inet_addr (argv[1]);
cout "正在扫描端口:" i endl;
if (connect (testsocket, (struct sockaddr *) target_addr, sizeof(struct sockaddr)) == SOCKET_ERROR)
cout "端口" i "关闭!" endl;
else
{
iopenedport++;
cout "端口" i "开放\n" endl;
}
}
cout "目标主机" argv[1] "从" iportFrom "--" iportTo "共有" iopenedport "个端口开放" endl;
closesocket (testsocket);
WSACleanup();
}
return 0;
}
vc6.0 下 编译
设计一个判断端口是否开启的扫描器程序的源代码怎么写?
for(int i=0;i6;i++)
{
for(int j=0;j10;j++)
{
theport[j].rmt_host=rmt_host;
theport[j].p=port[i*10+j];
theport[j].n=j;
Thread[j]=AfxBeginThread(pScan,(LPVOID)theport[j]);
//启动端口扫描线程
hThread[j]=Thread[j]-m_hThread;
Sleep(1);
}
WaitForMultipleObjects(10,hThread,TRUE,120000);
}
//扫描模块代码
SOCKET sockfd;
SOCKADDR_IN addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd 0)
{
exit(0);
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(rmt_host);
int r = connect(sockfd,(struct sockaddr *) addr, sizeof(addr));
//尝试连接端口进行检测
closesocket(sockfd);
//连接返回值处理
if (r!=-1)
{
::PostMessage(hWnd,WM_DISPLAY,port,0);
}
//显示端口扫描结果
LONG CScanDlg::OnDisplay(LONG lParam, UINT wParam)
{
LPSERVENT bar;
CString open;
int p=lParam;
bar = getservbyport(htons(p),"tcp");
open.Format("\t%d号端口(%s)开放!\r\n",p,(bar == NULL) ? "未知" :
bar-s_name);
m_HistoryEdit.AppendString (open);
return 0;
}
如何用Scapy写一个端口扫描器
常见的端口扫描类型有:
1. TCP 连接扫描
2. TCP SYN 扫描(也称为半开放扫描或stealth扫描)
3. TCP 圣诞树(Xmas Tree)扫描
4. TCP FIN 扫描
5. TCP 空扫描(Null)
6. TCP ACK 扫描
7. TCP 窗口扫描
8. UDP 扫描
下面先讲解每种扫描的原理,随后提供具体实现代码。
TCP 连接扫描
客户端与服务器建立 TCP 连接要进行一次三次握手,如果进行了一次成功的三次握手,则说明端口开放。
客户端想要连接服务器80端口时,会先发送一个带有 SYN 标识和端口号的 TCP 数据包给服务器(本例中为80端口)。如果端口是开放的,则服务器会接受这个连接并返回一个带有 SYN 和 ACK 标识的数据包给客户端。随后客户端会返回带有 ACK 和 RST 标识的数据包,此时客户端与服务器建立了连接。如果完成一次三次握手,那么服务器上对应的端口肯定就是开放的。
当客户端发送一个带有 SYN 标识和端口号的 TCP 数据包给服务器后,如果服务器端返回一个带 RST 标识的数据包,则说明端口处于关闭状态。
代码:
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=80
tcp_connect_scan_resp = sr1(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="S"),timeout=10)
if(str(type(tcp_connect_scan_resp))=="type 'NoneType'"):
print "Closed"
elif(tcp_connect_scan_resp.haslayer(TCP)):
if(tcp_connect_scan_resp.getlayer(TCP).flags == 0x12):
send_rst = sr(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="AR"),timeout=10)
print "Open"
elif (tcp_connect_scan_resp.getlayer(TCP).flags == 0x14):
print "Closed"
TCP SYN 扫描
这个技术同 TCP 连接扫描非常相似。同样是客户端向服务器发送一个带有 SYN 标识和端口号的数据包,如果目标端口开发,则会返回带有 SYN 和 ACK 标识的 TCP 数据包。但是,这时客户端不会返回 RST+ACK 而是返回一个只带有 RST 标识的数据包。这种技术主要用于躲避防火墙的检测。
如果目标端口处于关闭状态,那么同之前一样,服务器会返回一个 RST 数据包。
代码:
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=80
stealth_scan_resp = sr1(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="S"),timeout=10)
if(str(type(stealth_scan_resp))=="type 'NoneType'"):
print "Filtered"
elif(stealth_scan_resp.haslayer(TCP)):
if(stealth_scan_resp.getlayer(TCP).flags == 0x12):
send_rst = sr(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="R"),timeout=10)
print "Open"
elif (stealth_scan_resp.getlayer(TCP).flags == 0x14):
print "Closed"
elif(stealth_scan_resp.haslayer(ICMP)):
if(int(stealth_scan_resp.getlayer(ICMP).type)==3 and int(stealth_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print "Filtered"
TCP 圣诞树(Xmas Tree)扫描
在圣诞树扫描中,客户端会向服务器发送带有 PSH,FIN,URG 标识和端口号的数据包给服务器。如果目标端口是开放的,那么不会有任何来自服务器的回应。
如果服务器返回了一个带有 RST 标识的 TCP 数据包,那么说明端口处于关闭状态。
但如果服务器返回了一个 ICMP 数据包,其中包含 ICMP 目标不可达错误类型3以及 ICMP 状态码为1,2,3,9,10或13,则说明目标端口被过滤了无法确定是否处于开放状态。
代码:
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=80
xmas_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="FPU"),timeout=10)
if (str(type(xmas_scan_resp))=="type 'NoneType'"):
print "Open|Filtered"
elif(xmas_scan_resp.haslayer(TCP)):
if(xmas_scan_resp.getlayer(TCP).flags == 0x14):
print "Closed"
elif(xmas_scan_resp.haslayer(ICMP)):
if(int(xmas_scan_resp.getlayer(ICMP).type)==3 and int(xmas_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print "Filtered"
TCP FIN扫描
FIN 扫描会向服务器发送带有 FIN 标识和端口号的 TCP 数据包。如果没有服务器端回应则说明端口开放。
如果服务器返回一个 RST 数据包,则说明目标端口是关闭的。
如果服务器返回了一个 ICMP 数据包,其中包含 ICMP 目标不可达错误类型3以及 ICMP 代码为1,2,3,9,10或13,则说明目标端口被过滤了无法确定端口状态。
代码:
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=80
fin_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="F"),timeout=10)
if (str(type(fin_scan_resp))=="type 'NoneType'"):
print "Open|Filtered"
elif(fin_scan_resp.haslayer(TCP)):
if(fin_scan_resp.getlayer(TCP).flags == 0x14):
print "Closed"
elif(fin_scan_resp.haslayer(ICMP)):
if(int(fin_scan_resp.getlayer(ICMP).type)==3 and int(fin_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print "Filtered"
TCP 空扫描(Null)
在空扫描中,客户端发出的 TCP 数据包仅仅只会包含端口号而不会有其他任何的标识信息。如果目标端口是开放的则不会回复任何信息。
如果服务器返回了一个 RST 数据包,则说明目标端口是关闭的。
如果返回 ICMP 错误类型3且代码为1,2,3,9,10或13的数据包,则说明端口被服务器过滤了。
代码:
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=80
null_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags=""),timeout=10)
if (str(type(null_scan_resp))=="type 'NoneType'"):
print "Open|Filtered"
elif(null_scan_resp.haslayer(TCP)):
if(null_scan_resp.getlayer(TCP).flags == 0x14):
print "Closed"
elif(null_scan_resp.haslayer(ICMP)):
if(int(null_scan_resp.getlayer(ICMP).type)==3 and int(null_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print "Filtered"
TCP ACK扫描
ACK 扫描不是用于发现端口开启或关闭状态的,而是用于发现服务器上是否存在有状态防火墙的。它的结果只能说明端口是否被过滤。再次强调,ACK 扫描不能发现端口是否处于开启或关闭状态。
客户端会发送一个带有 ACK 标识和端口号的数据包给服务器。如果服务器返回一个带有 RST 标识的 TCP 数据包,则说明端口没有被过滤,不存在状态防火墙。
如果目标服务器没有任何回应或者返回ICMP 错误类型3且代码为1,2,3,9,10或13的数据包,则说明端口被过滤且存在状态防火墙。
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=80
ack_flag_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="A"),timeout=10)
if (str(type(ack_flag_scan_resp))=="type 'NoneType'"):
print "Stateful firewall presentn(Filtered)"
elif(ack_flag_scan_resp.haslayer(TCP)):
if(ack_flag_scan_resp.getlayer(TCP).flags == 0x4):
print "No firewalln(Unfiltered)"
elif(ack_flag_scan_resp.haslayer(ICMP)):
if(int(ack_flag_scan_resp.getlayer(ICMP).type)==3 and int(ack_flag_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print "Stateful firewall presentn(Filtered)"
TCP窗口扫描
TCP 窗口扫描的流程同 ACK 扫描类似,同样是客户端向服务器发送一个带有 ACK 标识和端口号的 TCP 数据包,但是这种扫描能够用于发现目标服务器端口的状态。在 ACK 扫描中返回 RST 表明没有被过滤,但在窗口扫描中,当收到返回的 RST 数据包后,它会检查窗口大小的值。如果窗口大小的值是个非零值,则说明目标端口是开放的。
如果返回的 RST 数据包中的窗口大小为0,则说明目标端口是关闭的。
代码:
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=80
window_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="A"),timeout=10)
if (str(type(window_scan_resp))=="type 'NoneType'"):
print "No response"
elif(window_scan_resp.haslayer(TCP)):
if(window_scan_resp.getlayer(TCP).window == 0):
print "Closed"
elif(window_scan_resp.getlayer(TCP).window 0):
print "Open"
UDP扫描
TCP 是面向连接的协议,而UDP则是无连接的协议。
面向连接的协议会先在客户端和服务器之间建立通信信道,然后才会开始传输数据。如果客户端和服务器之间没有建立通信信道,则不会有任何产生任何通信数据。
无连接的协议则不会事先建立客户端和服务器之间的通信信道,只要客户端到服务器存在可用信道,就会假设目标是可达的然后向对方发送数据。
客户端会向服务器发送一个带有端口号的 UDP 数据包。如果服务器回复了 UDP 数据包,则目标端口是开放的。
如果服务器返回了一个 ICMP 目标不可达的错误和代码3,则意味着目标端口处于关闭状态。
如果服务器返回一个 ICMP 错误类型3且代码为1,2,3,9,10或13的数据包,则说明目标端口被服务器过滤了。
但如果服务器没有任何相应客户端的 UDP 请求,则可以断定目标端口可能是开放或被过滤的,无法判断端口的最终状态。
代码:
#! /usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
dst_ip = "10.0.0.1"
src_port = RandShort()
dst_port=53
dst_timeout=10
def udp_scan(dst_ip,dst_port,dst_timeout):
udp_scan_resp = sr1(IP(dst=dst_ip)/UDP(dport=dst_port),timeout=dst_timeout)
if (str(type(udp_scan_resp))=="type 'NoneType'"):
retrans = []
for count in range(0,3):
retrans.append(sr1(IP(dst=dst_ip)/UDP(dport=dst_port),timeout=dst_timeout))
for item in retrans:
if (str(type(item))!="type 'NoneType'"):
udp_scan(dst_ip,dst_port,dst_timeout)
return "Open|Filtered"
elif (udp_scan_resp.haslayer(UDP)):
return "Open"
elif(udp_scan_resp.haslayer(ICMP)):
if(int(udp_scan_resp.getlayer(ICMP).type)==3 and int(udp_scan_resp.getlayer(ICMP).code)==3):
return "Closed"
elif(int(udp_scan_resp.getlayer(ICMP).type)==3 and int(udp_scan_resp.getlayer(ICMP).code) in [1,2,9,10,13]):
return "Filtered"
print udp_scan(dst_ip,dst_port,dst_timeout)
下面解释下上述代码中的一些函数和变量:
RandShort():产生随机数
type():获取数据类型
sport:源端口号
dport:目标端口号
timeout:等待相应的时间
haslayer():查找指定层:TCP或UDP或ICMP
getlayer():获取指定层:TCP或UDP或ICMP
以上扫描的概念可以被用于“多端口扫描”,源码可以参考这里:
Scapy 是一个非常好用的工具,使用它可以非常简单的构建自己的数据包,还可以很轻易的处理数据包的发送和相应。
(译者注:上述所有代码均在Kali 2.0下测试通过,建议读者在Linux环境下测试代码,如想在Windows上测试,请参见 Scapy官方文档 配置好scapy环境)
0条大神的评论