portscan

一个基于Python+Go的端口扫描及服务探测脚本

0x00 前言

近期由于公司环境整改/迭代以及历史弱口令等撞库,运维同事将内网测试环境的一些SSH等敏感端口对外,导致被挖矿团伙利用进行挖矿,虽然生产环境存在物理隔离,但仍存在极大安全风险,对此需要对所有用户进行端口对外开放监控。

0x01 确定方案

通过网上调研,发现滴滴安全应急响应中心发过一个相关的文章

需求基本一致,使用了下文章中提到的代码进行测试,可能我环境/带宽/目标等多种因素,导致测试之后发现并不理想,扫描速度慢且有时不稳定。

经过github、sourceforge、stackoverflow等一番搜索及疯狂复制粘贴,完成了个勉强算的上的成品。

代码逻辑如下:

1.1 用户输入目标处理

# 单独IP/HOST

ip: 127.0.0.1

ip_list: 127.0.0.1

# CIDR

ip: 127.0.0

ip_list: 127.0.0.1, 127.0.0.2, 127.0.0.3 ... 127.0.0.254

# IP访问

ip: 127.0.0.1-127.0.0.20

ip_list: 127.0.0.1, 127.0.0.2, 127.0.0.3 ... 127.0.0.20

# 文件

ip: ip.txt

ip_list: Same as above

1.2 目标存活探测

使用ICMP协议进行ping检测,使用的第三方库pyping(该库不支持python3,若要用py3需要自己转换下)

1.3 Go脚本探测

编译port_scan.go

go build -buildmode=c-shared -o portscan.so portscan.go

探测结果返回:

# 单个端口

94.191.42.58:22

# 多个端口

94.191.42.58:22, 9099

1.4 nmap指纹识别

根据go探测结果进行解析,分别使用nmap库进行服务识别

pip install python-nmap

返回结果:

127.0.0.1:22/ssh

127.0.0.1:9999:unknown

...

1.5 web service

若nmap结果返回为http,unknown,sun-answerbook等时,尝试连接获取title

0x02 代码实现

2.1 用户输入处理

def get_ip_list(ip):

'''

ip: 127.0.0.1

ip_list: 127.0.0.1

ip: 127.0.0

ip_list: 127.0.0.1, 127.0.0.2, 127.0.0.3 ... 127.0.0.254

ip: 127.0.0.1-127.0.0.20

ip_list: 127.0.0.1, 127.0.0.2, 127.0.0.3 ... 127.0.0.20

ip: ip.txt

ip_list: Same as above

'''

ip_list = []

iptonum = lambda x:sum([256**j*int(i) for j,i in enumerate(x.split('.')[::-1])])

numtoip = lambda x: '.'.join([str(x/(256**i)%256) for i in range(3,-1,-1)])

pattern = re.compile(

r'^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|'

r'([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|'

r'([a-zA-Z0-9][-_.a-zA-Z0-9]{0,61}[a-zA-Z0-9]))\.'

r'([a-zA-Z]{2,13}|[a-zA-Z0-9-]{2,30}.[a-zA-Z]{2,3})$'

)

if '-' in ip:

ip_range = ip.split('-')

ip_start = long(iptonum(ip_range[0]))

ip_end = long(iptonum(ip_range[1]))

ip_count = ip_end - ip_start

# print(ip_range,ip_start, ip_end, ip_count)

if ip_count >= 0 and ip_count <= 65536:

for ip_num in range(ip_start,ip_end+1):

ip_list.append(numtoip(ip_num))

else:

print('wrong format')

elif '.txt' in ip:

ip_file = open(ip, 'r')

for ip in ip_file:

ip_list.extend(get_ip_list(ip.strip()))

ip_file.close()

elif pattern.match(ip):

ip_list.append(ip)

else:

ip_split=ip.split('.')

net = len(ip_split)

if net == 2:

for b in range(1,255):

for c in range(1,255):

ip = "%s.%s.%d.%d"%(ip_split[0],ip_split[1],b,c)

ip_list.append(ip)

elif net == 3:

for c in range(1,255):

