前言目录
前言
正文
字典爆破
单线程
多线程
搜索引擎收录
在线平台查询
证书日志查询
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'] = item
subDomain['iplist'] = iplist
accessible.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'] = item
subDomain['iplist'] = iplist
# 判断是否可能存在CDN
subDomain['isCDN'] = False
if len(iplist) > 1:
subDomain['isCDN'] = True
accessible.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 = domain
def run(self):
iplist = domainToip(self.domain)
subDomain = {}
if len(iplist) > 0:
subDomain['domain'] = self.domain
subDomain['iplist'] = iplist
# 判断是否可能存在CDN
subDomain['isCDN'] = False
if len(iplist) > 1:
subDomain['isCDN'] = True
resultList.append(subDomain)
作为一个程序员,此处应该提起应有的警惕。多线程返回的值将同时访问resultList这个列表,这导致resultList变成了临界区,需要使用线程同步机制去协调对这个列表的访问,这里使用锁机制保护临界区:
#线程锁和临界资源:
threadLock = threading.Lock()
resultList = []
class DomainMinner(threading.Thread):
def __init__(self,domain):
threading.Thread.__init__(self)
self.domain = domain
def run(self):
iplist = domainToip(self.domain)
subDomain = {}
if len(iplist) > 0:
subDomain['domsin'] = self.domain
subDomain['iplist'] = iplist
# 判断是否可能存在CDN
subDomain['isCDN'] = False
if 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 = resultList
return 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上,项目地址点这里。下一篇文章中,我将尝试着自己手写一个端口扫描器,进一步探测主机所开放的端口信息。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)