【从零开始写漏扫】主机发现——自己动手写一个子域名挖掘器
目录
前言
正文
字典爆破
单线程
多线程
搜索引擎收录
在线平台查询
证书日志查询
DNS域传送漏洞
结语
前言
终于有时间将自己所学与实践经验系统性复盘,这是第一个系列,将渗透测试的常见流程总结并编码出来。
实践是检验真理的唯一标准,于是萌生了写这篇专栏的念头。只有真正理解相关技术,并将其编码出来,才算是将学到的东西消化吸收,而不是莽撞的脚本小子。
人生苦短,我用Python,信息安全的每一个领域都值得去深入探索,前期我会力求使用Python内置函数实现基本需求。但限于篇幅,本系列并不排斥使用现有的框架和技术,力求将每一个环节最基本的方法用脚本编写出来。
阅读本系列内容,你需要:
1.一定的Python基础
2.了解git,会使用gitee下载并查看代码
3.一定的代码阅读能力
4.使用搜索引擎查阅专业名词的能力
为什么要设置为“仅粉丝可见” ?系列发布后文章数据异常地高,我写这个系列的目的是整理自己的知识系统,同时能帮助到真正有需求且愿意学习的人,为了防止恶意行为,设置了一个小门槛来给爬虫制造一些麻烦,我自己也能通过关注列表来筛选机器人。
正文
对目标系统进行测试的第一步,就是通过了解目标的域名,进一步了解目标的资产信息,
域名(Domain Name),是由一串用点分隔的名字组成的,Internet上某一台计算机或计算机组的名称,用于在数据传输时对计算机的定位标识。域名有级别之分,可以分为顶级域名(一级域名)、二级域名、三级域名、多级域名。子域名,是顶级域名的下一级。
在一般的测试实践中,企业尝尝会配置多个域名以满足不同系统的要求,这就为我们搜集资产信息提供了便利。通常来说,一个系统的主域名防御力非常强,而子域名对应的系统往往是一些内部人员使用或无关紧要的服务,防护相对来说弱很多。通过收集的子域名寻找阿喀琉斯之踵,从子系统入手,进一步渗透更加容易成功。
这里总结一些常见的搜集方法。
字典爆破
最简单粗暴的方法,通过字典枚举每一个域名的解析情况,达到查询所有字域名的效果。获得的结果与字典直接相关,那么字典的选取就显得十分重要。字典的主要来源如下:
- 通用字典
- 域名解析商公布使用最多的子域名
- 其它域名爆破工具字典
这里使用服务商DNSpod提供的公开子域名列表sub_domain.txt,考虑到github在国内的访问效率,这里做了国内镜像
单线程
首先,我们封装一个函数,用于读取子域名文件
def readSubDomainList():subDomainList = []try:file = open(sub_domain_filename, 'r')for line in file:subDomainList.append(line[:-1])# 这里切片的作用是去掉换行file.close()except Exception as e:print(e)return subDomainList
然后,使用读取的字段列表依次拼接域名:
def splitSubDomain(domain,subDomainList):subDomains = []for item in subDomainList:subDomains.append(item + '.' + domain)return subDomains
接下来,我们需要依次验证域名是否有解析,并返回相应的ip列表,这里使用socket包中getaddrinfo()实现。
看到这里,可能有人会问:为什么不使用socket.gethostbyname?这是因为它回显的内容太单一,无法扩展,不利于进一步的信息收集,而getaddrinfo()不仅返回IP列表,还会回显部分whois信息,这有助于未来进一步判断真实目标。
def domainToip(domain):iplist = []try:results = socket.getaddrinfo(domain , None)for item in results:# item实际蕴含域名的whois信息,这里只取用返回的ip记录iplist.append(item[4][0])except Exception as e:print("domain:" + domain + " info:")print(e)return iplist
最后,我们来组装一下:
def subDominMining(domain):accessible = []subDomainList = readSubDomainList()subDomains = splitSubDomain(domain,subDomainList)for item in subDomains:subDomain = {}iplist = domainToip(item)if len(iplist) > 0:subDomain['domain'] = itemsubDomain['iplist'] = iplistaccessible.append(subDomain)return accessible
一个简单的子域名爆破挖掘脚本就完成了,这里拿baidu.com测试一下:
效果还不错。
但有没有发现,这里很多域名能解析出多个ip,这是使用了CDN的结果。CDN 的全称是 Content Delivery Network,即内容分发网络。CDN 依靠部署在各地的边缘服务器, 通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。这里有一篇比较浅显易懂的文章讲解CDN:漫话:如何给女朋友解释什么是CDN
但在安全测试过程中,若目标存在 CDN 服务,将会影响到后续的安全测试过程。如果直接访问CDN,我们访问的可能不是源站的真实IP,只是缓存的静态站点资源。
至于CDN的判断和绕过,长度足以再写一篇文章,这里使用解析出的ip数量进行一个粗略的筛选,只需要在主要函数中增加一个判断。
def subDominMining(domain):accessible = []subDomainList = readSubDomainList()subDomains = splitSubDomain(domain,subDomainList)for item in subDomains:subDomain = {}iplist = domainToip(item)if len(iplist) > 0:subDomain['domain'] = itemsubDomain['iplist'] = iplist# 判断是否可能存在CDNsubDomain['isCDN'] = Falseif len(iplist) > 1:subDomain['isCDN'] = Trueaccessible.append(subDomain)return accessible
这样,一个简单的子域名爆破的脚本就完成了,还提供了CDN判断的功能,再使用bing.com测试一下。
这样就满足了?当然不可以!单线程的机械式扫描速度太慢了,对bing.com进行子域名挖掘,耗费了56秒,我们必须得上相控阵(多线程)!
多线程
这里使用Python内置的threading库实现多线程,将单个子域名的解析拆分为多线程类:
#结果列表:
resultList = []class DomainMinner(threading.Thread):def __init__(self,domain):threading.Thread.__init__(self)self.domain = domaindef run(self):iplist = domainToip(self.domain)subDomain = {}if len(iplist) > 0:subDomain['domain'] = self.domainsubDomain['iplist'] = iplist# 判断是否可能存在CDNsubDomain['isCDN'] = Falseif len(iplist) > 1:subDomain['isCDN'] = TrueresultList.append(subDomain)
作为一个程序员,此处应该提起应有的警惕。多线程返回的值将同时访问resultList这个列表,这导致resultList变成了临界区,需要使用线程同步机制去协调对这个列表的访问,这里使用锁机制保护临界区:
#线程锁和临界资源:
threadLock = threading.Lock()
resultList = []class DomainMinner(threading.Thread):def __init__(self,domain):threading.Thread.__init__(self)self.domain = domaindef run(self):iplist = domainToip(self.domain)subDomain = {}if len(iplist) > 0:subDomain['domsin'] = self.domainsubDomain['iplist'] = iplist# 判断是否可能存在CDNsubDomain['isCDN'] = Falseif len(iplist) > 1:subDomain['isCDN'] = True# 临界区:threadLock.acquire()resultList.append(subDomain)threadLock.release()
接下来对主函数进行相应的改动:
def subDominMining(domain):threads = []subDomainList = readSubDomainList()subDomains = splitSubDomain(domain,subDomainList)try:for item in subDomains:thread = DomainMinner(item)threads.append(thread)thread.start()for thread in threads:thread.join()except Exception as e:print(e)accessible = resultListreturn accessible
多线程版的子域名挖掘就完成了,同样对bing.com进行挖掘。
测试速度压缩到了11秒,虽然优势不明显,但在大型字典中,提高五倍的速度也是不错的优化。
学会了基本思路,对它进行优化、打包和功能拓展,就得到了一个可供渗透测试人员随时使用的成熟产品,国内镜像点这里。
有兴趣的话,可以看看最常用的爆破工具—Layer子域名挖掘机的源码。
搜索引擎收录
这个思路是通过使用第三方的搜索引擎,挖掘可被访问的站点,算是Google-Hacking在子域名挖掘领域的一种应用,在发现域名时,往往会同时发现一些敏感的页面,但收录的站点有限,下面列举一些常见的语法:
Google、百度、360、bing、搜狗等主流搜索引擎、ZoomEye:
site:baidu.com
FOFA:
domain="baidu.com"
Shodan:
hostname:baidu
这些网站配合爬虫,都能取得不错的效果,至于爬虫部分,在后文中会提到。适合在枚举后用作资产信息补充。
通过百家号、微博、抖音、快手、哔哩哔哩等媒体公众号,也可以收集到员工的账号以及不小心泄露出来的一些web服务。收集到qq群这种信息时,还可以"潜伏"到qq群,群文件中可能会包含一些敏感的信息。这方面的信息收集能够帮助我们进一步筛选内部系统。
在线平台查询
可使用的平台较多,配合爬虫,同样有不错的挖掘效果,但仍然受制于第三方系统的查询能力,同时也不一定能够保证时效,这里就仅列出一些平台供选择
- ip138
- 站长工具
- Hackertarget
- Phpinfo
- t1h2ua
- dnsdumpster
- chinacycc
- zcjun
- 爱站
- 全国政府网站基本数据库
- WebScan
- Bufferoveryvf
- RapidDNS
- Dnsdb
- Viewdns
证书日志查询
用在线平台,通过网络上的证书信息查找授权子域名,这里推荐一款工具:Findomain,使用证书透明度日志查找子域名,项目地址,国内缓存点这里
不想使用工具的话,也可以自己写爬虫查找相应信息,这里放上几个比较可靠的数据来源:
crt.shhttps://crt.sh
查询语法:https://crt.sh/?q=baidu.com
Censyshttps://www.censys.io/
查询语法:https://www.censys.io/certificates?q=baidu.com
MySSLhttps://myssl.com/baidu.com
查询语法:https://myssl.com/baidu.com
DNS域传送漏洞
DNS服务器分为:主服务器、备份服务器和缓存服务器。在主备服务器之间同步数据库,需要使用“DNS域传送”。域传送是指备份服务器从主服务器拷贝数据,并用得到的数据更新自身数据库。
若DNS服务器配置不当,可能导致攻击者获取某个域的所有记录。造成整个网络的拓扑结构泄露给潜在的攻击者,包括一些安全性较低的内部主机,如测试服务器。同时,黑客可以快速的判定出某个特定zone的所有主机,收集域信息,选择攻击目标,找出未使用的IP地址,绕过基于网络的访问控制。
基本过程:
nslookup #进入交互式shell
server dns.xx.yy.zz #设定查询将要使用的DNS服务器
ls xx.yy.zz #列出某个域中的所有域名
exit #退出
目前来看,"DNS域传送漏洞"已经很少了,但如果遇到了存在相关漏洞的内网DNS服务器,还是可以试试的。
结语
作为渗透测试的第一步,子域名挖掘给了我们非常广阔的空间,项目中所涉及到的代码我将放在gitee上,项目地址点这里。下一篇文章中,我将尝试着自己手写一个端口扫描器,进一步探测主机所开放的端口信息。
【从零开始写漏扫】主机发现——自己动手写一个子域名挖掘器相关推荐
- 【从零开始写漏扫】服务识别—自己动手写一个指纹识别器—网络特征指纹
前言 上篇文章中,我们讨论了端口扫描器的实现,编码实现了一个简单的多线程端口扫描器,从子域名挖掘到端口扫描,主机发现部分暂时结束了,今后遇到更好用的主机发现技术再作补充,接下来开始服务的识别工作. 通 ...
- 自己动手写CSDN博客提取器源码分析之三:处理网页保存为pdf文件
下面我讲下处理pdf文件的,这里我用了PD4ML来处理的,原因有几个:(1).它对CSS的支持做的很好:(2).可以处理图片(很爽吧)(3).可以处理中文,不过麻烦一些.基础的过程可以看我的另外一篇帖 ...
- 自己动手写类似酷狗播放器(5)_文件的保存和读取
对于播放器,我们希望在打开的时候,播放列表存有上一次的歌曲,不必每次去添加,就是通过文件的操作实现的. 这里要实现两个: 1.在播放器打开的时候,能自动加载上一次的歌曲信息进入Listbox,并且更新 ...
- 自己动手写类似酷狗播放器(4)_系统托盘的显示
任何一个应用程序,在开启后都会在任务栏的又下角显示一个图标,用来表示这个应用程序已经开启,比如QQ.那是如何做到 的呢?其实也是很简单,就是填充NOTIFYICONDATA结构体,这时候就需要对该结构 ...
- 自己动手写类似酷狗播放器(2)_音乐播放模块实现
上一章中,主要是介绍了WINDOWS消息机制和模板对话框的创建,其实学到现在感觉windows程序设计就是各种逻辑+API函数.所以MSDN很重要.由于整个代码太大了,所以下面系列文章中,我只讲思路以 ...
- 小学生都能读懂的区块链原理和术语介绍(故事图文)-引自《从零开始自己动手写区块链》
本文目录 1.前言 2.中心化 2.1 交易 2.2 数字货币 2.3 复式记账法 2.4 未消费交易输出 2.5 中心化 2.6 区块与区块链 2.6 创世区块 3.去中心化原理 3.1 分布式存储 ...
- 自己动手写Docker学习笔记
零.前言 本文为<自己动手写 Docker>的学习,对于各位学习 docker 的同学非常友好,非常建议买一本来学习. 书中有摘录书中的一些知识点,不过限于篇幅,没有全部摘录 (主要也是懒 ...
- 【无标题】自己动手写Docker系列 -- 6.3 手动配置容器网络(上)
简介 网络部分较为复杂,本篇先利用之前写好的基础容器和网桥部分,加上手工给容器配置网络,让其容器与宿主机网络部分功能正常,为后面程序编写打下基础 源码说明 同时放到了Gitee和Github上,都可进 ...
- 自己动手写一个推荐系统,推荐系统小结,推荐系统:总体介绍、推荐算法、性能比较, 漫谈“推荐系统”, 浅谈矩阵分解在推荐系统中的应用...
自己动手写一个推荐系统 废话: 最近朋友在学习推荐系统相关,说是实现完整的推荐系统,于是我们三不之一会有一些讨论和推导,想想索性整理出来. 在文中主要以工程中做推荐系统的流程着手,穿插一些经验之谈,并 ...
最新文章
- 51单片机怎么学啊?有推荐的网课和书籍么?
- HTML5 localStorage本地儲存
- 一个简单的Ajax开发框架
- Java线程池的拒绝策略
- 笔记-中项案例题-2017年上-风险管理
- form表单按enter键自动提交的问题
- Blazor University (4)组件 — 单向绑定
- Spring 使用Cache(转)
- C++ - STL迭代器失效
- php 各种排序算法,PHP四种常见排序算法
- html怎么绘制飞线,绘制飞线,echarts迁徙图原理
- python列表综合练习
- 面试Python时,面试官最喜欢问这些技术问题
- 解决 Android 中的 DNS 域名劫持问题
- 高级查询(mysql)
- 数学笔记27——极坐标下的面积
- 微信小程序的脚本就是c语言,新手尝试编写微信小程序(2)——我的第一个微信小程序...
- 给大家分享下仿QQ消息页面横向滑出菜单,Item内容较多的情况
- html word 批注,Word2013中显示批注的两种方法
- c++ grpc compress(deflate算法) demo编译