ksnctfを使ってHTTP通信について学ぶ④(python・ksnctf-9)

前回、pythonでHTTPリクエストメッセージを作り、HTTPレスポンスメッセージを表示させた。
これを用いて、ksnctfの問9を解いてみる。
ksnctf - 9 Digest is secure!


認証を行ってflag.htmlにアクセスすればいいことまではわかっている。
Authorizationヘッダを付けたHTTPリクエストメッセージをつくって、HTTPレスポンスメッセージを表示させてみる。


①Authorizationヘッダを作る
Authorizationヘッダを作るためにはnonceが必要である。リクエストメッセージを送り、nonceを得る。
ハッシュの作成にはhashlibライブラリを使う。

import requests
import hashlib

url="http://ctfq.sweetduet.info:10080/~q9/flag.html"

nonce = requests.get(url).headers["WWW-Authenticate"].split(" ")[2][7:-2]
a1="c627e19450db746b739f41b64097d449"
nc="00000001"
cnonce="9691c249745d94fc"
qop="auth"
a2=hashlib.md5(b"GET:/~q9/flag.html").hexdigest()

res=hashlib.md5((a1+":"+nonce+":"+nc+":"+cnonce+":"+qop+":"+a2).encode('utf-8')).hexdigest()

key='Digest username="q9", realm="secret", nonce="'+nonce+'", uri="/~q9/flag.html", algorithm=MD5, response="'+res+'", qop=auth, nc=00000001, cnonce="9691c249745d94fc"'


②HTTPリクエストメッセージを送る。
前回のコードに上記の認証を加える。

headers={
'Host': 'ctfq.sweetduet.info:10080',
'Connection':'keep-alive',
'Authorization': key,
'User-Agent': 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.162 Safari/535.19',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Encoding': 'gzip,deflate,sdch',
'Accept-Language': 'ja,en-US;q=0.8,en;q=0.6',
'Accept-Charset': 'Shift_JIS,utf-8;q=0.7,*;q=0.3',
}

r=requests.get(url, headers=headers)


③HTTPレスポンスメッセージを得る。

print(r.status_code)
print(r.headers)
print(r.text)

(実行結果)

> python .\sample.py
200
{'Date': 'Tue, 21 Jan 2020 09:56:55 GMT', 'Server': 'Apache/2.2.15 (CentOS)', 'Authentication-Info': 'rspauth="ed70106349d8d9e632ae77641a40a1b7", cnonce="9691c249745d94fc", nc=00000001, qop=auth', 'Last-Modified': 'Sat, 26 May 2012 12:29:31 GMT', 'ETag': '"422e3-90-4c0efa30418d3"', 'Accept-Ranges': 'bytes', 'Content-Length': '144', 'Connection': 'close', 'Content-Type': 'text/html; charset=UTF-8'}
<!DOCTYPE html>
  <head>
    <meta charset="utf-8">
    <title>Q9</title>
  </head>
  <body>
    <p>(フラグ)</p>
  </body>
</html>


下記のドキュメントを参考にした。
Requests: 人間のためのHTTP — requests-docs-ja 1.0.4 documentation


(間違い等あればコメントよろしくお願いいたします。)