
TJ O'Connorの書籍「Violent Python」のソースコード。このコードは完全にPython 3に変換され、PEP8規格に準拠するよう再フォーマットされ、非推奨ライブラリの実装に起因する依存関係の問題を解消するためにリファクタリングされています。
TJ O'Connor 著の書籍「Violent Python」のソースコードです。コードは完全に Python 3 に変換され、PEP8 標準に準拠するようにフォーマットされ、非推奨ライブラリの実装に伴う依存関係の問題を解消するためにリファクタリングされています。
これと同様の変換を、Justin Seitz 著の書籍「Black Hat Python」のソースコードについても私自身が行っています。まだご覧になっていない方は、こちらをご確認ください。
プロジェクト用の新しいディレクトリ (DIR) を作成し、その中に仮想環境または venv を作成することを推奨します。その後、git clone でこのリポジトリをクローンし、pip install で要件をインストールします。
user@host:~/DIR$ git clone https://github.com/EONRaider/violent-python3
user@host:~/DIR$ python3 -m venv venv
user@host:~/DIR$ source venv/bin/activate
(venv) user@host:~/DIR$ pip install -r requirements.txt
optparse ライブラリは、ソースコード全体で argparse に置き換えられました。すべての引数解析は、各ファイルの __main__ 実行スコープに含まれています。元のコードではオプションとして扱われていた、スクリプト実行に必須だった CLI 引数は、すべて位置引数として実装されています。-h 引数を CLI に指定することで、argparse を使用するすべてのスクリプトで使用法のプロンプトが利用可能になりました。CLI パーサーに境界オブジェクトと制御オブジェクトの両方の役割を任せることは、ソフトウェアアーキテクチャの観点からは決して最善の選択ではありませんが、元のコーダーの意図に準拠する必要があるため、そのままにしています。PEP 8: E722 do not use bare except 違反のすべての発生箇所は、より具体的な例外句でリファクタリングされています。close() メソッドを呼び出さない習慣があります。そのため、ファイルおよびデータベース操作のすべてのインスタンスは、コンテキストマネージャーを使用してリファクタリングされています。# -*- coding: utf-8 -*-)の使用は、Python 3 のデフォルトエンコーディングとして UTF-8 が標準化された(Python 2 の ASCII から置き換え)ため、削除されました。以下にリストされていないファイルは、「注意点」セクションで確立されたように、何らかの形でリファクタリングされているものとみなされます。
chapter01/vuln_scanner.py は、存在しないファイルが実行時に OSError 例外を引き起こすような構造になっていました。そのため、check_vulns() を呼び出す反復制御は、メイン関数で定義された条件文に移動されました。chapter02/nmap_scan.py は、非推奨の optparse ライブラリを呼び出すためだけにメイン関数を実装していましたが、これは argparse に置き換えられました。そのため、メイン関数は削除されました。元のコードの optparse 呼び出しの一部であった反復制御構造は、スキャンされたポートごとに nmap への新しい呼び出しが実行されるように実装されていました。サイクルの無駄を防ぐために、反復は nmap_scan 関数に移動されました。chapter02/ssh_command.py は、初期化コードが __main__ 実行スコープに移動されました。関数のパラメータ名と衝突していた外部スコープで使用されていた変数名が変更されました。返されるプロンプト情報は元々エンコードされていましたが、可読性を高めるためにデコードされました。chapter02/ssh_brute.py は、pxssh をスタンドアロンライブラリとしてインポートしていましたが、実際には pexpect ライブラリの下のライブラリです。このバグにより が発生していましたが、修正されました。本に掲載されているコードそのものは、インデントエラーが蔓延しており、使用不可能でしたが、動作可能な状態に修正されました。他の言語でのコントリビューションはこちらで確認できます:
常識として、まずは Issue を介して、このリポジトリに加えたい変更について議論してください。
ModuleNotFoundErrorchapter02/ssh_brutekey.py は、動作するために多数の事前生成されたキーを必要としました。さらに、本は読者に対して、現在は 403 応答を返す URL でそのようなキーを入手するように指示しています。そのため、キーを含む圧縮アーカイブが chapter02 サブディレクトリに追加されました。chapter02/ssh_botnet.py は、optparse への未使用のインポート文があり、削除されました。これは、このスクリプトに CLI を実装しようとして失敗した断片のように見えます。驚くべきことに、印刷版の本でもそのまま放置されていました。ボットネットを初期化してそのコマンドを発行するコードは、標準化のために __main__ 実行スコープの下に整理されました。ボットに発行される 2 つのコマンドは、不要な return 文の数を避けるために統一されました。chapter02/conficker.py は、sys ライブラリへの未使用の呼び出しを削除しました。chapter03/discover_networks.py は、単なるリファクタリングではなく再実装する必要がありました。元々、非推奨の mechanize ライブラリを使用していただけでなく、WiGLE サービスと対話する方法が現在では不要になっていました。なぜなら、WiGLE は現在 API を提供しているからです。そのため、コードは標準化され、requests ライブラリを使用して WiGLE に認証付き HTTP GET リクエストを送信する新しい wigle_print 関数が実装されました。応答は直接アクセス可能な JSON オブジェクトを返すため、re ライブラリの使用も不要になりました。API から送信されるエラーレスポンスメッセージを処理できるように、例外処理が追加されました。このスクリプトは winreg に依存しており、これは Microsoft Windows OS 上の Python インストールでのみ動作し、レジストリキーにアクセスするために実行時に管理者権限が必要です。API にアクセスするには、https://wigle.net/account にアカウントを登録する必要があります。chapter03/pdf_read.py は、非推奨の PyPDF の代わりに PyPDF4 ライブラリを使用するようになりました。本のテキスト内で特定の PDF ファイルが参照されており、それが chapter03 サブディレクトリに追加されました。chapter03/exif_fetch.py は、BeautifulSoup オブジェクトコンストラクターの呼び出しに features="html.parser" 引数が必要でした。15 行目に追加されました。このスクリプトは、画像を img HTML タグでラップする Web アプリケーションでのみ機能します(JavaScript に大きく依存する最新の Web アプリケーションでは稀な慣行です)。chapter03/skype_parse.py は、例として main.db ファイルを使用しています。便宜上、chapter03/skype_profile サブディレクトリに追加されました。chapter03/firefox_parse.py は、例としていくつかの .sqlite ファイルを使用しています。便宜上、chapter03/firefox_profile サブディレクトリに追加されました。chapter03/iphone_messages.py は、著者が提供していない iPhone バックアップファイルを参照しています。そのため、コードはリファクタリングされましたが、未テストのままです。chapter04/geo_ip.py は、非推奨の pygeoip ライブラリを使用していました。作成者によって提案されているように、代わりに geoip2 を使用する必要があります。新しく実装されたコードを本の元の実装にできるだけ近づけるよう努めましたが、geoip2 の新しいパッケージ構造とその属性に対応するために、いくつかの変更を行う必要がありました。スクリプトの実行に必要なデータベースファイルは、MaxMind からダウンロードされ、chapter04 ディレクトリで利用可能になりました。argparse を使用した CLI も実装されました。chapter04/print_direction.py は、元の実装でファイルを開く際に UnicodeDecodeError 例外を発生させました。ファイルを扱うコンテキストマネージャーに rb 引数を追加することで修正されました。chapter04/find_ddos.py は、Hivemind 攻撃の送信元アドレスを宛先として出力しており、出力が無意味になっていました。正しい dst 変数が stdout に表示されるようになりました。本では traffic.pcap というファイルが参照されていますが、著者によって提供されていないため、コードはリファクタリングされましたが、未テストのままです。chapter04/test_domain_flux.py は、著者が提供した pcap ファイルを分析する際に、未回答のリクエストが 0 であると返します。何らかの理由で、パケット自体に DNS リソースレコードフィールドの値が設定されていないため、dns_QR_test 関数の条件は常に false と評価されます。そのため、DNSRR フィールドを評価する条件が条件文から削除され、ポート 53 をソースとするすべての UDP パケットが分析されるようになりました。これによりコードの効率は低下しますが、少なくとも本で意図されたとおりの結果が出力されます。chapter05/blue_bug.py は、PyBluez ライブラリを使用しており、その インストール手順 に記載されているように、BlueZ ライブラリとヘッダーファイルを要求します。これらの依存関係は、要件として PyBluez をインストールする前にインストールする必要があります。Linux では、apt install bluetooth libbluetooth-dev コマンドを実行することで実行できます。元のコードは、存在しない client_sock オブジェクトを参照しており、phone_sock に置き換えられました。chapter05/ftp_sniff.py には、if... else 文の実装が不十分であったため、スニッフィングされたユーザー名は表示されるがパスワードは表示されないという論理上の欠陥がありました。条件文をネストされた if 句に置き換えることで修正されました。chapter05/ninja_print.py は、動作に obexftp ライブラリが必要です。このライブラリは Python 2 用に書かれており、現在まで移植も同等のものへの置き換えも行われていないため、コードは著者が書いた Python 2 バージョンのまま残されています。chapter05/__init__.py と chapter06/__init__.py は、それぞれ chapter05/dup.py と chapter06/anon_browser.py からのモジュールのインポートを可能にするために追加されました。chapter06/anon_proxy.py は、Python 3 ライブラリである MechanicalSoup で再実装されました。proxy_test.py、useragent_test.py、print_cookies.py に必要な修正を統合しています。chapter06/anon_browser.py も MechanicalSoup で再実装され、コードにいくつかの変更が加えられました。cookielib ライブラリは、AnonBrowser クラスのコンストラクタメソッドで http.cookiejar に置き換えられ、パラメータ user_agents はタプルではなく文字列のリストを受け入れるようになりました。chapter06/link_parser.py は、re と bs4 の実装を処理する新しい方法を使用してリファクタリングされました。