前 言
大约6 年来,我们3 个人领导了北美专用渗透测试咨询。作为首席顾问,我们代表客户执行了项目的相关技术工作,包括网络渗透测试;我们还率先开发出了更好的工具、流程和方法。在某些时候,我们采用Go 作为我们的主要开发语言之一。
Go 提供了很好的语言特性,在性能、安全性和易用性之间取得了平衡。我们在开发工具时将其作为我们的默认语言。最终,我们心甘情愿地成为这种语言的倡导者,将其推荐给我们在安全行业的其他同事。这是因为我们觉得Go 这种优秀的语言应该进入更多人的视野。
在本书中,我们将带你从安全从业人员和黑客的角度出发,全面了解Go 编程语言。
与其他黑客类图书不同的是,我们将不仅向你展示如何自动化第三方或商业工具(尽管我们会稍微讨论一下),而且将深入探讨各种具有实用价值的主题,这些主题涉及对于对抗有用的特定问题、协议或策略。此外,还将介绍TCP、HTTP 和DNS 协议,以及与Metasploit和Shodan 交互、搜索文件系统和数据库、从其他语言到Go 的漏洞移植、编写SMB 客户端的核心函数、攻击Windows、交叉编译二进制文件、加密相关的内容、调用C 库、与Windows API 交互等。
本书的适用对象
本书适用于所有想要学习如何使用Go 开发自己的黑客工具的人。在我们的整个职业生涯中,尤其是作为顾问,我们一直提倡将编程作为渗透测试人员和安全从业人员必须具备的基本技能。特别值得一提的是,编码能力可以增强你对软件工作原理及其会遭到怎样的攻击的理解。此外,如果你已经是软件程序员,则将会对他们在保护软件方面面临的挑战有更全面的了解,因而可以更好地利用个人经验来提出破解方法,消除误报并找出隐蔽的漏洞。编写代码通常会迫使你与第三方库以及各种应用程序栈和框架进行
交互。对很多人(包括我们)来说,亲自操作和不断修改才能使个人得到最大的发展。
为充分利用本书,我们鼓励你复制本书的官方代码库,这样你就拥有了我们将要讨论的所有示例(请通过https://github.com/blackhat-go/bhg/查找和下载)。
本书的不同之处
本书不是一般意义上的Go 编程介绍,而是关于使用Go 开发安全工具的介绍。我们首先是黑客,然后才是程序员。我们中没有一个人曾经是软件工程师。因此,作为黑客,我们更看重功能性而不是优雅性。在很多情况下,我们都选择像黑客一样编写代码,而忽略了软件设计的一些习惯用法或最佳实践。对于顾问来说,时间就是金钱,而开发的代码越简单,用时就越少。因此,在功能性与优雅性之间,我们选择了前者。当你需要快速创建一个问题的解决方案时,样式风格则是次要的。
这必然会激怒Go 纯粹主义者,他们可能会在推特上对我们说,你们没有优雅地处理所有的错误情况,你们的示例可以被优化,或者有更好的构造或方法来产生期望的结果。大多数情况下,我们并不关心教给你的是不是最好的、最优雅的或者百分之百理想的解决方案,当然前提是这样做不会对最终结果造成什么影响。尽管我们将简要介绍语言语法,但这样做纯粹是为了构建我们可以奠定的基线基础。事实上,我们这里想要教会你的不是如何用Go 优雅地进行编程,而是如何使用Go 开发黑客工具。
为什么要使用Go 进行黑客攻击
在Go 问世之前,你可能会使用某种动态类型语言(如Python、Ruby 或PHP)。这里你优先考虑的是其易用性,而很少会考虑其性能和安全性。另外,你还可以选择某种静态类型语言(例如C 或C++),这类语言以高性能和安全见长,但易用性不太好。Go 摆脱了其主要祖先C 的许多缺点,使开发更具人性化。同时,它是一种静态类型语言,在编译时会产生语法错误,从而极大地保障了代码在实际运行过程中的安全。与解释型语言相比,它的性能更好,且在设计时考虑了多核计算,让并发编程成为小儿科。
Go 的以上优点并没有让它得到安全从业者的垂青。然而,该语言的许多功能却给黑客和攻击者带来了“福音”。
● 整洁的包管理系统。Go 的包管理解决方案非常优雅,可以直接与Go 的工具集成。通过使用Go 二进制文件,可以轻松地下载、编译和安装包与依赖项,这样第三方库使用起来非常简单,且通常不会发生冲突。
● 交叉编译。Go 最好的特性之一是它能够交叉编译可执行文件。只要代码不与原始C 交互,你就可以很轻松地在Linux 或Mac 系统上编写代码,且以Windows友好的、可移植的可执行格式编译代码。
● 丰富的标准库。如果对开发其他语言所花费的时间有所了解,你就能更直观地感受到Go 标准库的丰富程度。许多现代语言缺乏执行一些常见任务所需的标准库,如加密、网络通信、数据库连接和数据编码(JSON、XML、Base64、hex)。
Go 将许多关键函数和库作为语言标准打包的一部分,从而减少了正确设置开发环境或调用函数所需的工作量。
● 并发。与已经存在很长时间的语言不同,Go 发布的时间和最初的主流多核技术上市的时间差不多。因此,Go 的并发模式和性能优化专门针对这个模型进行了调整。
为什么你可能不喜欢Go
同时,我们也认识到Go 并不能完美地解决所有问题。以下是该语言的一些缺点。
● 二进制文件大小。当在Go 中编译二进制文件时,二进制文件的大小可能为数兆字节。当然,你可以剥离调试符号并使用打包程序以减小体积,但要想完成这些步骤,你必须有专注力。这可能是一个缺点,特别是对于那些需要将二进制文件附加到电子邮件、托管在共享文件系统上或通过网络传输的安全从业人员而言。
● 冗长。尽管Go 没有C#、Java 甚至C/C++语言那么冗长,但你仍可能会发现,简单的语言构造会迫使你过度使用列表(在Go 中称为切片)、处理、循环或错误处理等内容。Python 的单行代码很容易在Go 中变成3 行代码。
章节内容概览
本书的第1 章概述了Go 的基本语法和原理。接下来,我们开始探索可用于工具开发的示例,包括各种常见的网络协议,例如HTTP、DNS 和SMB。然后,我们深入研究渗透测试人员遇到的各种手段和问题,解决包括数据窃取、数据包嗅探和漏洞利用开发在内的主题。最后,我们简短讨论了如何创建动态的、可插入的工具,并且深入研究加密技术以及如何攻击Microsoft Windows 和实现隐写术。
许多情况下,你都有机会扩展我们展示给你的工具以实现特定目的。尽管我们始终提供可靠的示例,但我们的真正目的是为你提供知识和基础,而你则可以此为基础来扩展或重新开发示例以实现你的目标。授之以鱼,不如授之以渔——这就是我们的追求。
在继续阅读本书接下来的内容之前,请务必牢记这一点:我们(作者和出版商)创作的内容仅供合法使用。我们不会为你选择实施的邪恶或非法行为承担任何责任。这里的所有内容仅用于教育目的;未经授权,请勿对系统或应用程序进行任何形式的渗透测试。
以下是对每一章内容的概述。
第1 章:Go 语言基础
该章介绍Go 编程语言的基础知识,以帮助你理解本书中的概念。这包括对Go 的基本语法和习惯用法的简要介绍。除此之外,我们还将讨论Go 生态系统,包括支持工具、IDE、依赖管理等。对编程语言不熟悉的读者可以在学习了Go 的一些基本知识后,更好地理解、实现和扩展后续章节中的示例。
第2 章:TCP、扫描器和代理
该章介绍Go 的基本概念、并发基础和模式、输入/输出(I/O)以及如何通过实际TCP应用程序使用接口。我们将首先引导你创建一个简单的TCP 端口扫描器,它使用解析的命令行选项扫描列表中的端口。这能让你直观地感受到Go 代码相较其他语言的简单性,并且有助于你理解基本类型、用户输入和错误处理。接下来,我们将讨论如何通过引入并发功能来提高此端口扫描器的效率和速度。然后,我们将通过构建一个TCP 代理(一个端口转发器)引入I/O 的相关知识:从基本示例开始,通过改进代码创建一种更可靠的解决方案。最后,我们将在Go 中重新创建Netcat 的“安全巨洞”功能,教你如何在操作stdin 和stdout 以及通过TCP 重定向它们时运行操作系统命令。
第3 章:HTTP 客户端以及与工具的远程交互
HTTP 客户端是与现代Web 服务器架构交互的关键组件。该章将向你展示如何创建执行各种常见Web 交互所需的HTTP 客户端。你将使用多种格式与Shodan 和Metasploit进行交互。此外,我们还将演示如何使用搜索引擎,以及使用它们来获取和解析文档元数据,以便提取对组织分析活动有用的信息。
第4 章:HTTP 服务器、路由和中间件
该章介绍创建HTTP 服务器所需的概念和约定。我们将讨论常见的路由、中间件和模板样式,利用这些知识创建凭证收割服务器和键盘记录器。最后,我们将演示如何通过构建反向HTTP 代理来复用C2 连接。
第5 章:DNS 利用
该章将介绍DNS 的基本概念。首先,将执行客户端操作,包括如何查找特定的域记录。然后将向你展示如何编写一个自定义的DNS 服务器和DNS 代理,这两个都对C2操作很有用。
第6 章:与SMB 和NTLM 交互
我们将探索SMB 和NTLM 协议并以此为基础讨论在Go 中的协议实现。我们将使用SMB 协议的部分实现讨论数据的编组和解组、自定义字段标签的使用等。此外,我们还将讨论并演示如何使用SMB 协议的部分实现检索SMB 签名策略以及进行密码猜测攻击。
第7 章:滥用数据库和文件系统
掠夺数据是对抗测试的一个关键方面。数据存在于众多资源(包括数据库和文件系统)中。该章介绍了在各种常见的SQL 和NoSQL 平台上进行连接和与数据库交互的基本方法。你将学习连接到SQL 数据库和运行查询的基本知识。我们将向你展示如何在数据库和表中搜索敏感信息,这是在后渗透阶段使用的一种常见技术。我们还将演示如何遍历文件系统和检查文件中的敏感信息。
第8 章:原始数据包处理
我们将向你展示如何使用基于libpcap 的gopacket 库来嗅探和处理网络数据包。你将学习如何识别可用的网络设备、如何使用数据包过滤器以及如何处理这些数据包。然后我们将开发一个端口扫描程序,它可以通过各种保护机制(包括syn-flood 和syn-cookies)可靠地进行扫描,但这些机制会导致正常的端口扫描出现过多的误报。
第9 章:编写和移植利用代码
该章几乎只关注漏洞利用。首先创建一个模糊器来发现不同类型的漏洞。该章的后半部分将讨论如何从其他语言移植现有的漏洞利用到Go 中。要讨论的内容包括如何移植Java 反序列化利用和脏牛(Dirty COW)提权利用。我们将在该章结束时讨论如何创建和转换shellcode 以便用在Go 程序中。
第10 章:Go 插件和可扩展工具
我们将介绍两种不同的创建可扩展工具的方法。Go 1.8 版中引入的第一种方法是使用Go 的本地插件机制。我们将讨论这种方法的用例并讨论另外一种利用Lua 创建可扩展工具的方法。我们将演示一些实例,以阐释如何选择合适的方法来执行一个常见的安全任务。
第11 章:针对密码学的攻击和实现
该章将介绍有关如何使用Go 进行对称和非对称加密的基本知识,使得你能够通过标准Go 包来使用和理解加密技术。Go 是少数几种不使用第三方库进行加密而是在语言中使用本地实现的语言之一。这使得代码易于导航、修改和理解。
我们将通过检查常见用例和创建工具来探索标准库。该章将向你展示如何执行散列、消息验证和加密。最后,我们将演示如何对RC2 加密密文进行暴力破解。
第12 章:Windows 系统交互与分析
在有关攻击Windows 的讨论中,我们将演示与Windows 本地API 交互的方法,探索syscall 包以执行进程注入,并且学习如何构建可移植可执行(Portable Executable,PE)二进制解析器。该章最后将讨论如何通过Go 的C 互操作机制调用本地C 库。
第13 章:使用隐写术隐藏数据
隐写术是将信息或文件隐藏在另一个文件中。该章介绍隐写术的一种变体:在PNG图像文件的内容中隐藏任意数据。这些技术对于过滤信息、创建混淆的C2 消息以及绕过检测或预防性的控制非常有用。
第14 章:构建一个C2 远控木马
最后一章将讨论Go 语言中C2 植入程序和服务器的实际实现。我们将利用前面章节所学的知识来构建C2 通道。C2 客户机/服务器实现由于其定制性质,将规避基于签名的安全控制,并且试图绕过启发式和基于网络的出口控制。