【文章标题】: 小菜的扫描程序
【软件名称】: 扫描器
【使用工具】: Python
【操作平台】: inlux,windows
【作者声明】:只是做为学习python语言而写的程序,拿来提供socket编程思路
首先我用的是跨平台语言python及socket写的(各种linux商业版本基本都自带它的解释器,windows下得自己安装python解释器)支持多线程,程序非常的简单同时请高手指教我siaomiaozhujidizhi()函数也就是IP生成的函数的算法有没有更好的?我感觉我这个比较麻烦.谢谢.
这个拿不出手的程序是我唯一的"作品"因为现在在研究软件安全方面的东西.非常想加入本论坛希望管理给个邀请码吧.先谢谢了.
#-*-coding:utf-8-*-
from socket import *
from Queue import Queue
import cPickle as p
import threading
import time
import thread
import os
class zhujidizhi:
'''zhujidizhi类解释:
主要功能为返回一个IP列表
参数为:1.列表的开始IP
2.列表的结束IP
注意事项:本类返回IP的列表
函数:siaomiaozhujidizhi(self)
解释:主要计算IP地址和返回IP地址'''
def __init__(self,kaishidizhi='1.1.1.1',jieshudizhi='255.255.255.254'):
self.kaishidizhi=kaishidizhi.split('.')
self.jieshudizhi=jieshudizhi.split('.')
self.zfkaishijieshuzhujidizhi=[]
self.zfkaishijieshuzhujidizhi.append(self.kaishidizhi)
self.zfkaishijieshuzhujidizhi.append(self.jieshudizhi)
def siaomiaozhujidizhi(self):
if self.zfkaishijieshuzhujidizhi[0]!=self.zfkaishijieshuzhujidizhi[1]:
zfkaishijieshuzhujidizhi=self.zfkaishijieshuzhujidizhi
linshiliebiao=zfkaishijieshuzhujidizhi[0][:]
saomiaozhujidizhi=[]
saomiaozhujidizhi.append(zfkaishijieshuzhujidizhi[0])
duibishu1=0
duibishu2=zfkaishijieshuzhujidizhi[1]
while duibishu1!=duibishu2:
if int(linshiliebiao[3])<254:
linshiliebiao[3]=str(int(linshiliebiao[3])+1)
elif int(linshiliebiao[3])==254 and int(linshiliebiao[2])<=255:
linshiliebiao[3]='1'
linshiliebiao[2]=str(int(linshiliebiao[2])+1)
elif int(linshiliebiao[3])==254 and int(linshiliebiao[2])==255 \
and int(linshiliebiao[1])<=255:
linshiliebiao[3]='1'
linshiliebiao[2]='1'
linshiliebiao[1]=str(int(linshiliebiao[1])+1)
elif int(linshiliebiao[3])==254 and int(linshiliebiao[2])==255 \
and int(linshiliebiao[1])==255 \
and int(linshiliebiao[0])<=int(zfkaishijieshuzhujidizhi[1][0]):
linshiliebiao[3]='1'
linshiliebiao[2]='1'
linshiliebiao[1]='1'
linshiliebiao[0]=str(int(linshiliebiao[0])+1)
else:
break
saomiaozhujidizhi.append(linshiliebiao[:])
duibishu1=linshiliebiao
return saomiaozhujidizhi
else:
return [self.zfkaishijieshuzhujidizhi[0],]
class saomiaofuwu:
'''saomiaofuwu类解释:
本类主要功能为扫描指定IP的指定TCP端口是否开启(服务是否可用)
参数为:1.要扫描的主机的列表(不代表点)
2.要扫描的端口列表(数字类型)
注意事项:本类没有返回值,而是直接在程序目录中写一个日志文件
函数:saomiao(self)
解释:执行扫描的方法'''
def __init__(self,zhujiliebiao,fuwuliebiao):
self.zhujiliebiao=zhujiliebiao
self.fuwuliebiao=fuwuliebiao
def saomiao(self):
saomiaorizhi=[]
zhujiming=self.zhujiliebiao
saomiaorizhi.append('扫描的主机为:'+zhujiming)
for afuwu in self.fuwuliebiao:
duankou=afuwu[0]
fuwuming=afuwu[1][0]
ADDR=(zhujiming,duankou)
moufuwu=''
try:
print '正在扫描--',zhujiming,'端口-',str(duankou)+'...'
#每次扫描服务都要新建立一个socket对象,否则报错
tcplianjie=socket(AF_INET,SOCK_STREAM)
#设置socket链接超时为5秒 linux 默认为 76妙 如果有链接不到的主机会当误很长时间
tcplianjie.settimeout(5)
tcplianjie.connect(ADDR)
except:
#关闭socket链接
tcplianjie.close()
print '主机:',zhujiming,'端口-',str(duankou),'关闭'
continue
#关闭socket链接
tcplianjie.close()
#设置提示信息和日志写入信息
fuwujieshi=afuwu[1][1]
moufuwu='主机:'+zhujiming+'\r\n端口:'+str(duankou)+'\r\n服务:'+fuwuming+'状态: 开启\r\n服务简介:'+fuwujieshi
saomiaorizhi.append(moufuwu)
print moufuwu
if len(saomiaorizhi)>1:
suoyouduankouliebiao=[]
for zjfulb in self.fuwuliebiao:
suoyouduankouliebiao.append(str(zjfulb[0]))
suoyouduankou='扫描的服务列表:'+','.join(suoyouduankouliebiao)
saomiaorizhi.append(suoyouduankou)
saomiaorizhi.append(time.ctime())
saomiaorizhi.append('---------------------------------------------------------------------------------------------------------------------------')
saomiaorizhi.append('\r\n\r\n')
rizhiwenjianduixiang=file('saomiaorizhi.txt','a')
for jjilu in saomiaorizhi:
rizhiwenjianduixiang.write(jjilu+'\r\n\r\n')
print '扫描完毕 记录已存入文件 同目录下的"saomiaorizhi.txt"'
class xianchengsaomiao(threading.Thread):
'''线程子类
参数列表:(主机IP,扫描服务端口列表,互斥锁对象,线程交互对象)'''
def __init__(self,zhujidizhi,fuwuliebiao,lock,xianchenggongxiang):
threading.Thread.__init__(self)
self.zhujidizhi=zhujidizhi
self.fuwuliebiao=fuwuliebiao
self.xianchenggongxiang=xianchenggongxiang
self.lock=lock
def run(self):
zhujishu=1
#线程的每IP扫描循环
#以IP列表中的主机数量来判断
while zhujishu<=len(self.zhujidizhi):
#如果锁是锁住的就等待,直到锁开启为止
while self.lock.locked():pass
#将锁锁定,防止其他线程修改共享内容
self.lock.acquire()
#获得Queue模块的Queue类对象(此对象是所有线程都可以访问的先进先出列表)
#获得的内容为当前准备扫描的IP地址的序列号(在列表中的索引)
zhujishu=self.xianchenggongxiang.get(1)
#如果索引大于主机列表的最大数就退出 线程会自动结束
if zhujishu+1>len(self.zhujidizhi):
#防止共享对象中内容为空,其他线程会无限等待下去,把获得的数再放回去
self.xianchenggongxiang.put(zhujishu,1)
#打开锁让其他进程可以继续访问Queue对象
self.lock.release()
break
#把下一个线程应该扫描的IP的序列号存如Queue对象
zhujishu+=1
self.xianchenggongxiang.put(zhujishu,1)
#打开锁
self.lock.release()
#获得字符串格式的主机IP地址
dangqiansaomiaozhuji='.'.join(self.zhujidizhi[zhujishu-1])
#实例化saomiaofuwu类 用来扫描主机服务的类
saomiaoduixiang=saomiaofuwu(dangqiansaomiaozhuji,self.fuwuliebiao)
#调用扫描的方法
saomiaoduixiang.saomiao()
print '结束线程'
def saomiaoduixiang(self):
f=file('duankoufuwu.txt')
bb=[['a',['a','a']],]
while True:
duankouhao=f.readline()
fuwuming=f.readline()
fuwujianjie=f.readline()
if len(duankouhao)!=0 and len(fuwuming)!=0 and len(fuwujianjie)!=0:
bb.append([int(duankouhao),[fuwuming,fuwujianjie]])
else:
break
f1=file('saomiaofuwuduixiang','w')
del bb[0]
p.dump(bb,f1)
f1.close()
def main():
kaishidizhi=raw_input('请输入扫描主机的开始IP地址: ')
jieshudizhi=raw_input('请输入扫描主机的结束IP地址: ')
xianchengshuliang=raw_input('请输入扫描的线程数量: ')
fuwuduixiangpanduan=raw_input('是否从新生成要扫描的服务配置文件(yes/no): ')
#判断是否需要调用生成服务配置文件函数
if fuwuduixiangpanduan=='yes':
saomiaoduixiang()
#从配置文件中获得扫描服务的列表对象
f=file('saomiaofuwuduixiang')
fuwuliebiao=p.load(f)
#调用制作IP地址列表类返回IP地址列表
dizihduixiang=zhujidizhi(kaishidizhi,jieshudizhi)
fanhuidizhi=dizihduixiang.siaomiaozhujidizhi()
#设置多线程间的通讯对象(用来判断扫描到列表的哪台主机)
xianchenggongxiang=Queue(40)
xianchenggongxiang.put(0,1)
#设置线程锁用来控制通讯对象读写
alock=thread.allocate_lock()
#判断线程数量
if xianchengshuliang<=1 or len(fanhuidizhi)<=1:
xianchengshuliang=1
#声明存线程对象的列表
xcsmdxlb=[]
#声明一个从0开始到线程个数的列表
xianchengliebiao=range(int(xianchengshuliang))
#声明线程对象并把每个线程存到列表中
for dizhi in xianchengliebiao:
xcsmdx=xianchengsaomiao(fanhuidizhi,fuwuliebiao,alock,xianchenggongxiang)
xcsmdxlb.append(xcsmdx)
#调用线程对象
for dizhi in xianchengliebiao:
xcsmdxlb[dizhi].start()
#判断每个线程都结束后在退出程序
for dizhi in xianchengliebiao:
xcsmdxlb[dizhi].join()
print '扫描结束....'
os.system('vi saomiaorizhi.txt')
if __name__=='__main__':
main()
不要看好象很长的样子其实除了说明以及空行和没用的说明输出外这个小程序的功能代码绝对不超过100行非常简单
这个简单的小程序最好的东西是它的配置文件这个文件里面有183个端口以及相应的服务和此服务的说明 这个文件是duankoufuwu.txt
扫描完毕后会在执行文件的相同目录下产生日志文件
输入说明:1.是要扫描的IP段的开始地址
2.是要扫描的IP段的结束地址
3.是为这次扫描设置的线程数
4.是是否重新生成配置文件(它会把本目录下的名为duankoufuwu.txt的文件生成一个它可以认识的配置文件)
只要把duankoufuwu.txt拷贝到执行程序的相同目录下然后在本选项中选yes就可以了
注意:这个简单的小程序没有对输入的东西进行过滤如果你在输入IP的地方输入了莫名其妙的字符程序会崩溃..(因为没有时间写这样的功能了;>)
[课程]FART 脱壳王!加量不加价!FART作者讲授!