ip = "%s.%s.%s.%d"%(ip_split[0],ip_split[1],ip_split[2],c)

ip_list.append(ip)

elif net ==4:

ip_list.append(ip)

else:

print('wrong format')

return ip_list

2.2 目标存活探测

def get_target_status(target):

try:

r = pyping.ping(target)

if r.ret_code == 0:

return True

else:

return False

except:

return False

2.3 Go脚本探测

lib = cdll.LoadLibrary(u'./portscan.so')

lib.Scan.argtypes = [c_char_p]

lib.Scan.restype = c_char_p

def run(ip):

if get_target_status(ip):

print("\033[32m[ * ] {} is alive\033[0m".format(ip))

ip = str(ip).encode("utf-8")

temp_result = str(lib.Scan(ip))

print('\033[33mScan Result:{}\033[0m'.format(temp_result))

if ',' in temp_result:

port_list = temp_result.split(':')[1].split(',')

# print(port_list)

port_num = len(port_list)

if port_num > 30:

print('Possible WAF/CND on target.')

else:

for i in range(len(port_list)):

port = str(port_list[i]).strip()

# print(port, int(port))

nmap_scan(ip=ip, port=int(port), arg="-sS -Pn --version-all --open -p")

else:

port_list = temp_result.split(':')[1]

# print(port_list)

nmap_scan(ip=ip,port=port_list,arg="-sS -Pn --version-all -p")

else:

print("\033[31m[ * ] {} is not alive\033[0m".format(ip))

1.4 nmap指纹识别

nm =nmap.PortScanner()

def nmap_scan(ip,port,arg):

try:

ret = nm.scan(ip, arguments=arg+str(port))

# print(ret)

service_name = ret['scan'][ip]['tcp'][int(port)]['name']

if 'http' in service_name or service_name == 'sun-answerbook' or 'unknown' in service_name:

if service_name == 'https' or service_name == 'https-alt':

scan_url = 'https://{}:{}'.format(ip,port)

title = get_title(scan_url)

service_name = '{}(title:{})'.format(service_name,title)

else:

scan_url = 'http://{}:{}'.format(ip,port)

title = get_title(scan_url)

service_name = '{}(title:{})'.format(service_name,title)

print('\033[32m[ * ] {}:{}/{}\033[0m'.format(ip, port, service_name))

except nmap.nmap.PortScannerError:

print("Please run -O method for root privileges")

1.5 web service

def get_title(scan_url):

try:

r = requests.get(scan_url,timeout=5, verify=False)

r_detectencode = chardet.detect(r.content)

# print(r_detectencode)

actual_encode = r_detectencode['encoding']

