【从零开始写漏扫】主机发现——自己动手写一个子域名挖掘器

【从零开始写漏扫】主机发现——自己动手写一个子域名挖掘器,第1张

目录

前言 

正文

字典爆破

单线程

多线程

搜索引擎收录

在线平台查询

证书日志查询

DNS域传送漏洞

结语

前言 

        终于有时间将自己所学与实践经验系统性复盘,这是第一个系列,将渗透测试的常见流程总结并编码出来。

        实践是检验真理的唯一标准,于是萌生了写这篇专栏的念头。只有真正理解相关技术,并将其编码出来,才算是将学到的东西消化吸收,而不是莽撞的脚本小子。

        人生苦短,我用Python,信息安全的每一个领域都值得去深入探索,前期我会力求使用Python内置函数实现基本需求。但限于篇幅,本系列并不排斥使用现有的框架和技术,力求将每一个环节最基本的方法用脚本编写出来。

        阅读本系列内容,你需要:

1.一定的Python基础

2.了解git,会使用gitee下载并查看代码

3.一定的代码阅读能力

4.使用搜索引擎查阅专业名词的能力

正文

        对目标系统进行测试的第一步,就是通过了解目标的域名,进一步了解目标的资产信息,

        域名(Domain Name),是由一串用点分隔的名字组成的,Internet上某一台计算机或计算机组的名称,用于在数据传输时对计算机的定位标识。域名有级别之分,可以分为顶级域名(一级域名)、二级域名、三级域名、多级域名。子域名,是顶级域名的下一级。

        在一般的测试实践中,企业尝尝会配置多个域名以满足不同系统的要求,这就为我们搜集资产信息提供了便利。通常来说,一个系统的主域名防御力非常强,而子域名对应的系统往往是一些内部人员使用或无关紧要的服务,防护相对来说弱很多。通过收集的子域名寻找阿喀琉斯之踵,从子系统入手,进一步渗透更加容易成功。

         这里总结一些常见的搜集方法。

字典爆破

        最简单粗暴的方法,通过字典枚举每一个域名的解析情况,达到查询所有字域名的效果。获得的结果与字典直接相关,那么字典的选取就显得十分重要。字典的主要来源如下:

  1. 通用字典
  2. 域名解析商公布使用最多的子域名
  3. 其它域名爆破工具字典

        这里使用服务商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群,群文件中可能会包含一些敏感的信息。这方面的信息收集能够帮助我们进一步筛选内部系统。

在线平台查询

        可使用的平台较多,配合爬虫,同样有不错的挖掘效果,但仍然受制于第三方系统的查询能力,同时也不一定能够保证时效,这里就仅列出一些平台供选择

  1. ip138
  2. 站长工具
  3. Hackertarget
  4. Phpinfo
  5. t1h2ua
  6. dnsdumpster
  7. chinacycc
  8. zcjun
  9. 爱站
  10. 全国政府网站基本数据库
  11. WebScan
  12. Bufferoveryvf
  13. RapidDNS
  14. Dnsdb
  15. 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上,项目地址点这里。下一篇文章中,我将尝试着自己手写一个端口扫描器,进一步探测主机所开放的端口信息。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/727316.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-26
下一篇 2022-04-26

发表评论

登录后才能评论

评论列表(0条)

保存