《渗透模块Socket Nmap Scapy》
Socket模块:
socket是一个类,三个参数: 第一个地址族(ip),第二个是流(tcp/udp),第三个参数为使用的协议
参数1 family:
常用的协议有 AF_INET,AF_INET6,AF_LOCAL(OR AF_UNIX,UNIX域Socket),AF_ROUTE等
默认为AF_INET
参数2 type:
SOCK_STREAM: TCP类型,默认值
SOCKDGRAM: UDP类型
SOCK_RAW:原始类型,允许底层协议如IP或ICMP来进行直接访问
参数3 使用的协议:
通常赋值0 由系统自己选择
初始化一个TCP类型的Socket: s = socket.socket() >>> s = socket.socket(AF_INET,SOCK_STREAM)
服务端常用函数:
bind():由服务端调用,在创建socket之前与指定的ip地址,端口进行绑定,如果已经初始化,则使用元组(host,port)的形式来表示地址 >>> s.bind(('127.0.0.1',2345))
listen():开启监听模式,可以使用一个参数来指定最大连接数 最小为1 一般设置为5 >>> s.listen(5)
accept(): 服务端接受连接,一般为阻塞态等待态,接受tcp连接并返回(conn,address)
conn为新的套接字对象,可以用来接受和发送数据,address为客户端地址
客户端常用函数:
connect(): 连接服务端,使用方法 s.connect(("127.0.0.1",2345))
服务器和客户端都可以使用的函数:
send(): 用于使用TCP时发送数据 使用方法: send(string[,flag])
sendall(): 与send()类似,也是用于在使用tcp时发送数据,使用方法:sendall(string,[,flag])
与send()类似,区别是完整发送tcp数据。将string中的数据发送到连接的套字,但返回之前会尝试发送所有的数据,成功返回None,失败则抛出异常 >>> sendall("hello word")
recv(): 用于使用tcp接受数据,使用:recv(bufsize[,flag]) 例如通过函数接受长度为1024的字符
obj.recv(1024)
sendto(): 用于UDP发送数据,使用: sendto(string[,flag],address) >>> address --> (ipaddr,port)
recvfrom():用于UDP接收数据,返回值为(data,address)
close()关闭 socket
Nmap模块:
概念:nmap可以实现1、主机发现功能,2、端口扫描,3、服务及版本检测,4、操作系统检测
安装:apt-get install nmap pip install python-nmap
介绍:nmap核心模块为:PortScanner,PortScannerAsync,PortScannerError、PortScannerHostDict、PortScannerYield等,其中最重要的就是 PortScanner
使用:
实例化 nmap.PortScanner() >>> nm = nmap.PortScanner()
namp.PortScannerAsync() >>> nm = nmap.PortScannerAsync() //可以实现异步扫描
PortScanner函数:
scan():
对指定目标进行扫描,参数有 hosts、ports和arguments
scan(self,hosts='127.0.0.1',ports = None,arguments='-sV',sudo=False)
hosts:顾名思义就是主机ip或者域名
ports:就是端口 可以个单个也可以多个 多个用逗号来进行分割
arguments:就是类型,参数。
-sP:表示对目标进行Ping主机在线扫描,
-PR:表示对目标进行一个ARP的主机在线扫描,
-sS:表示对目标进行一个TCP半开(SYN)类型的端口扫描,
-sT:表示对目标进行一个TCP全开类型的端口扫描,
-O:表示扫描目标的操作系统类型,
-sV:表示扫描目标上所安装网络服务软件的版本。
练习:对192.168.1.101的1~500端口进行一次TCP半开扫描
import nmap
nm = nmap.PortScanner()
nm.scan("192.168.1.101","1-500","-sS")
all_hosts():返回一个被扫描的所有主机列表 nm.all_hosts()
command_line():返回在当前扫描中使用的命令 nm.command_line()
csv():返回一个比较工整的扫描结果 nm.csv()
has_host(self,host):检查是否有host结果,有为T 无为F,>>> nm.has_hosts("192.168.1.100")
scaninfo():列出扫描信息结构 nm.scaninfo()
PortScannerAsync函数:
scan():
同PortScanner中的一样,只不过多了一个回调函数
scan(self, hosts='127.0.0.1',ports=None, arguments='-sV', callback=None, sudo=False)
callback是以(host,scann_data)为参数的函数
still_scanning():如果扫描正在进行,则返回True,否则返回False
st = nm.still_scanning()
wait(self, timeout=None):函数表示等待时间
nm.wait(2)
stop(): 停止扫描
Scapy:
概念:在Scapy中每一个协议就是一个类
ip:
ip = IP(src="ip_address",dst="ip_address",ttl=32) 范围:target = 192.168.1.0/24 ip = IP(dest = target)
查看每一个数据包: [p fpr p in ip]
Ether:
由于scapy采用分层的形式来构造数据包,ip无法构造arp的请求和应答报文,所以要使用Ether来进行构造
构造广播包 >>> Ether(dst="ff:ff:ff:ff:ff:ff")
TCP:
可以使用 Ether()/IP()/TCP() 来构造一个完整的tcp数据包
HTTP:
IP()/TCP()/"GET / HTTP/1.0\r\n\r\n "
ls函数:
ls函数可以查看一个类所拥有的属性,ls(IP())
send和sendp模块:
send模块工作在第三层,sendp模块工作在第二层
send模块发送IP数据,sendp模块发送Ether数据包
send(IP(dst="192.168.1.1")/ICMP()) >>> successful > Sent 1 packets
sendp(Ether(dst="ff:ff:ff:ff:ff:ff")) >>> successful > Sent 1 Packets
这两个函数的特点在于 只发不收
fuzz函数:
负责内容随机填充
IP(dst = "192.168.1.1")/fuzz(TCP())
sr()、sr1()、srp():
sr和sr1主要用于第三层,srp则用于第二层
sr当数据发送出去,同时scapy会监听返回的数据, received表示收到的数据包个数、answer表示对应的应答数据包
sr()函数为scapy的核心,它的返回值是两个列表,第一个列表是收到了应答的包和对应的应答,第二个列表是未收到应答的包。所以可以使用两个列表来保存 sr() 的返回值
ans,unans = sr(IP(dst = "192.168.1.1")/ICMP()) >>> 使用ans,unans来保存 ans.summary() >>> 来查看列表内容
sr1与sr函数大同小异,但是只返回一个应答包,可以使用sr1函数来测试目标的某个端口是否开放采用半开SYN扫描法
>>> sr1(IP(dst="192.168.26.101")/TCP(dport=80,flags="S"))
sniff()
在终端开启sniff,scapy就属于捕获网卡数据的状态,如有流量经过网卡,ctrl+c就可以获取sniff的数据
sniff 可以使用 filter参数进行过滤
例如,指定只捕获与192.168.1.102有关的数据包,可以使用“host 192.168.1.102”: >>>sniff(filter=" host 192.168.1.102")
如果要同时满足多个条件可以使用“and”“or”等关系运算符来表达: >>>sniff(filter=" host 192.168.1.102 and icmp")
iface:可以指定网卡 >>> sniff(iface = "eth1")
count: 指定最大监听数量 >>> sniff(count = 3)
练习:设计一个综合性的监听器,它会在网卡eth0上监听源地址或者目的地址为192.168.1.102的icmp数据包,当收到了三个这样的数据包之后,就会停止监听。
首先在Scapy中创建如下监听器:
>>> sniff(filter="icmp and host 192.168.16.128“,count=3,iface="eth0")
Ctrl C 停止结束捕获 即可查看结果
如果需要查看 捕获到的三个数据包具体的内容,可以使用_来进行查看,在scapy中_代表上一条语句的结果
a=_ a.nsummary()
刚刚使用过的函数pkt.summary()用来以摘要的形式显示pkt的内容,这个摘要的长度为一行 pkt packet
p = IP(dst="www.baidu.com")
p.summary()
"192.168.169.130>Net('www.baidu.com') hopopt"
综合案例:
使用Scapy进行ACK端口扫描
ACK扫描:扫描主机向目标主机发送ACK数据包。根据返回的RST数据包有两种方法可以得到端口的信息。
若返回的RST数据包的TTL值小于或等于64,则端口 开放,反之端口 关闭
对192.168.1.102 的 21、23、135、443、445 这5个端口是否被屏蔽进行扫描,注意是屏蔽不是关闭,采用ACK扫描模式,
ans,unans = sr(IP(dst="192.168.1.102")/TCP(dport=[21,23,135,443,445],flags="A"))
按照TCP三次握手的规则,如果目标端口没有被过滤,发出的数据包就会得到回应,否则没有回应。
for s,r in ans:
... if s[TCP].dport == r[TCP].sport:
... print str(s[TCP].dport) + " is unfiltered"
使用Scapy来设计一个端口是否开放的扫描器。
tips:
如果一个端口处于屏蔽状态,那么它将不会产生任何响应报文。
如果一个端口处于开放状态,那么它在收到syn数据包之后,就会回应一个ack数据包。
反之,如果一个端口处于关闭状态,那么它在收到syn数据包之后,就会回应一个rst数据包。
步骤:
1、导入模块
from scapy.all import fuzz,TCP,IP,sr
2、生成syn数据包
ans,unans = sr(IP(dst="192.168.26.100")/fuzz(TCP(dport=80,flags="S")))
3、循环遍历结果
如果r[TCP].flags==18,则表示返回数据包flags的值为0x012 (SYN,ACK)目标端口为开放状态。
如果r[TCP].flags==20,则表示返回数据包flags的值为0x014 (RST,ACK)目标端口为关闭状态。
for s,r in ans:
...if r[TCP].flags==18:
print "This port is Open"
...if r[TCP].flags == 20:
print "This port is Closed"

浙公网安备 33010602011771号