本記事は、オライリージャパンから発行されている「サイバーセキュリティプログラミング ―Pythonで学ぶハッカーの思考(原題:Black Hat Python)」の学習メモとして、書籍ではPython2で書かれていますが、自分なりに解釈した上でPython3に書き直しをしています。
5章からはWebサーバへの攻撃に主眼を置き、今回はHTTPのリクエストを行うためのモジュール操作について学んでいきます。
PythonでHTTPリクエストを行うモジュールたち
前回までにPythonのソケットライブラリを使用して、TCP通信のやり取りを学びました。
このsocketを使って自力でHTTPの仕様に沿ったコーディングも可能なのですが、PythonではHTTPでのデータのやり取りを簡単に行うことができるモジュールがあります。
それらは、requestsとurllibおよびurllib2の3つです。
書籍ではurllib2を使ったコーディングがされていますが、このモジュールはPython3系では廃止され、urllib.requestsおよびurllib.errorに解体されてしまいます(書籍はPython2系でコーディングされています)。
urllibは標準ライブラリとしてインストールされていますが、ここではrequestsを使用したいと思います。
以下が公式のドキュメントになります。
「人間のためのHTTP」を謳い、urllib2で複雑化したAPIからシンプルなAPIを目指したライブラリのようです。
requestsを使ってみる
試しにrequestsを使ってHTTPリクエストをしてみます。
以下がスクリプトになります。
# get_requests.py import requests url = 'http://127.0.0.1:8000' headers = {} headers['User-Agent'] = "Googlebot" headers['foo'] = 'bar' res = requests.get(url, headers=headers) print(res.text)
HTTPヘッダの付与や、クッキーを使ったセッション管理およびPOSTメソッドによるパラメータを受け渡しなど、様々なオプションが簡単に使えます。
しかし、JavaScriptなどのクライアント側で動くアプリケーションの操作には向いていないので、その場合はSeleniumなどのブラウザを操作できるライブラリを使ったほうが良いです。
上記のスクリプトでは、HTTPヘッダを追加しています。
"User-Agent"をGoogle Botに偽装し、新たなフィールドを追加してみました。
動作確認
前回に作成した簡易HTTPサーバに対して、上記のHTTPリクエストを送信してみます。
それでは、コマンドプロンプトを起動してサーバプログラムを起動します。
> python tcp_server.py [*] Listening on 0.0.0.0:8000
サーバが起動したら、上記で作成したスクリプトを実行し、サーバにGETリクエストをしてみます。
> python get_requests.py <!DOCTYPE html><html lang="ja"><body><p>Test Server</p></body></html>
問題なくHTMLファイルを取得することができました。
サーバ側のログからクライアントのヘッダを確認してみます。
[*] Accepted connection from: 127.0.0.1:52061 [*] Received: GET / HTTP/1.1 Host: 127.0.0.1:8000 User-Agent: Googlebot Accept-Encoding: gzip, deflate Accept: */* Connection: keep-alive foo: bar
"User-Agent"が"Googlebot"に偽装されているのと、新たなヘッダフィールドとして"foo: bar"が付与されているのが確認できました。
最後に
今回はPythonのrequestsを使ったHTTPの簡単なやり取りについて学びました。
これらのライブラリを使うことで、Webサーバ側のディレクトリ構造やどのようなファイルが存在するかの調査、または総当たり攻撃(ブルートフォースアタック)などをする際にとても役に立ちます。