文章目錄
- 免責聲明
- 個人武器開發
- 美觀輸出
- Whois查詢
- 反查ip
- 目錄掃描
- 子域名爆破
- 被動掃描
- 主動掃描(字典爆破)
- CDN檢測
免責聲明
💡 本博客絕不涉及任何非法用途。
💡 使用者風險自擔,違規后果自負。
💡 守法為先,技術向善。
💡 請合理、合法地使用網絡安全技術,共同維護一個健康、安全的網絡環境!
個人武器開發
學習項目用到的代碼以及數據已開源,喜歡的師傅可以幫忙點一下免費的💡star
💡,后續可能考慮開源自己寫的一些工具,感興趣的師傅可以耐心等待…
國內項目地址:https://gitee.com/whoisDhan/LoveTools
國外項目地址:https://github.com/whoisdhan/LoveTools
這里可以開始給你第一個安全工具起名字了,_______ <- 名字留給各位師傅替自己填
注:本章節的所有代碼放github倉庫中,作者建議各位還是去github上直接下載整個項目來學習,不用自己創建了
(如果喜歡的話可以順手點一個免費的star~后續我肯定會出一些安全工具的,各位師傅可以持續關注我的公眾號!!!)
tips:
這里先告訴各位師傅我存了兩個全局參數在root.go中,target是通用的,proxy也是通用的,同時target目標可以用逗號分隔開作為多個目標傳遞,因為我使用了StringSliceVarP函數接收參數,OK交代完畢。
美觀輸出
先對后面的終端輸出簡單的美觀裝飾一下,裝b必備,學了安全開發可以給不懂安全的朋友裝一下多是一件美事。
- 設置表頭:SetHeader(v[0])
- 啟用邊框:SetBorder(true)
- 啟用行分隔線:SetRowLine(true)
- 開啟自動換行:SetAutoWrapText(true)
- 自定義中心分隔符:SetCenterSeparator(“+”) // 即每一個列之間的分隔符
- 自定義列分隔符:SetColumnSeparator(“|”)
- 自定義行分隔符:SetRowSeparator(“-”)
當我們傳入數據調用函數的時候
輸出如下圖所示:
函數代碼如下:
func PrettyPrint(v [][]string) {table := tablewriter.NewWriter(os.Stdout)table.SetHeader(v[0]) // 設置表頭table.SetBorder(true) // 啟用邊框table.SetRowLine(true) // 啟用行分隔線table.SetAutoWrapText(true) // 開啟自動換行table.SetCenterSeparator("+") // 自定義中心分隔符,即每一個列之間的分隔符table.SetColumnSeparator("|") // 自定義列分隔符table.SetRowSeparator("-") // 自定義行分隔符// 添加數據if len(v) == 0 {//如果沒有數據,直接返回table.Render()return}for _, row := range v[1:] {// 這里v[1:]從第二行開始添加數據,第一行是表頭,因為表頭已經設置好了table.Append(row)}table.Render() // 將結果 prettily 打印到標準輸出fmt.Println("")}
Whois查詢
下載
go get -u github.com/likexian/whois
簡單測試一個域名:
t := "baidu.com"
tmp, err := whois.Whois(t)if err != nil {panic(err)}
fmt.Println(res)
這個是最簡單的用法,然后為了接收返回的結果,我創建了一個結構體來接收
但是whois返回的是整個查詢結果的原生字符串,所以只能夠自己寫正則匹配來提取內容了
代碼較多,就發核心代碼截圖來講解(所有源碼在結尾)
util文件的一些函數
-
加載動畫
-
whois主要功能
其中包含了加載動畫、正則提取、打印結果
-
運行結果
更多函數細節不用深究,后面我會給出所有源碼,而且這些函數功能其實用ai也能寫出來,不用造輪子。
反查ip
最終效果
自己在https://site.ip138.com/網站上找ip進行反查作為例子即可,很多ip都可以反查到域名
這功能在https://site.ip138.com/網站請求
-
核心函數
iprSearch
:
負責對單個域名進行ip反查
-
iprsSearch
,ipr后多了一個s區分,用來對域名列表進行ip反查
-
ipr
最終調用功能函數
-
運行結果
目錄掃描
練習項目我們這里就直接用字典掃url一層目錄即可
- 2xx 狀態碼:綠色
- 3xx 狀態碼:橙色
- 4xx 狀態碼:藍色
- 5xx 狀態碼:紅色
最終運行效果如下:
(我們僅僅做于學習,并沒有對服務器造成影響,掃了幾個請求而已哈~)
細節:
- 目錄掃描要設置禁止自動跟蹤跳轉,否則服務器有完整的302跳轉的話,你掃出來的都是200
- 超時時間建議也帶上,可控性強
- 這里其實還可以加一個延遲請求效果,比如每一個請求之間間隔多久,否則發送太快容易被服務端封禁(這里留著可以給感興趣的師傅自己寫)
- 線程設置,這里不做實現(×)
- 我們scanner讀取每一行的時候,由于可能用戶會給多個目標,所以我們的字典要指針要回到頭部進行重新讀取,seek需要第二層循環完成字典后記得將指針指向頭部
對url進行清洗
- checkHttp:檢查是否是http開頭,因為有的用戶可能會直接給一個域名
- 去除多余空格
- 去除多余
/
對不同狀態碼之間的請求路徑上色
- 這里判斷一下狀態碼的范圍即可,注意我第一個用了
IsSuccessState
,他就是判斷200~299之間的,后面就沒有了,只剩下一個IsErrorState
,他是大于400就true,不符合我們的要求
一個目標完成掃描后,我們的字典到尾部了,所以我們需要將這個指針指向頭部重新給下一個目標掃描目錄
最后給命令Run給上運行邏輯和init上添加子命令和對應的參數即可
最后就是運行go run main.go -t xxx.com,aaa.ccc
,多個目標可以用逗號隔開
(僅僅做學習,不要對服務器造成影響)
這里還有幾個狀態碼效果顏色需要找到對應的服務器返回狀態碼才行,這里就忽略了,能夠打印顏色就表示成功了。
子域名爆破
這里有一個細節要注意:
-
由于子域名爆破中主動掃描要用到dict字典,之前在目錄掃描中也有一個字典,為了方便,使用同一個參數就合并起來了,放到root中作為全局參數
同時為了更容易區分和防止子命令撞參數就把全局的短選項參數更改為大寫
-
同時也在root添加了yaml配置文件變量名
-
被動掃描用的是subfinder提供出來的sdk進行開發,下載的時候需要注意go get是否能下載到,下載不了可能你是更改成為了其他加速的地址需要更改回來官方的:
具體要看你能不能下載,下載失敗就要更改回官方的
go env -w GOPROXY=https://goproxy.io,direct
<- 這是官方的,之前可能你更改了阿里云或者其他國內加速地址
被動掃描
使用subfinder的核心接口sdk,有官方使用代碼例子:
https://github.com/projectdiscovery/subfinder/blob/dev/v2/examples/main.go
我這里寫了三個函數,將官方示例代碼小小的拆開了幾部分
-
subDomainFinder
:掃描單個域名
0.寫一個&runner.Options
結構體
1.NewRunner
創建一個runner
2.&bytes.Buffer{}
緩沖區
3.使用EnumerateSingleDomainWithCtx
進行被動掃描,參數按照官方給的用就行,這些代碼都是官方上拿的
4.改動:我將結果作為函數返回值,因為我們是對多個目標進行掃描,這里單個結果返回即可
-
對多個目標進行掃描,就是結合單個域名掃描那里進行包裝循環
-
打印結果:沒啥好說的,就看你自己需求,我這里就直接用官方給的打印方式了,唯一不同就是由于我們有加載動畫,首先不能讓加載動畫覆蓋我們的域名打印結果,所以我們在打印結果之前進行清行:
\r\033[K
,當然
主動掃描(字典爆破)
主動掃描意思是使用字典進行爆破,所以自己就能寫,可以不用subfinder的代碼,使用lookup
就能判斷域名是否有效。
我這里用了一個函數一個結構體
-
結構體
LookupResult
:
用來存儲域名和對應的ip,因為他lookup
會返回一個lookup的ip地址列表 -
bruteSubdomains
:go協程、加鎖、文件讀取、yaml文件解析都用上了,這里學習了一個新的解析格式yaml
,建議自己去看https://www.runoob.com/w3cnote/yaml-intro.html菜鳥這篇文章,短小精悍,一看就懂。
- 單個域名解析:
scanDomain
函數變量
這里還涉及到多個協程操作一個results
列表變量的問題,所以需要用到互斥鎖,否則會出現不同步的問題,可能會導致死鎖。
還有一個就是ip顯示還是不顯示的問題,這個也提取出來作為一個可選參數,畢竟我們爆破域名的時候也想看看ip(默認是不開啟)
- 為了更加定制化,所以我將url字典提取出來了,放到了yaml文件中,方便以后url字典能夠在配置文件更換
- 這里需要添加一個config.go文件存儲結構體
- 接著就是寫解析
yaml
函數,其實就是之前學的導出文件中的函數一樣,只不過函數類別換成了yaml來調用
- 因為要用
bufio.NewScanner
,在util.go文件中添加一個函數,所以要讀取url返回一個io.Reader
類型,那么就直接封裝到util.go
文件中使用了
- 本地掃描就忽略了,因為就是一個讀取文件一行一行拼接就行,下面我直接放剩下的代碼截圖
- 單個域名解析:
-
參數添加如下
所以我們可以使用的命令組合有:
subdomain -a true -T xxx.cxm
默認使用url字典主動掃描
subdomain -a true -F dict.txt -T xxx.cxm
使用字典路徑掃描
subdomain -b true -T xxx.cxm
被動掃描
subdomain -T xxx.cxm
兩個都是false的時候,默認就是被動掃描,函數代碼中有進行判斷兩個false
subdomain -i true -T xxx.cxm
加上-i組合就更多了,自己測試即可
這里貼一個運行結果
命令是:go run main.go subdomain -a true -u true -T baidu.com -i true
CDN檢測
檢測最終結果,僅做學習用途,無非法動作。
-
yaml文件添加cdn檢測節點
節點檢測方式:CDNURL/?domain=baidu.com
-> 響應返回用逗號隔開的ip列表(檢測成功) 或者檢測失敗
-
config.go文件添加屬性
-
創建
cdn.go
文件,分別寫了三個函數以及一個結構體去完成這個功能cdnInfo
就是用來存儲一個域名去多個cdn節點檢測結果的一個結果合集
所以除了domain都是string列表類型,看下圖抓包就能看到請求的完整路徑,所以知道請求路徑就知道怎么寫代碼了。
-
cdnCheck
最核心的函數:最終要的是在你config := util.ParseConfig(yamlPath)
讀取配置文件后怎么請求,其實就是很簡單,用創建好的client請求,如果狀態碼200就請求成功,否則就請求失敗,在響應結果和相應列表的append中自己修改一下即可。
- 在第二層循環的時候記得把
target
和yaml配置中的cdn歸屬地址address
添加進cdnInfo
里面即可
- 在第二層循環的時候記得把
-
cdns函數
:
就是對多個目標進行遍歷給到cdnCheck檢測即可
同時記得加上加載動畫過程
-
打印CDN結果
雙層遍歷找到cdnInfo
的結果列表,因為他就是最深一層,然后按照需求添加進去res
里面給到util.PrettyPrint
函數就行(這個函數是之前寫的,一直都有用)
-
Command結構體的Run屬性寫法:
-
最終運行結果:
正在掃描中
結果
還有其他功能在前面幾個章節的功能函數拿來就能填充進去作為一個功能參數使用,這里就不做無謂的擴展了。
Go紅隊開發暫時告一段落了,想必各位師傅已經跟著我前面幾期學下來,自己就能夠開發小工具了,告別腳本小子的第一步已經邁出,接下來師傅們就可以靠這些基礎修行了,沒想到這一個合集內容收獲了這么多師傅的光臨,讓各位見笑了,接下來我也要繼續前進,打磨技術希望后面出更好的高質量文章給各位師傅~
.......如您所見,鄙人總喜歡在最后放一些內容感謝能夠看到這里的師傅,不管是否看到這里還是劃到這里的都是一種緣分
無論如何😶竹某人非常感動還有這么師傅在看我的文章!!