0x00 前言
承接上一篇子域名枚举的艺术——被动子域枚举,此篇文章主要是介绍主动子域枚举技术,主动子域枚举经常和爆破、字典相关联,爆破是在主域之前尝试单词、字母表和数字的可能组合,以便获取被解析为IP地址的子域。有的时候,子域没法在搜索引擎上找到,在DNS聚合站点上也不可用,在这种情况下,暴力破解是找出可能被组织遗忘的子域的最佳方法,本文前半部分将从DNS协议、解析漏洞以及保护机制讲起,后半部门主要是实战中一些用来主动枚举子域名的工具,一步步的加深大家对子域名枚举的理解。
0x01爆破的两种类型
一、字典爆破
在字典爆破中,我们直接将字典列表用于强制域名以查找有效子域,但是有一个致命缺点就是流量较大。
工具:
- Aquatone (https://github.com/michenriksen/aquatone)
- Bluto-Old (https://github.com/darryllane/Bluto-Old)
- DNS-Discovery (https://github.com/m0nad/DNS-Discovery)
- Dnssearch (https://github.com/evilsocket/dnssearch)
- Amass (https://github.com/OWASP/Amass)
- Subbrute (https://github.com/TheRook/subbrute)
- subDomainBrute (https://github.com/lijiejie/subDomainsBrute)
- Sublist3r (https://github.com/aboul3la/Sublist3r)
- OneForAll (https://github.com/shmilylty/OneForAll)
- DNSBrute (https://github.com/Q2h1Cg/dnsbrute)
二、排列爆破
在排列爆破中,我们利用置换、变异和字表的修改,从已知的子域/域创建一个新的子域解析了解,缺点也是流量较大。
工具:
- altdns (https://github.com/infosec-au/altdns) (https://github.com/infosec-au/altdns) (一个比较老的工具了,去年更新过字典列表)
0x02 区域传输
DNS区域传输是将DNS数据库或DNS记录从主名称服务器复制到辅助名称服务器的过程。
只有当主名称服务器配置为将区域信息复制到任何服务器时,才能使用DNS区域传输功能。
1、为什么我要使用DNF区域传输
- 可用性
如果主名称服务器出现故障,则辅助服务器讲处理所有DNS请求。
- 负载均衡
如果发生了大量DNS名称解析请求,则辅助名称服务器负载将平衡这些请求。
- 更快
如果主名称服务器位于慢速的网络连接上,则辅助名称服务器将处理名称解析请求。
2、区域转移收集的信息类型
- 子域
- 电子邮件地址(可能有助于钓鱼)
- 当前序列号(更改序列号,可能表示组织中的变化)
- 电子邮件服务器(可以帮助钓鱼)
- 名称服务器
- loc记录披露
- 网站的ip地址
- 通过SRV记录在组织中运行的服务
3、使用命令检查区域传输
dig ns zonetransfer.me +noall +answer
host -t axfr zonetransfer.me intns1.zonetransfer.me
nslookup -type=ns zonetransfer.me
nslookup -query=AXFR zonetransfer.me nsztm2.digi.ninja
nslookup -type=ns zonetransfer.me
nslookup -query=AXFR zonetransfer.me nsztm2.digi.ninja
0x03 域名系统安全扩展(DSSEC)
域名系统安全扩展(DNSSEC)通过建立信任链来保护DNS中数据的完整性和真实性。
在了解DNSSEC之前,我们需要了解DNS的基础知识
1、DNS的功能是什么?
- DNS用于将域名转换为ip地址,反之亦然。
- DNS同时工作在TCP和UDP上,但通常在UDP端口53上工作。
- 当发送非常大的请求和响应时,例如区域传输时,使用TCP端口53。
www.example.com 192.168.1.100
192.168.1.100 www.example.com
2、为什么是DNS?
在DNS之前,我们需要定期更新host.txt文件,并将其分发到Internet上的所有主机
存在的问题就是:
- 主机文件在长时间使用后通常是巨大的
- 需要定期手动更新
- 需要维护名称的唯一性
3、DNS是怎么工作的?
在浏览器输入域名时(www.baidu.com),他首先尝试从系统主机文件解析,然后将请求传递给ISP DNS服务器,然后传递到另一个DNS服务器,此过程一直持续到请求被解析为止。当请求解析后,响应流返回到作为浏览器的原始请求者的DNS服务器,然后被请求的网站可以访问。
4、基本DNS术语
- 名称服务器
- 权威服务器
- 非权威/缓存服务器
- DNS查询
- 递归DNS查询
- 非递归或迭代DNS查询
- 逆查询
名称服务器:
(1)权威服务器
- 权威名称服务器是授权为您正在查询的域提供答案的官方名称服务器。
- 权威名称服务器可以是多个名称服务器。
- 基于管理方法((主)主和从(从)),有两种类型的权威名称服务器。
- 在主名称服务器中进行更改,辅助名称服务器将从主名称服务器检索区域文件的副本。
(2)非权威/缓存服务器
非权威名称服务器是缓存服务器,它缓存域信息,以更快地响应您正在查询的域。
DNS查询:
DNS查询在DNS服务器上配置,相应的,DNS服务器工作。
(1)递归DNS查询
在DNS服务器上配置递归查询时,DNS服务器代表您完成所有工作,以获取查询的结果。此过程中,DNS服务器可能会查询Internet上的其他DNS服务器以获得结果。
(2)非递归或迭代dns查询
当在DNS服务器上配置了非递归查询时,DNS服务器不会获取查询的完整结果,而是会给出其他DNS服务器的地址,后者可能具有查询的结果。在此过程中,DNS服务器可能会为结果提供Internet上其他DNS服务器的IP地址,操作系统解析器将进行查询,直到域名没有解析为止。
(3)逆查询
反向DNS查询与普通DNS查询相反,当用于系统将IP地址解析为完全限定域名时,将使用反向DNS查询。
0x04 DNS协议漏洞
最初的DNS协议在设计时并没有考虑到安全性,随着互联网的发展,它变得不那么值得信任了。没有DNS数据保护机制,导致以下漏洞
- DNS数据在主服务、辅助服务、解析器或转发器、缓存服务器之间传输时可能损坏
- DNS数据可能受到危害,因为主服务器可能会将DNS记录数据发送到可能处于黑客控制中的错误的辅助服务器。
- 无法查询DNS的完整性
0x05 DNS保护机制
1、基于DNS的安全配置
- 运行更新版本的DNS软件。
- 限制查询
- 防止未授权的区域转移
- 使用最少的权限运行绑定(使用chroot)
- 随机源端口
- 配置TSIG和DNSSEC
2、双保护机制 事务签名(TSIG)和DNS安全扩展(DNSSEC)用于dns数据保护
(1)交易签章(TSIG)
- TSIG保护事务以保护区域传输和动态更新。
- TSIG确保DNS查询来自正确的位置,并且不会再传输过程中被修改。
- 在主服务器和从DNS服务器上配置共享密钥。
- TSIG是在DNS服务器(named.conf)文件中配置的,而不是在区域文件中。
- 错误的密钥不允许在区域传输,因此将记录在服务器日志中。
- 命令:dig@
AXFR-k
Dig@localhost example.com AXFR-k密钥-NS1.net.+200+1337.key
(2)DNS安全扩展(DNSSEC)
- 通过确保资源记录是由区域管理员前面的记录,DNSSEC用于保护区域数据。
- 它通过建立信任链来保护区域数据的完整性和真实性。
- 它使用数字签名来验证区域数据。
(3)对于前面验证,DNSSEC添加新的DNS记录类型:
资源记录 | 完整形式 | 功能 |
---|---|---|
RRSIG | 资源记录签名 | 它包含一个加密签名。 |
DNSKEY | DNS键 | 它包含验证RRSIG所需的公钥。 |
DS | 代表团签字人 | 它包含DNSKEY记录的散列。 |
NSEC/NSEC 3 | 下一个安全 | 它指示区域中的下一个名称,它用于显式拒绝dns记录的存在。 |
(4)RRset和RRSIG
使用DNSSEC保护区域的第一步就是分组所有相同类型的记录,称为资源记录集(RRest)
RRset 示例:
www.example.com. 7200 IN A 192.168.1.100
blog.example.net. 7200IN A 10.0.1.100
admin.example.net. 7200IN A 172.16.2.200
RRSET使用区域服务器的私钥进行数字签名,签名作为RRSIG在DNS中发布。还发布了公共DNSKEY来验证RRSIG签名。
RRSIG示例:
www.example.com. 4 IN A 149.20.64.69
www. example.com. 4 IN RRSIG A 5 3 60 (
20141029233238 20140929233238 4521 isc.org.
DX5BaGVd4KzU2AIH911Kar/UmdmkARyPhJVLr0oyPZaq
jqExHZZuZ268Ntlxqgf9OmKRRv8X8YigaPShuyU=
(5)区域签名密钥(ZSK)
- 专用区域签名密钥用于对每个RRset进行数字签名,并将其存储在RRSIG中。
- 解析器使用公用区域签名密钥来验证存储在RRSIG中的数字签名。
- 公用区域签名密钥存储在DNSKEY记录中。
- 当DNSSEC解析器请求DNS记录(例如A)时,名称服务器也返回相应的RRSIG,然后DNSSEC解析器从名称服务器请求公共ZSK。
- 如果我们信任区域签名密钥,那么我们可以信任区域中的所有记录,但是如果区域签名密钥被破坏了怎么办?因此,为了验证公开的ZSK,我们使用了密钥签名密钥(KSK)。
(6)密钥签名密钥(KSK)
- KSK以ZSK验证RRSIG记录的方式验证区域签名密钥的DNSKEY记录。
- 私人KSK签署了公共ZSK和公共KSK,它们存储在DNSKEY记录中,并为DNSKEY创建一个RRSIG,存储公共ZSK和KSK的签名。
- 名称服务器将公共KSK存储在另一个DNSKEY记录中。
- DNSSEC解析器使用公共KSK验证公共ZSK。
- 在区域内建立信任。
- 密钥签名密钥(KSK)是由自己签名的,它不提供任何额外的信任,黑客可能会破坏区域并更改所有这些密钥。因此,为了完全信任,我们需要父级子信任,因为这个委托签名者(DS)记录是使用的。
(7)委托签字人(DS)记录
- 委托签名(DS)记录允许从父区域向子区域传输信任。
- 区域运算符对公共KSK进行散列,并将其分配给父区域,以便将哈希作为DS记录发布。
- 每当解析器与子区域连接时,父区域也共享它的DS记录,这使得父区域和子区域之间的信任。
- 父区域中的DS记录帮助解析器知道子区域已启用DNSSEC。
- 不应在子区域中添加DS记录。
(8)我们为什么要使用两个key?
我们使用两个密钥来保护区域本身并提供父-子信任,因为对密钥签名密钥(KSK)进行任何修改都是一个困难的过程,因为我们必须创建一个哈希并将该哈希更改为父代理签名者(DS)记录。更改DS记录是一个多步骤的过程,如果执行不当,可能会破坏区域。另一方面,更改区域签名密钥(ZSK)要容易得多。我们只需要在一个区域内修改一下。
如果黑客破坏了子服务器和父服务器,那么所有DS信息将会匹配,因此,首先要信任DNS记录,我们需要了解一下 信任链。
信任链
- 信任链通过ZSK对委托签名者(DS)记录进行签名,就像对子密钥的任何其他RRset一样,这意味着它将签名数据存储到父服务器的RRSIG中。
- 存储的DS的数字签名存储在RRSIG记录中。
- 对于信任链,验证解析器请求“.com”获取ZSK公钥、DS和签名,以验证子KSK密钥的父区域中的散列,并验证“.com”的KSK。然后解析器询问根(.)用于DS、ZSK和签名。根也遵循相同的过程。整个验证过程会重复进行,直到我们到达父方的公共KSK为止。
(9)NSEC/NSEC 3(明确否认存在)
在传统的DNS设置中,当我们向DNS请求一个不存在的域的IP地址时,它会返回一个空的结果。那么,如何验证请求的域是否存在?因为没有要签名的消息。解决此问题的方法是添加NSEC和NSEC 3记录类型,这些记录类型显式地告诉DNS解析器不存在给定区域。
NSEC记录用于证明某些东西确实不存在,方法是提供它前面的名称和后面的名称。
NSEC通过返回“Next Secure”记录来工作。NSEC记录允许证明记录类型不存在.对于现有的每个名称,都有相应的NSEC记录。此NSEC记录在排序区域文件中说明当前名称可用的类型以及下一个有效名称。这就引出了NSEC的缺点:因为NSEC记录的基本上是整个区域的链,所以可以进行“区域遍历”。
例子:
Example.com
Api.example.com
Beta.example.com
让我们假设对example.com提出了一个请求。
1.请求
Dig nsec example.com
2.响应
响应部分
example.com. 3600 IN NSEC api.example.com. A NS SOA MX TXT AAAA RRSIG NSEC DNSKEY
3。请求
dig NSEC api.example.com
4.响应
响应部分
api.example.com. 3600 IN NSEC beta.example.com. A NS SOA MX TXT AAAA RRSIG NSEC DNSKEY
同样的,黑客也可以使用它进行区域遍历并枚举区域中的所有子域。
NSEC 3使用哈希算法以“哈希”格式列出下一个可用域
(10)DNSSEC 过程
- 用户在浏览器中输入example.com访问网站。
- DNS请求传输到解析器进行DNS解析。
- 用于A记录的Resolver查询example.com名称服务器,在此查询中,解析器添加DNSSEC位,它通知名称服务器该解析器已启用DNSSEC,并且需要DNSSEC答案。
- 名称服务器已启用DNSSEC,因此名称服务器使用“A Record”的RRSIG(用于验证目的的数字签名)的RRSIG响应“A Record”查询的答案。
- 对于数字签名验证,解析器向名称服务器请求公钥,即DNSSEC(ZSK和KSK)记录。
- Nameserver响应DNSSEC(ZSK和KSK)和DNSSEC记录的RRSIG。
- DNSSEC(ZSK)记录用于验证“A记录”的RRSIG,第4步接收答案,DNSSEC(KSK)记录用于验证DNSSEC(ZSK和KSK)记录的RRSIG。
- 对于信任链,解析器查询父(.com)的DS记录,这是example.comKSK的散列。
- 父(.com)名称服务器使用DS记录和DS记录的RRSIG进行响应。
- DS记录是存储在父DS记录中的子KSK的散列值。解析器通过解密数字签名并将DS记录的哈希值与解密后的RRSIG KSK哈希值进行比较来验证KSK在子协议中的RRSIG记录。
- Resolver查询DNSKEY的.com名称服务器以验证DS记录的RRSIG。
- Parent(.com)名称服务器使用DNSKEY(ZSK和KSK)进行响应。解析器用ZSK公钥解密DS记录的RRSIG,并验证结果。KSK的RRSIG通过KSK公钥进行验证。
- 对于信任链,解析器询问根(.)对于(.)DS记录,它是.comKSK的散列。
- 根名服务器使用DS记录和DS的RRSIG进行响应。DS记录用于验证(.com)的KSK。
- 解析器查询根的DNSKEY以验证DS的RRSIG记录。
- 根名称服务器用DNSKEY响应,解析器用根ZSK解密DS的RRSIG,并比较DS值。公开根KSK用于解密ZSK的RRSIG,并对ZSK进行信任比较。如果所有的结果都被验证,那么所有的区域和记录都是可信任的。
0x06 一些常用枚举方法
1、NSEC子域枚举工具
- ldns-walk
安装:sudo apt-get install ldnsutils
命令:ldns-walk iana.org
- nsec3map
git clone https://github.com/anonion0/nsec3map.git
sudo apt-get install python python-dev python-dnspython libssl libssl-dev python-numpy python-scipy
sudo python setup.py install
- dig
kali 自带
命令:dig NSEC iana.org
2、DNS记录的子域枚举
CNAME记录
在DNS区域文件中,CNAME代表规范名称。CNAME用于在域名系统(DNS)中创建一个别名或指向另一个域名的指针。
有时CNAME会揭示一个组织子域,或者透露类似Amazon这样的第三方服务的信息。
3、SPF记录
SPF是发件人策略框架,它是一种用于白名单IP地址和域名的策略,授权它们代表您的域发送电子邮件。SPF是允许代表您的域发送电子邮件的IP地址和域的列表。
一般是如下两种情况:
- 如果发送IP地址在列表中,则电子邮件将通过SPF检查,邮件可能会被发送。
- 如果发送IP不在SPF记录上,则可能不会发送。
黑客使用这些信息来理解组织的基础结构、IP地址、第三方电子邮件服务、内部网卡和子域。SPF记录是使用TXT记录定义的。因此,无论何时搜索SPF记录,都应该由TXT记录搜索。
工具
从SPF记录中提取网卡、ASN和域名
地址:https://github.com/0xbharath/assets-from-spf
安装:
git clone https://github.com/0xbharath/assets-from-spf.git
如果缺少库 pip安装对应库即可
python assets_from_spf.py --help
4、HTTP报头的子域枚举
内容安全策略(ContentSecurityPolicy,CSP)是一个响应头,它从允许浏览器包含和执行资源的源中通知浏览器,可以使用此信息枚举组织允许的更多子域和其他域。
工具
curl (kali自带)
从csp中提取
Https://github.com/0xbharath/domains-from-csp
安装:
git clone https://github.com/0xbharath/domains-from-csp.git
pip install 安装缺少库
python csp_parser.py --help
0x07 实战中比较好用的子域名枚举工具
工具的介绍,咱就不贴图了,有手就行。
1、OneForAll(国内大佬写的,非常好用,首推)
地址:https://github.com/shmilylty/OneForAll
2、Sublist3r
地址:https://github.com/aboul3la/Sublist3r
3、subDomainBrute
地址:https://github.com/lijiejie/subDomainsBrute
4、ksubdomain(无状态域名爆破,并且快和准确)
地址:https://github.com/knownsec/ksubdomain/releases
5、massdns
地址:https://github.com/blechschmidt/massdns
6、meltego(很直观)
注册地址:https://www.maltego.com/ce-registration/?utm_source=paterva.com&utm_medium=referral&utm_campaign=301
0x08 小结
因为是对子域名进行主动枚举,这种探测可能会引起目标报警,上一篇文章中我们提到了被动子域枚举,我们可以在被动枚举获取到足够信息的情况下,再进行主动子域枚举,这将有利于进一步渗透攻击。