[ksnctf] Digest is secure!

ksnctfにチャレンジ 第9問目です。

※ksnctfは常駐型のCTFサイトです。 ※問題のページはコチラです。

Digest is secure!

前問の発展版でBasic認証の代わりにDigest認証が使われています。 Digest認証では一度サーバーにアクセスして nonce と呼ばれるランダムな文字列を 得た上で、必要情報を適切に hach化するなどして通信する必要があります。 これはCurlでどうにかするのは難しいので Rubyで行きます。

キャプチャデータから nonce 以外のデータを抜き出しておき 最後に nonce だけ実際にサーバーから貰って認証することができます。

ちなみにここに書かれていますが、flagは flag.txt に記載されています。

require 'uri'
require 'net/http'
require 'digest/md5'

username   = "q9"
realm      = "secret"
#nonce     = 
uri        = URI.parse("http://ctfq.sweetduet.info:10080/~q9/flag.html")
algorithm  = "MD5"
#response  = 
qop        = "auth"
nc         = "00000001"
cnonce     = "9691c249745d94fc"

a1         = "c627e19450db746b739f41b64097d449"
a2         = Digest::MD5.hexdigest("GET:#{uri.path}")

http = Net::HTTP.new( uri.host, uri.port)
http.start {
    hello = http.get( uri.path)
    nonce = hello['WWW-Authenticate'].match(/nonce="(.*),"/)[1]

    response = Digest::MD5.hexdigest("#{a1}:#{nonce}:#{nc}:#{cnonce}:#{qop}:#{a2}")

    header = { "Authorization" => %(Digest username="#{username}", realm="#{realm}", nonce="#{nonce}", uri="#{uri.path}", algorithm=#{algorithm}, response="#{response}", qop=#{qop}, nc=#{nc}, cnonce="#{cnonce}") }

    flag = http.get( uri.path, header)
    puts flag.body
}

まず hello で一旦サーバーに挨拶して 応答内の nonce だけ抜き出してきます。 あとはルール通りに response を計算すればOKです。