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です。