iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 16
1

今日目標

花了好幾天終於完成登入,但還是有一些地方怪怪的,譬如說剛登入進去應該要看到 recent activity,但我們自己架在 localhost 的 Phish Github 卻看不到,今明兩天就是要解決這個問題

上圖是自己的架的 Phish Github,下圖是真正的 Github

還有哪裡沒做好嗎

我們在 Day11 ~ Day13 完成了轉發 cookie,Day14Day15 完成了重新導向 Location,這些東西都是包含在 HTTP header 裡面的,但其實 header 裡面還包含很多其他資訊,所以筆者我猜想可能是 header 內有一些驗證用的資料 我們沒有轉發,所以才會造成錯誤

關於 header 轉發會分成兩部分,今天要做的是 把來自瀏覽器的 header 轉發給 Github ,也就是圖中的第二步,而明天要做的是 把來自 Github 的 header 轉發給瀏覽器

Request 裡面有哪些 header

在把 header 轉發給 Github 前先來看一下裡面有啥(下圖),除了我們先前已經處理完的 cookie 之外還有一堆有的沒的,其中最重要的兩個是 OriginReferer

  • Origin

    origin 是目前網站的 <schema>://<host>:<port> 組合而成的字串,譬如說在 Github 上那 origin 就是 https://github.com,在自己架的 localhost 就是 http://localhost:8080

  • Referer

    referer 是 當你發出請求時網頁在哪個網址 ,譬如說在 Github 發出登入請求時一定是在登入頁面,那 referer 就是 https://github.com/login

這些 header 之前都沒有轉傳給 Github,所以 Github 只要判斷收到的 header 內沒有 OriginReferer 就可以知道這個人 不是正常的使用者 ,進而把請求檔掉

想要偽裝成正常的使用者就要把 header 也轉傳給 Github,但現在 OriginReferer 寫的是 localhost 而不是 github.com,如果把這個 header 原封不動轉傳給 Github,那還是會被 Github 發現我們正在假冒他的網站,所以在轉傳的過程中要把 OriginReferer 取代掉

把來自瀏覽器的 header 轉發給 Github

在複製請求時一併複製 header,然後再把 OriginReferer 取代一下讓 Github 辨認不出來

func cloneRequest(r *http.Request) *http.Request {
    // ...

    // 複製整個 request header
    req.Header = r.Header
  
    // 取代 header 中的 Origin, Referer 網址
    origin := strings.Replace(r.Header.Get("Origin"), phishURL, upstreamURL, -1)
    referer := strings.Replace(r.Header.Get("Referer"), phishURL, upstreamURL, -1)
    req.Header.Set("Origin", origin)
    req.Header.Set("Referer", referer)

    // ...
  
    return req
}

這樣可能會有什麼問題?

header 中有個 Accept-Encoding,這代表瀏覽器告訴 Github 說「我可以接受 gzip 壓縮過的內容」,等瀏覽器收到內容再自己解壓縮,藉以節省網路傳輸的時間

但大家還記得在 Day10-替換頁面中的網址 中我們把網址替換掉嗎,如果我們收到的內容是 gzip 壓縮過的,那就得先自己解壓縮才能取代網址,為了省麻煩我們就直接告訴 Github 說「我不能接受 gzip 壓縮過的內容」,這樣 reverse proxy 收到的內容就會跟原本一樣是沒壓縮過的 HTML 明碼

說了這麼多到底該怎麼做呢?其實就在複製請求時把 Accept-Encoding 刪掉就可以了,這樣 Github 就會回覆沒壓縮過的 HTML,我們也可以輕易的取代網址

func cloneRequest(r *http.Request) *http.Request {
    // ...

    req.Header.Set("Origin", origin)
    req.Header.Set("Referer", referer)
    
    // 直接把 Accept-Encoding 刪掉
    req.Header.Del("Accept-Encoding")

    // ...
}

但沒有用 gzip 網站速度不是會變慢嗎??

對阿,但只是釣魚網站而已不用太講究,再說你在看 Demo 時有覺得很慢嗎,沒有的話那代表其實影響也沒有很大嘛XD

小結

今天的 commit 在這裡,實作了怎麼把 HTTP header 轉發給 Github 還有稍微講解 gzip,整體內容偏難,如果有什麼地方看不懂可以多看幾次,或是在下面留言我也會盡量回答大家,明天要繼續實作 把來自 Github 的 header 轉發給瀏覽器 ,都沒問題的話就明天見囉

參考資料


上一篇
Day15-HTTP Redirect II(實作篇)
下一篇
Day17-轉發 HTTP header II
系列文
Go Phishing!30 天用 Go 實作 Reverse Proxy 之釣魚大作戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
minchao
iT邦新手 5 級 ‧ 2018-11-11 22:57:33

看了一下 golang 的原始碼,其實當請求沒指定 Accept-Encoding 時,Transport 會自己加上去,預設使用 gzip,也會自動 uncompress 回應的內容。請參考:

https://github.com/golang/go/blob/da6c168378b4c1deb2a731356f1f438e4723b8a7/src/net/http/transport.go#L2099-L2122

// Ask for a compressed version if the caller didn't set their
// own value for Accept-Encoding.

題外,若想要強制關閉壓縮,可以加上 DisableCompression 設定:

http.DefaultTransport.(*http.Transport).DisableCompression = true

哦哦太厲害了~竟然可以翻到 Go 的原始碼,剛剛看了一下真的是你說的這樣,很謝謝你的補充

我要留言

立即登入留言