《Violent Python》(TJ O'Connor著)一书的源代码。该代码已完全转换为Python 3,按照PEP8标准重新格式化,并经过重构以消除涉及已废弃库实现中的依赖问题。
TJ O'Connor 所著《Violent Python》一书的源代码。代码已全面转换为 Python 3,按照 PEP8 标准重新格式化,并进行了重构,以消除因使用已弃用库而导致的依赖问题。
本人也进行了类似的转换,将 Justin Seitz 所著《Black Hat Python》的源代码转换成了 Python 3。如果你还没看过,可以点击这里查看。
只需为项目创建一个新目录(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 参数,现已实现为位置参数。现在所有使用 argparse 的脚本都可以通过向 CLI 提供 -h 参数来获取用法提示。将边界和控制器对象的职责都交给 CLI 解析器在软件架构上肯定不是最佳选择,但为了与原作者的意图保持一致,仍保留了原样。PEP 8: E722 不要使用裸 except 的情况都已重构,使用了更具体的异常子句。close() 方法。因此,所有涉及文件和数据库操作的地方已使用上下文管理器进行重构。# -*- coding: utf-8 -*-)。未在下面列出的文件可以认为已经按照“注意”部分的规定以某种方式进行了重构。
chapter01/vuln_scanner.py 的结构导致不存在的文件会在运行时引发 OSError 异常。因此,调用 check_vulns() 的迭代控制已被移入在 main 函数中定义的条件语句中。chapter02/nmap_scan.py 实现了一个 main 函数,其唯一目的是调用已弃用的 optparse 库,该库已被 argparse 替换。因此,main 函数已被移除。原始代码中作为 optparse 调用一部分的迭代控制结构实现方式导致每次扫描一个端口时都会执行一次新的 nmap 调用。该迭代已被移入 nmap_scan 函数,以避免浪费周期。chapter02/ssh_command.py 的初始化代码已被移入 __main__ 执行范围。外作用域中与函数参数名冲突的变量名已被更改。原本编码的返回提示信息现在已被解码,以提高可读性。chapter02/ssh_brute.py 将 pxssh 作为独立库导入,但实际上它是 pexpect 库下的一个库。这个错误导致 ModuleNotFoundError 异常,现已修正。书中呈现的代码本身充满了缩进错误,使其无法使用,现已修复为可运行状态。其他语言的贡献可以在这里查看:
根据常识,首先尝试通过 issue 讨论你希望对此仓库进行的更改。
chapter02/ssh_brutekey.py 需要大量预生成的密钥才能工作;此外,书中引导读者在一个目前返回 403 响应的 URL 中获取这些密钥。因此,一个包含密钥的压缩归档文件已被添加到 chapter02 子目录中。chapter02/ssh_botnet.py 中有一个未使用的 optparse 导入语句,已被移除。它看起来像是中止实现此脚本 CLI 时的遗留碎片。令人惊讶的是,即使是在印刷版中,它也被留在了那里。初始化僵尸网络并发出命令的代码已为了标准化而组织在 __main__ 执行范围内。发送给僵尸主机(bots)的两条命令已合并,以避免不必要的返回语句。chapter02/conficker.py 移除了未使用的 sys 库调用。chapter03/discover_networks.py 不得不重新实现而不仅仅是重构。它不仅使用了已弃用的 mechanize 库,而且与 WiGLE 服务的交互方式也已不再必要,因为 WiGLE 现在提供了一个 API。因此,代码已标准化,并通过使用 requests 库向 WiGLE 发送经过身份验证的 HTTP GET 请求实现了一个新的 wigle_print 函数。响应返回一个可直接访问的 JSON 对象,因此也无需使用 re 库。添加了异常处理,使脚本能够处理 API 发送的错误响应消息。请注意,此脚本依赖于 winreg,它仅能在 Microsoft Windows 操作系统下的 Python 安装中运行,并且在执行期间需要管理员权限才能访问注册表键。必须注册 https://wigle.net/account 账户才能访问 API。chapter03/pdf_read.py 现在使用 PyPDF4 库代替已弃用的 PyPDF 库。书中在文本中引用了一个特定的 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 变量。书中引用了一个名为 traffic.pcap 的文件,但作者未提供该文件,因此代码已重构但未测试。chapter04/test_domain_flux.py 在分析作者提供的 pcap 文件时,返回了零个未应答的请求。由于某种原因,数据包本身没有设置 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 使用 MechanicalSoup Python 3 库重新实现。它整合了 proxy_test.py、useragent_test.py 和 print_cookies.py 所需的修改。chapter06/anon_browser.py 也使用 MechanicalSoup 重新实现,并经历了一些代码修改。在 AnonBrowser 类的构造函数方法中,cookielib 库已被 http.cookiejar 替代,参数 user_agents 现在接受字符串列表而不是元组。chapter06/link_parser.py 通过使用处理 re 和 bs4 实现的新方式进行了重构。