一:安装IPy组件
1:方法一:离线安装
下载IPy包,解压后在命令行中安装
在命令行中执行python setup.py install
2:方法二:在线安装
命令行中执行pip install IPy
二:IPy模块的使用
1:用version()区分IP地址属于什么版本(注意大小写)
>>> from IPy import IP
>>> IP ('10.0.0.1').version()
2:通过指定的网段输出该网段的IP个数及所有ip地址清单(编辑器中写)
from IPy import IP
ip=IP('192.168.0.0/28')
print (ip.len())
for x in ip:
print (x)
3:IP类常用的方法
>>> from IPy import IP
>>> ip=IP('192.168.1.20')
>>> ip.reverseNames()
['20.1.168.192.in-addr.arpa.']
>>> ip.iptype()
'PRIVATE'
>>> IP('8.8.8.8').iptype()
'PUBLIC'
>>> IP('8.8.8.8').int()
134744072
>>> IP('8.8.8.8').strHex()
'0x8080808'
>>> IP('8.8.8.8').strBin()
'00001000000010000000100000001000'
>>> print (IP(0x8080808))
8.8.8.8
4:网络地址转换,根据IP与掩码生成网络格式
>>> print (IP('192.168.1.0').make_net('255.255.255.0'))
192.168.1.0/24
5:通过strNormal方法指定不同wantprefixlen参数值以定制不同输出类型的网段,输出类型为字符串
>>> IP('192.168.1.0/24').strNormal(0)
'192.168.1.0'
>>> IP('192.168.1.0/24').strNormal(1)
'192.168.1.0/24'
>>> IP('192.168.1.0/24').strNormal(2)
'192.168.1.0/255.255.255.0'
>>> IP('192.168.1.0/24').strNormal(3)
'192.168.1.0-192.168.1.255'
三:多网格计算方法
1:判断IP地址和网段是否包含于另一个网段
>>> from IPy import IP
>>> '192.168.1.100' in IP ('192.168.1.0/24')
True
2:判断两个网段是否存在重叠
>>> IP('192.168.0.0/23').overlaps('192.168.1.0/24')
1
>>> IP('192.168.2.0/24').overlaps('192.168.1.0/24')
0
注释:0表示不重叠,1表示有重叠
3:根据输入的IP或子网返回网络、掩码、广播、反向解析、子网数、ip类型等信息
在编辑器中输入
from IPy import IP
ip_s=raw_input('Please input an IP or net-range:')
while len(ip_s)==0:
ip_s=raw_input('Please input an IP or net-range:')
ips=IP(ip_s)
if len(ips)>1:
print ('net:%s' % ips.net())
print ('netmask:%s' % ips.netmask())
print ('broadcast:%s' % ips.broadcast())
print ('reverse address:%s' % ips.reverseNames()[0])
print ('subnet:%s' % len(ips))
else:
print ('reverse address:%s' % ips.reverseNames()[0])
print ('hexadecimal:%s' % ips.strHex())
print ('binary ip:%s' % ips.strBin())
print ('iptype:%s' %ips.iptype())
保存后执行此程序,并输入ip或ip范围观察效果
4:给定一个子网10.0.0.16/29,计算子网地址、子网掩码、广播地址、可用IP数量,
(1)计算子网地址
>>> IP('10.0.0.16/29').net()
IP('10.0.0.16')
(2)计算子网掩码
>>> IP('10.0.0.16/29').netmask()
IP('255.255.255.248')
(3)计算广播地址
>>> IP('10.0.0.16/29').broadcast()
IP('10.0.0.23')
(4)显示地址范围
>>> IP('10.0.0.16/29').strNormal(3)
'10.0.0.16/29'
(5)可用IP数量
>>> len(IP('10.0.0.16/29'))
8
(6)列出所有IP地址
>>> for x in IP('10.0.0.16/29'):
print (x)
四:Python案例-编写端口扫描器
import optparse
from socket import *
from threading import *
screenLock=Semaphore(value=1)
#Semaphore,是负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。
def connScan(tgtHost,tgtPort):
try:
connSkt=socket(AF_INET,SOCK_STREAM) ##创建一个套接字对象
connSkt.connect((tgtHost,tgtPort)) ##尝试连接
connSkt.send('ViolentPython\r\n') ##发送数据
results=connSkt.recv(100) ##接受返回来的数据
screenLock.acquire() ##产生的线程排好队,一个一个得打印
实现线程扫描,还有信号量来避免乱码和失序。
使用screenLock.acquire()进行加锁,如果信号量没有被锁上,线程就有权继续运行,并且输出打印到屏幕上。
如果信号量已经被锁定,只能等待持有信号量的线程释放信号量。
通过利用信号量来确保在任何给定的时间点上只有一个线程可以打印屏幕
print ('[+]%d/tcp open'%tgtPort)
print ('[+]' + str(results))
except:
screenLock.acquire()
print ('[-]%d/tcp closed'%tgtPort)
finally:
screenLock.release() #释放掉
connSkt.close() #关闭连接
def portScan(tgtHost,tgtPorts):
try:
tgtIP=gethostbyname(tgtHost) #根据域名,获取ip
except:
print ("[-] Cannot resolve '%s':Unkown host"%tgtHost) #解析失败,打印信息
return
try:
tgtName=gethostbyaddr(tgtIP) #ip解析主机名
print ('\n[+] Scan Results for:' +tgtName[0]) ##解析成功打印扫描主机名
except:
print ('\n[+] Scan Results for:' +tgtIP) #否则,打印扫描ip
setdefaulttimeout(1) ##设置超时时间
for tgtPort in tgtPorts:
t=Thread(target=connScan,args=(tgtHost,int(tgtPort))) #线程扫描
t.start()
def main():
parser=optparse.OptionParser("usage%prog" + "-H -p ") #创建对象实例
usage:显示使用方法
parser.add_option('-H',dest='tgtHost',type='string',help='specify target host') #解释定义-H选项
parser.add_option('-p',dest='tgtPort',type='string',help='specify target port[s] separated by comma') #定义-p选项
(options,args)=parser.parse_args()
一旦已经定义好了所有的命令行参数,调用 parse_args() 来解析程序的命令行
tgtHost=options.tgtHost
print (options.tgtPort) #打印选项中的端口
各个参数的含义:
dest:用于保存输入的临时变量,其值通过options的属性进行访问,存储的内容是dest之前输入的参数,多个参数用逗号分隔
type: 用于检查命令行参数传入的参数的数据类型是否符合要求,有 string,int,float 等类型
help:用于生成帮助信息
default: 给dest的默认值,如果用户没有在命令行参数给dest分配值,则使用默认值
tgtPorts=str(options.tgtPort).split(',') #多个端口用,分隔
print (tgtPorts) #打印tgtPorts
if (tgtHost==None) | (tgtPorts[0]==None): #如果host为空或者ports为空
print (parser.usage) #显示使用方法
exit(0) #退出if判断
portScan(tgtHost,tgtPorts) #调用函数扫描主机端口
if __name__=="__main__":
main()