聲明:本人堅決反對利用文章內容進行惡意攻擊行為,一切錯誤行為必將受到懲罰,綠色網絡需要靠我們共同維護,推薦大家在了解技術原理的前提下,更好的維護個人信息安全、企業安全、國家安全。

一、什么是域名泛解析

域名泛化解析是指:利用通配符* (星號)來做次級域名以實現所有的次級域名均指向同一IP地址。在域名前添加任何子域名,均可訪問到所指向的IP地址。例如:

(1)常規域名解析

www.wolke.cn   10.10.10.10

(2)域名泛解析

*.wolke.cn     10.10.10.10

訪問子域名a.wolke.cn,b.wolke.cn等均指向10.10.10.10

二、為什么要解決子域名泛化問題

在子域名解析中,每個子域名都會解析為一個特定的IP地址。只有被設置解析,用戶才能正常進行訪問。一旦用戶輸入錯誤的子域名,就會造成無法訪問。在網站運營中,域名持有者為了避免因為錯誤輸入,而造成用戶流失,就會使用泛域名解析。泛域名解析是一種特殊的域名解析方式。它使用通配符形式,設置域名解析。它可以將沒有明確設置的子域名一律解析到一個IP地址上。這樣,即使用戶輸入錯誤的子域名,也可以訪問到域名持有者指定的IP地址。

在信息收集中,這會造成請求的所有子域名都能訪問的假象,從而收集到一堆無效的子域名。這為我們去做子域名爆破帶來了極大的不便,以前子域名爆破常用的是layer子域名挖掘機。不過layer子域名挖掘機在跑具有泛解析的站的時候,就不是那么適用。

三、域名泛解析對抗

這里以淘寶和百度為例子:ping一個絕對隨機不可能存在的域名,它解析了,那么說明它大概率使用了泛解析

(1)淘寶可能存在域名泛解析??

(2)百度可能不存在域名泛解析??

針對百度,我們可以直接使用layer子域名挖掘機等子域名爆破工具,而針對淘寶的資產,我們不能使用layer子域名挖掘機等常規工具

1、判斷是否使用了泛解析,五次完全隨機的域名前綴A記錄解析

import asyncioimport aiodnsimport random
loop = asyncio.get_event_loop()resolver = aiodns.DNSResolver(loop=loop)
async def query(name, query_type):    return await resolver.query(name, query_type)
def random_to_A(main_domain):    total = []    # 隨機循環五次    for i in range(5):        sub_domain = "".join(random.sample('abcdefghijklmnopqrstuvwxyz', random.randint(8, 12)))        res = query(sub_domain + "." + main_domain, 'A')        result = loop.run_until_complete(res)        total.append(result)    return total
if __name__ == '__main__':    main_domain = input("Please input the main_doamin: ")    print(str(random_to_A(main_domain)).replace("],", "],"))

五次完全A記錄解析成功,認為存在泛解析,如果不存在泛解析問題,就常規子域名收集一把梭,如果檢測出泛解析,就使用破泛解析的子域名爆破工具。

2、CNAME查詢黑名單,維護特定廠商CNAME列表

CNAME查詢幾個不存在的淘寶域名,也是一樣的思路,循環多次不存在的域名,如果訪問不存在的域名,CNAME為shop.taobao.com

3、A記錄查詢命中次數,如果A記錄查詢,命中相同ip>10,后續的爆破A記錄解析的域名就不展示記錄

四、腳本源碼

import asyncioimport aiodnsimport randomimport optparse
loop = asyncio.get_event_loop()resolver = aiodns.DNSResolver(loop=loop)
async def query(name, query_type):    return await resolver.query(name, query_type)
def random_to_A(main_domain):    total = []    # 隨機循環五次    for i in range(5):        sub_domain = "".join(random.sample('abcdefghijklmnopqrstuvwxyz', random.randint(8, 12)))        res = query(sub_domain + "." + main_domain, 'A')        result = loop.run_until_complete(res)        total.append(result)    return total
def random_to_cname(sub_domain):    res = query(sub_domain, 'CNAME')    result = loop.run_until_complete(res)    return result
if __name__ == '__main__':    parser = optparse.OptionParser("%prog " + "[options] [domain]")    parser.add_option('-a', action="store", dest='main_domain', type='string', help='')    parser.add_option('-c', action="store", dest='sub_domain', type='string', help='')    (options, args) = parser.parse_args()    main_domain = options.main_domain    sub_domain = options.sub_domain    if main_domain:        print(str(random_to_A(main_domain)).replace("],", "],"))    elif sub_domain:        print(str(random_to_cname(sub_domain)).replace("<", "<"))