response = re.findall(u'

(.*?)', r.content, re.S)

# print(response)

if response == []:

return None

else:

title = response[0].decode(actual_encode).decode('utf-8')

# banner = r.headers['server']

return title

except Exception as e:

pass

0x03 运行效果

以tx云的一台vps为例,全端口扫描+服务识别我测试的稳定在40s之内,还可以。但是有些IP不知什么情况会比较慢,还需进行优化。

go代码就不放了,太烂了,完全cv拼凑的,若有兴趣可私聊讨论。

参考文章

python 端口扫描 东京_GitHub - w2n1ck/portscan: 一个基于Python+Go的端口扫描及服务探测脚本...相关推荐

  1. python云盘私有云_GitHub - 0x2642/Umi-Chest: 一个基于python的私有云实验项目

    Umi-Chest 一个基于angular 4的单页面舰娘百科App 关于项目名是因为kuma一直找不到好的名字,因为联想到海,然后我喜欢海爷,所以本来想叫海爷百宝箱什么的(一个舰娘的App你叫海爷百 ...

  2. 一个基于Python数据大屏可视化开源项目

    ‍‍ 今天给大家介绍一个开源数据大屏可视化工具. 项目简介 这是一个基于Python开发的,结构简单的项目.可通过配置Json的数据,实现数据报表大屏显示. 优点:代码清晰.结构简单.配置Json数据 ...

  3. 推荐一个基于Python开源的文档系统

    今天给大家推荐一个基于Python开发的在线开源文档系统. 项目简介 在日常开发中,每个项目都需要编写大量的文档.文档放在网络上,涉及一些公司.个人机密就不适合放在互联网上面.这个系统就刚好可以满足我 ...

  4. 一个基于Python的tkinter模块实现的游戏活动日历模拟器

    一个基于Python的tkinter模块实现的游戏活动日历模拟器 1.Python环境准备 2.简单介绍 3.源代码 4.源代码及活动配置表下载 1.Python环境准备 运行该项目需要Python3 ...

  5. python创建网盘_超简单!基于Python搭建个人“云盘”

    1 简介 当我们想要从本地向云服务器上传文件时,比较常用的有pscp等工具,但避免不了每次上传都要写若干重复的代码. 而笔者最近发现的一个基于Python的工具updog,可以帮助我们在服务器上搭建类 ...

  6. python应用如何实现升级_一种基于Python实现BMC批量升级的方法与流程

    本发明涉及BMC批量升级,尤其涉及一种基于Python实现BMC批量升级的方法. 背景技术: 随着现代服务器主板技术的发展,主板设计形态复杂多变.无论是设计成本还是后期使用过程中的维护成本都很高.如何 ...

  7. 基于python的图像处理的毕业论文_个人毕业设计基于python开发的图像论文34646.doc...

    word文档可自由复制编辑 本科生毕业论文(设计) 题目:基于python开发的图像 采集器之Airppt 学 部 学科门类 专 业 基于python开发的图像采集器之Airppt 摘 要 装订 装 ...

  8. python做一副54扑克牌发牌_基于Python制作一副扑克牌过程详解

    整理一下通过本文分享给大家, 该案例是通过 Python 类属性创建一幅除去大王.小王之后的 52 张扑克牌,并实现随机抽牌.排序.洗牌等功能: 创建一个纸牌类 一副扑克除去大王小王之外,剩下的 52 ...

  9. python性能测试可视化_locust安装及其简单使用----基于python的性能测试工具

    1.已安装python3.6 ,安装步骤略 pip安装: pip install locust 检查locust是否安装成功 locust --help 2.安装 pyzmq If you inten ...

最新文章

  1. aspen串联反应怎么输入_【精】反应器(反应釜)的结构和工作原理
  2. HighNewTech:LL / GCP BOOTH at CES 2019 - January 8-11, 2019 - Westgate Convention Center Las Vegas
  3. WP7 WMAppManifest.xml各个属性作用
  4. stdin,stdout,stderr
  5. 关于PHPExcel 导出下载表格,调试器响应乱码
  6. 计算机应用技术专业毕业论文,计算机应用技术专科毕业论文范文
  7. Spring Boot 发送邮件
  8. Java性能调优全攻略来了
  9. Tomcat9 配置HTTPS连接
  10. 2、idea热部署插件JRebel+2020年Jrebel激活码+Springboot web开发+Springboot配置文件详解+thymeleaf模板引擎的使用【Springboot】
  11. python中换页是干嘛的_python什么是转页符
  12. java web需要学多久_java框架都有哪些 要学多久
  13. 国产web服务器系统,国产web服务器
  14. Latex、如何将word中的表格转换为Latex代码
  15. 要实现一台电脑可以上公司内网也可以访问外网
  16. 如何在期货与现货市场之间套利?
  17. 北斗星通GPS调试记录
  18. 用Ogre实现画中画 [ 截图 ]
  19. 1.11 Illustrator视图的预览模式 [Illustrator CC教程]
  20. 数字化转型:核心架构、重要价值及实现路径

热门文章

  1. (五)激光雷达、移动测量、点云与影像的相关术语与规范来源
  2. 6.824 raft lab 2A 2B实验分析
  3. 数学建模-插值算法(Matlab)
  4. 绿色环保低碳生活节能减排PPT模板分享
  5. Unity 截取摄像头圆形区域并保存 By Opencv
  6. 软件缺陷和软件缺陷的种类
  7. 如何合并表格的简单操作
  8. CTF中 Crypto(密码学)在线解密网站
  9. 校园网自动登陆(河南科技学院)
  10. this application requires.net framework4.0,please install the.net framework then run this installer