此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出。欢迎各位前来交流。(部分材料来源网络,若有侵权,立即删除)
本人博客所有文章纯属学习之用,不涉及商业利益。不合适引用,自当删除!
若被用于非法行为,与我本人无关
基于Python|ACK|FIN|Null|Xmas|windows|扫描|端口扫描|scapy库编写|icmp协议探测主机|对开放端口和非开放端口完成半连接扫描
引用库
from socket import *
import threading
import scapy.all as s
from IPy import IP as IPY
- 这里使用as给引用的库进行更名是为了防止在后续使用两个库中的同名函数报错
全连接端口扫描
对指定端口进行扫描
def Scanner(host, port):
try:
s = socket(AF_INET, SOCK_STREAM)
s.connect((host, port))
print("[open] ports:" + str(port))
except:
pass
s.close()
- 基于SOCK_STREAM
- TCP连接
- 使用的是全连接,如果能建立连接则输出,如果不能建立连接则pass
对单线程端口扫描的多线程管理
thread = []
def ctrl_Scan(host):
for port in range(1, 8080):
t = threading.Thread(target=Scanner, args=(host, port))
thread.append(t)
t.start()
for t in thread:
t.join()
- 这边使用了多线程,主要是考虑到要扫描的端口众多
使用IP协议发包来判断端口是否开放
def port_scan(ip, port):
p = IP(dst=ip) / TCP(dport=int(port), flags="*")
ans = sr1(p, timeout=1, verbose=1)
print(ans)
if ans == None or ans[TCP].flags!='*':
print(ip, "port", port, "is open.")
elif ans != None and ans[TCP].flags == '*':
ans.display()
print(ip, "port", port, "is closed.")
使用ICMP协议探测主机状况
- 很想用PING命令
- 想了想下次一定
def Ping_icmp(dest):
print("=" * 100)
print("\n正在进行为PING扫描:")
ip_addr = IPY(dest)
for ip in ip_addr:
# print(ip)
packet = s.IP(dst=str(ip)) / s.ICMP() / b'rootkit'
ping = s.sr1(packet, timeout=1, verbose=False)
if ping:
print(str(ip) + "主机已开启")
else:
print(str(ip) + "主机未开启")
print("=" * 100)
- 为了区分IP()函数,前面as使用的别名就用上了
半连接扫描
ACK
- 通过设置flags位为A,不回复表示端口关闭或被过滤,根据回复的数据包TTL小于等于64表示端口开放,大于64端口关闭
def ACK_scan(ip, port):
print("=" * 100)
print("\n正在进行为ACK的半连接扫描:")
p = s.IP(dst=ip) / s.TCP(dport=int(port), flags="A")
link = s.sr1(p, timeout=1, verbose=1)
if link == None:
print("[ACK]The host is closed.")
else:
if link != None and link.ttl <= 64:
print("[ACK]The host is open.")
elif link != None and link.ttl > 64:
print("[ACK]The host is closed.")
print(ip, port)
print("=" * 100)
SYN
- 向主机对应端口发送SYN数据,即建立连接请求,如果回应SYN+ACK,则端口开启。若回复RST说明目标端口不关闭。然后再发送一个RST拒绝连接。导致三次握手失败。
- 半连接的优点在于不会留下记录
def SYN_scan(ip, port):
print("=" * 100)
print("\n正在进行为SYN的半连接扫描:")
p = s.IP(dst=ip) / s.TCP(dport=int(port), flags="S")
link = s.sr1(p, timeout=1, verbose=1)
if link[s.TCP].flags == 'SA':
print("[SYN]The PORT is open.")
else:
print("[SYN]The PORT is closed.")
print(ip, port)
print("=" * 100)
FIN
- FIN扫描中将标志位FIN置1,若端口开放,则无回应,若端口关闭,会收到RST
def FIN_scan(ip, port):
print("=" * 100)
print("\n正在进行为FIN的半连接扫描:")
p = s.IP(dst=ip) / s.TCP(dport=int(port), flags="F")
link = s.sr1(p, timeout=1, verbose=1)
if link == None:
print("[FIN]The PORT is open.")
elif link != None and link[s.TCP].flags == 'RA':
link.display()
print("[FIN]The PORT is closed.")
print(ip, port)
print("=" * 100)
NULL
- 通过设置flags位为空,不回复则表示端口开启,回复并且回复的标志位为RS表示端口关闭
def NULL_scan(ip, port):
print("=" * 100)
print("\n正在进行为NULL的半连接扫描:")
p = s.IP(dst=ip) / s.TCP(dport=int(port), flags="")
link = s.sr1(p, timeout=1, verbose=1)
if link == None:
print("[NULL]The PORT is open.")
elif link != None and link[s.TCP].flags == 'RA':
link.display()
print("[NULL]The PORT is closed.")
print(ip, port)
print("=" * 100)
Xmas
- 通过设置flag位FPU,如果未回复表示端口开启,如果回复RA表示端口关闭
def XMAS_scan(ip, port):
print("=" * 100)
print("\n正在进行为Xmas的半连接扫描:")
p = s.IP(dst=ip) / s.TCP(dport=int(port), flags="FPU")
link = s.sr1(p, timeout=1, verbose=1)
if link == None:
print("[Xmas]The PORT is open.")
elif link != None and link[s.TCP].flags == 'RA':
link.display()
print("[Xmas]The PORT is closed.")
print(ip, port)
print("=" * 100)
WINDOWS
- 通过设置flags位为ACK,不回复表示端口关闭或被过滤,如果回复的数据包TTL小于等于64表示端口开放,大于64端口关闭(windows)
def WINOWS_scan(ip, port):
print("=" * 100)
print("\n正在进行为WINDOWS的半连接扫描:")
p = s.IP(dst=ip) / s.TCP(dport=int(port), flags="A")
link = s.sr1(p, timeout=1, verbose=1)
if (str(type(link)) == "<class 'NoneType'>"):
print("[WINDOWS]The PORT is closed.")
elif (link.haslayer(s.TCP)):
if (link.getlayer(s.TCP).window == 0):
print("[WINDOWS]The PORT is closed.")
elif (link.getlayer(s.TCP).window > 0):
print("[WINDOWS]The PORT is OPEN.")
else:
print("[WINDOWS]The PORT is closed.")
print(ip,port)
print("=" * 100)
总结
- 需要使用哪个就使用哪个
- 没有写菜单了(主要是懒)
if __name__ == '__main__':
ctrl_Scan()
Ping_icmp()
ACK_scan()
SYN_scan()
FIN_scan()
NULL_scan()
XMAS_scan()
WINOWS_scan()
- 还有就是扫描的情况会受到网络波动以及系统情况的影响,可能会出现错误的情况,多试几次
- 以及部分函数在某些特殊情况下发包扫描可能会报错、
end