在我之前的文章中,我演示了一个使用 Tor 浏览器运行的 Kali Linux 容器,并使用 VNC 客户端连接到其桌面环境。我确认 Tor 浏览器在浏览会话期间连接到 Tor 网络。此设置将允许我模拟可能来自针对网站的攻击者的流量类型。
在本实验中,我将使用 Selenium 使 Tor 浏览器自动化,通过浏览器的 WebDriver 界面合成击键和导航事件。每个爬虫都会有一个由嵌入式 Tor 代理提供的随机 IP 地址,用于逃避检测。将结果保存为本地文件系统中的 JSON 对象后,我将使用 Python 将它们处理为单个 CSV 文件。最后,我将讨论在数据中心和客户端可以应用哪些对策来尝试检测、限制速率和阻止机器人活动。
所有文件和适用的许可证都可以在此开源存储库中找到: tor-driver-python
我有测试自动化背景,并且花了很多时间设计测试。我还花了很多时间使用 Selenium,并且在许多不同的编程语言和设置中使用它来自动化 Web 浏览器以进行测试。在某些情况下,只能使用真实的浏览器来测试 Web 应用程序,而 Selenium 是一个很好的工具。
在作为 DevOps 工程师的工作中,我花了很多时间担心如何处理正在攻击(有时甚至是直接攻击)我负责的 Web 应用程序的网络爬虫。我认为这一次探索这个问题的另一面将是一个有趣的实验。
我想看看出于教育目的模拟来自僵尸网络的攻击有多接近,并讨论对抗现代数据中心中可疑的 Tor 网络流量等问题的方法。僵尸网络通常用于执行撞库攻击。我将使用类似的技术来搜索查询并从网络上收集信息。
凭证填充是指将窃取的用户名和密码对(“凭证”)自动注入到网站登录表单中,以欺诈性地获取对用户帐户的访问权限。 1
为了避免道德问题,同时也尽量忠于任务。我正在对场景进行以下更改:
robots.txt
文件的网站,并且在撰写本文时检查了条款和条件,不排除抓取。例如,IMDB 的条款和条件明确禁止未经书面同意进行抓取。
机器人排除协议是网站管理员告诉爬虫它们在哪里以及不允许从哪里收集信息的一种方式。更多信息和示例可以在robotstxt.org网站上找到。我发现了一篇文章:替代搜索引擎列表,同时试图找到一个允许在搜索结果页面上进行网页抓取的引擎。以下是该研究的摘要。
搜索引擎 | robots.txt 网址 | 允许爬行吗? |
---|---|---|
没有,但有 Api | ||
没有,但有 Api | ||
不 | ||
没有,但有 Api | ||
是的,但不完全是我想要的 | ||
是的 |
我在研究该主题时发现有用的其他一些资源:
在这个例子中,我将避免使用 selenium 以外的库。我想演示一些非常基本的模式,但我不想陷入特定领域特定语言 (DSL) 的泥沼,因为这可能会让理解正在发生的事情变得更加困难。
然而,我认为使用测试运行框架是组织此类代码的好方法。添加框架可以解决围绕通用代码结构、重试逻辑甚至报告的许多问题。
我如何在 WebDriver 会话中操作页面有一个基本模式。我还会在执行每个操作后添加一个暂停。浏览器自动化可能很不稳定。超时增加了抓取的稳定性,并极大地限制了速率受限和阻塞的机会。只要有必要,我还会通过对其他搜索引擎或信息源的 API 调用来增强爬网功能。
我对选择器采取了一种非常简单的方法。我正在使用浏览器中提供的xpath和css选择器。主要关注锚标记和 URL 片段,以在爬网期间在页面之间导航。
我正在使用预期条件等待元素出现,然后再尝试单击它们。 Selenium 项目有很多文档,但我还发现Stack Overflow上有关等待条件的讨论以及示例用法是非常宝贵的资源。
现有的 PyPi 项目tbselenium具有类似的功能。对于此实验,我引用了 Firefox 配置文件设置,但不需要 tbselenium 包含的任何其他功能。没有 root 访问权限的容器的额外复杂性都导致调试变得更加困难。这增加了限制依赖性和尝试简单的现有解决方案的动机。例如,有很多地方我使用linux工具和子shell,而不是直接实现纯python解决方案。
完成的课程大约有 150 行 Python 代码。我认为深入分析正在发生的事情会更容易,而无需审查。我学到了很多关于 Tor 浏览器启动器如何工作以及如何配置 Firefox 配置文件的知识。此配置文件是从在线多个来源收集的,源代码和本文档中都提到了它们。
我将启动、拆卸和一个非常常见的导航逻辑抽象到一个名为TorDriver
的类中。这是一个非常简单的类,用于使用 Tor 浏览器启动器设置 Firefox 配置文件。它有一个方法用于检查元素在页面上是否可见,另一个方法用于验证代理套接字是否已启动并正在运行。 Firefox 配置文件设置和调试主要来自 Stack Overflow 讨论:使用 Selenium 打开 Tor 浏览器。
完整的文件可以在这里找到: tor-driver-python/torDriver.py
为安装程序和 WebDriver 组件导入 selenium、pprint、子进程和套接字。
以下方法抽象检查元素,如果元素在超时内可见,则返回True
或False
。
在向代理端口发送信号之前,代理端口需要处于活动状态。根据 Stack Overflow 中关于在 Python 中测试套接字连接的一些示例,我想出了这个:
该模块的大部分内容是控制 Firefox 配置文件、下载 geckodriver 和启动 torbrowser-launcher 的类。
这里我有一个基本的配置和一些重写的方法,但主要是尽可能简单:
Firefox 配置文件需要至少配置才能连接到代理端口,我还禁用了 javascript。
这使用 TorDriver 中的配置文件和二进制文件来初始化驱动程序
添加在子进程中下载和提取 geckodriver 的方法。值得一提的是,当在容器中运行时, tar.gz
不再被压缩,它只需要取消归档即可。有关该错误的更多信息可在此处找到: stdin: not in gzip format error
在套接字响应之前,重试与代理端口的连接:
在此示例中,我采用了以下方法两阶段方法。第一阶段是信息收集,后续阶段是信息处理。这样,我在整个过程中就不会受到网络连接的束缚,并且可以根据需要多次重试解析结果,而无需返回源材料。
完整的文件可以在这里找到: tor-driver-python/crawler.py
爬网程序读取文本文件并使用该信息来填充 WebDriver 会话中的查询。爬网的状态保存在每个查询一个 json 文件的文件夹中。我尝试进行一次导出信息所绝对必需的最少处理,并且任何后续处理都可以在现有数据中进行,而不是返回到站点。
我使用文本文件来存储搜索。我选择文本文件是因为它很容易重组。编辑文本对于开始抓取新信息或恢复中途失败的信息来说是一个很低的障碍。如果这个爬虫有更复杂的数据要求,我会考虑使用数据库。这将允许实现一个 API,用于使用自定义用户界面控制扫描和报告。
示例文件已位于存储库的结果文件夹中: tor-driver-python/results
在更强大的爬虫中,我建议使用实际的数据库技术。这足以轻松判断数据收集在哪里停止并便于重新启动。
可以使用以下命令从容器运行爬网程序。报告生成器需要存在 JSON 文件,可以在此处找到导出 CSV 文件的示例:
启动容器:
docker run -it --rm -p 5901:5901 -v "${HOME}/src":/src excitingtheory/kalilinux-xvfb:torbrowser
在容器中启动 VNC Server,它会提示输入会话密码:
/opt/start-vnc-server-once.sh
从 VNC 会话内部开始爬网:
python3 crawler.py
爬虫将等待 Tor 浏览器的初始化,不幸的是,这是一个手动步骤。只需单击复选框,然后单击连接。有关示例,请参阅视频演示。
报告脚本将从以下位置生成一个逗号分隔值 (CSV) 文件:
爬网程序在爬网过程中保存的 JavaScript 对象表示法 (JSON ) 结果文件。我选择 CSV 格式是因为它是与同事共享的更常见格式,但仍然可以轻松导入到其他工具中以进行进一步分析。
完整的文件可以在这里找到: tor-driver-python/report.py
它使用内置的 Python 库来读取 JSON、编写 CSV 并解析 URL 以进行格式化和数据呈现。然后循环访问结果并加载它们以开始数据处理。
这是报告生成器的核心功能。这对结果对象中捕获的数据进行最终呈现和排序。通常,URL 仅对爬虫在站点中进行功能性移动有用,而不是作为最终数据捕获,但它是自定义进一步数据提取的良好开端。
爬网结果以 JSON 文件形式保存在./results
目录中。我将使用以下脚本根据数据生成报告。
python3 report.py
可以在此处找到输出 CSV 文件的示例: tor-driver-python/output.csv
有几种不同的方法可以检测和缓解机器人活动。我将主要关注数据中心方面的事情,但我也会讨论一些客户端检测方法。尽管客户端信号可以随时更改并且可以被欺骗,但客户端永远无法真正被信任。我认为在设计检测系统时记住这一点很重要。在数据中心,我将讨论两种形式的保护:速率限制和信誉阻止。
有几种方法可以仅使用 javascript 来检测客户端上的活动 WebDriver 会话: Github 中的一些相关问题有更详细的介绍。本质上,由于 WebDriver 协议更改了文档和窗口对象,因此可以在客户端代码中检测到。
我将重点介绍我最有经验的解决方案:Fastly、AWS WAF 和 Nginx。 CloudFlare 完全令人惊讶,所以我也将谈论他们的产品。
AWS Web 应用程序防火墙 (WAF) 基于速率的规则还可用于阻止拒绝服务级别的活动,并且还有可用于检测 Tor 网络流量的默认规则,请参阅IP 信誉规则文档以了解更多信息。另一种常见的方法是阻止来自其他数据中心的所有流量,如果目标受众是消费者,则这是安全的。然而,企业可能会使用云 VPN 和其他技术,从而对合法流量造成损害。
Fastly 的 Signal Science 是一种非常流行的解决方案,可用于专门检测 Tor 流量。首先,他们可以防御 DDOS 攻击,请参阅他们的DDOS 缓解页面以获取更多信息。其次,他们可以检测 Tor 流量并阻止它。这是涵盖此内容的使用系统信号文档。
对于Nginx,也有一些关于执行此操作的文章: 如何使用 Nginx 或在您的 Web 应用程序内阻止匿名流量。本质上,通过调用 API 来获取有关 Tor 出口节点的信息,可以生成 IP 阻止规则并按计划应用于 Nginx。
与上述云提供商形成鲜明对比的是,CloudFlare 为 Tor 客户端提供支持。我发现了他们的Tor 支持文档!?他们讨论了从网络向 Tor 用户提供内容的能力。我认为这是一个非常有趣的方法,我渴望在未来进一步探索它。
WebDriver 是一个强大的测试工具,也可用于在无法访问 API 的地方收集信息。例如:访问受到其他限制、审查、成本过高或通常被锁定在反竞争行为背后。更好的方法是将网络爬行收集的数据与 API 收集的信息结合起来。
这是一项重要的练习,因为阻止来自机器人的恶意流量变得越来越困难,而且等到攻击发生才考虑如何缓解攻击并不是一个好的安全实践。我相信每个负责将信息发布到网上的人都应该知道泄露的信息将如何用于他们负责的系统。在一个简化的场景中,在道德约束下,我通过执行以下操作来证明这一点: