前言
最近,Python 开始受到越来越多的关注,最新的 Python 更新添加了许多可用于执行关键任务的包。我们的主要目标是帮助您利用 Python 包来检测和利用漏洞,并解决网络挑战。
本书将首先带您了解与网络和安全相关的 Python 脚本和库。然后,您将深入了解核心网络任务,并学习如何解决网络挑战。随后,本书将教您如何编写安全脚本,以检测网络或网站中的漏洞。通过本书,您将学会如何利用 Python 包实现端点保护,以及如何编写取证和加密脚本。
本书适合对象
本书非常适合网络工程师、系统管理员以及希望解决网络和安全挑战的任何安全专业人士。对 Python 及其网络和安全包感兴趣的安全研究人员和开发人员也会从本书中受益匪浅。
本书涵盖内容
第一章,使用 Python 脚本,向您介绍了 Python 语言、面向对象编程、数据结构、以及使用 Python 进行开发的方法和开发环境。
第二章,系统编程包,教授您有关系统编程的主要 Python 模块,涵盖主题包括读写文件、线程、套接字、多线程和并发。
第三章,套接字编程,为您提供了使用 socket 模块进行 Python 网络编程的一些基础知识。socket 模块公开了编写 TCP 和 UDP 客户端以及服务器所需的所有必要部分,用于编写低级网络应用程序。
第四章,HTTP 编程,涵盖了 HTTP 协议和主要的 Python 模块,如 urllib 标准库和 requests 包。我们还涵盖了 HTTP 身份验证机制以及如何使用 requests 模块来管理它们。
第五章,分析网络流量,为您提供了使用 Scapy 在 Python 中分析网络流量的一些基础知识。调查人员可以编写 Scapy 脚本来调查通过嗅探混杂网络接口的实时流量,或加载先前捕获的pcap
文件。
第六章,从服务器获取信息,探讨了允许提取服务器公开的信息的模块,如 Shodan。我们还研究了获取服务器横幅和 DNS 服务器信息,并向您介绍了模糊处理。
第七章,与 FTP、SSH 和 SNMP 服务器交互,详细介绍了允许我们与 FTP、SSH 和 SNMP 服务器交互的 Python 模块。
第八章,使用 Nmap 扫描器,介绍了 Nmap 作为端口扫描器,并介绍了如何使用 Python 和 Nmap 实现网络扫描,以获取有关网络、特定主机以及在该主机上运行的服务的信息。此外,我们还介绍了编写例程以查找 Nmap 脚本中给定网络可能存在的漏洞。
第九章,与 Metasploit 框架连接,介绍了 Metasploit 框架作为利用漏洞的工具,并探讨了如何使用python-msfprc
和pymetasploit
模块。
第十章,“与漏洞扫描器交互”,介绍了 Nessus 和 Nexpose 作为漏洞扫描器,并为它们在服务器和 Web 应用程序中发现的主要漏洞提供了报告工具。此外,我们还介绍了如何使用 Python 中的nessrest
和Pynexpose
模块对它们进行程序化操作。
第十一章,“识别 Web 应用程序中的服务器漏洞”,涵盖了 OWASP 方法论中的 Web 应用程序中的主要漏洞,以及 Python 生态系统中用于 Web 应用程序漏洞扫描的工具。我们还介绍了如何测试服务器中的 openSSL 漏洞。
第十二章,“从文档、图片和浏览器中提取地理位置和元数据”,探讨了 Python 中用于从图片和文档中提取地理位置和元数据、识别 Web 技术以及从 Chrome 和 Firefox 中提取元数据的主要模块。
第十三章,“加密和隐写术”,深入探讨了 Python 中用于加密和解密信息的主要模块,如pycrypto
和 cryptography。此外,我们还介绍了隐写术技术以及如何使用stepic
模块在图片中隐藏信息。
为了充分利用本书
您需要在本地计算机上安装 Python 发行版,内存至少为 4GB。
在第九章、第十章和第十一章中,我们将使用一个名为 metasploitable 的虚拟机,用于进行与端口分析和漏洞检测相关的一些测试。可以从 SourceForge 页面下载:
sourceforge.net/projects/metasploitable/files/Metasploitable2
对于第九章,您还需要安装 Kali Linux 发行版和 Python,以执行 Metasploit Framework。
在本书中,您可以找到基于 Python 2 和 3 版本的示例。虽然许多示例可以在 Python 2 中运行,但使用最新版本的 Python 3 会获得最佳体验。在撰写本文时,最新版本为 2.7.14 和 3.6.15,并且这些示例已针对这些版本进行了测试。
下载示例代码文件
您可以从www.packt.com的帐户中下载本书的示例代码文件。如果您在其他地方购买了本书,可以访问www.packt.com/support并注册,以便直接通过电子邮件接收文件。
您可以按照以下步骤下载代码文件:
-
登录或注册www.packt.com。
-
选择“支持”选项卡。
-
单击“代码下载和勘误”。
-
在“搜索”框中输入书名,然后按照屏幕上的说明操作。
下载文件后,请确保使用最新版本的解压缩软件解压文件夹:
-
Windows 上的 WinRAR/7-Zip
-
Mac 上的 Zipeg/iZip/UnRarX
-
Linux 上的 7-Zip/PeaZip
该书的代码包也托管在 GitHub 上,网址为github.com/PacktPublishing/Mastering-Python-for-Networking-and-Security。如果代码有更新,将在现有的 GitHub 存储库中进行更新。
我们还有其他代码包,来自我们丰富的图书和视频目录,可在github.com/PacktPublishing/上找到。去看看吧!
下载彩色图片
我们还提供了一个 PDF 文件,其中包含本书中使用的屏幕截图/图表的彩色图像。您可以在此处下载:www.packtpub.com/sites/default/files/downloads/9781788992510_ColorImages.pdf
使用的约定
本书中使用了许多文本约定。
CodeInText
:表示文本中的代码词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 用户名。例如:"将下载的WebStorm-10*.dmg
磁盘映像文件挂载为系统中的另一个磁盘。"
代码块设置如下:
import requests
if __name__ == "__main__":
response = requests.get("http://www.python.org")
for header in response.headers.keys():
print(header + ":" + response.headers[header])
当我们希望引起您对代码块的特定部分的注意时,相关行或项目将以粗体显示:
import requests
http_proxy = "http://<ip_address>:<port>"
proxy_dictionary = { "http" : http_proxy}
requests.get("http://example.org", proxies=proxy_dictionary)
任何命令行输入或输出都将按如下方式编写:
$ pip install packagename
粗体:表示新术语、重要单词或屏幕上看到的单词。例如,菜单或对话框中的单词会以这种方式出现在文本中。例如:"从管理面板中选择系统信息。"
警告或重要提示会以这种方式出现。提示和技巧会以这种方式出现。
第一章:使用 Python 脚本
在本章中,我们将介绍 Python 脚本、集合、函数、异常处理和面向对象编程。我们将回顾如何创建类、对象以及 Python 初始化对象的特点,包括使用特殊属性和方法。还将介绍一种方法、工具和开发环境。
本章将涵盖以下主题:
-
编程和安装 Python
-
数据结构和 Python 集合
-
Python 函数和异常处理
-
Python 中的面向对象编程
-
包括如何管理模块、包、依赖项、传递参数、使用虚拟环境以及 Python 脚本的
STB
模块的 OMSTD 方法论 -
Python 脚本开发的主要开发环境
-
与 Python IDE 交互和调试
技术要求
在开始阅读本书之前,您应该了解 Python 编程的基础知识,如基本语法、变量类型、数据类型元组、列表字典、函数、字符串和方法。在python.org/downloads/上提供了两个版本,3.6.5 和 2.7.14。
本章的示例和源代码可在 GitHub 存储库的chapter 1
文件夹中找到:github.com/PacktPublishing/Mastering-Python-for-Networking-and-Security。
编程和安装 Python
Python 是一种易于阅读和编写的字节编译的面向对象编程语言。这种语言非常适合安全专业人员,因为它允许快速创建测试以及可重用的项目以供将来使用。由于许多安全工具都是用 Python 编写的,它为对已经编写的工具进行扩展和添加功能提供了许多机会。
介绍 Python 脚本
在本书中,我们将使用两个版本。如果您使用 Debian 或 Kali 等 Linux 发行版,那么不会有问题,因为 Python 是多平台的,并且在大多数 Linux 发行版中默认安装了 2.7 版本。
为什么选择 Python?
有很多选择 Python 作为主要编程语言的原因:
-
多平台和开源语言。
-
简单、快速、强大的语言。
-
许多关于计算机安全的库、模块和项目都是用 Python 编写的。
-
有很多文档和一个非常庞大的用户社区。
-
这是一种设计用于用几行代码创建强大程序的语言,而在其他语言中,只有在包含每种语言的许多特性之后才有可能实现。
-
适用于原型和快速概念测试(PoC)。
多平台
Python 解释器可在许多平台上使用(Linux、DOS、Windows 和 macOS X)。我们在 Python 中创建的代码在第一次执行时会被翻译成字节码。因此,在我们要执行 Python 中开发的程序或脚本的系统中,我们需要安装解释器。
面向对象编程
面向对象编程是一种范式,程序是通过“对象类”来定义的,它们通过发送消息来相互通信。它是程序化、结构化和模块化编程范式的演变,并在 Java、Python 或 C++等语言中实现。
类定义了对象中指定的行为和可用状态,并允许更直接地表示建模问题所需的概念,允许用户定义新类型。
对象的特点是:
-
区分它们之间的身份
-
通过方法定义它们的行为
-
通过属性和属性定义它们的状态
类允许在新类型的数据和与对象相关的功能之间进行分组,有利于在实现的细节和其使用的基本属性之间进行分离。这样,目标是不显示更多的相关信息,隐藏类的状态和内部方法,这被称为“封装”,它是继承自模块化编程的原则。
在使用类的一个重要方面是它们不是直接操作的,而是用来定义新类型。类为对象(类的实例)定义属性和行为。类充当一组对象的模板,这些对象被认为属于该类。
面向对象编程中使用的最重要的技术包括:
-
抽象:对象可以执行任务,与其他对象交互,或者修改和报告它们的状态,而无需沟通这些操作是如何执行的。
-
封装:对象通过清晰的接口阻止其他对象修改其内部状态或调用内部方法,并且只通过这个接口与其他对象相关联。
-
多态性:不同的行为可以与相同的名称相关联。
-
继承:对象通过建立层次结构与其他对象相关联,有可能一些对象继承其他对象的属性和方法,扩展它们的行为和/或专业化。对象以这种方式分组在形成层次结构的类中。
获取和安装 Python
在 Linux 和 Windows 平台上,Python 的安装速度很快。Windows 用户可以使用一个简单的安装程序,使配置工作变得容易。在 Linux 上,您可以选择从源代码构建安装,但这并不是强制的,您可以使用经典的包管理依赖,如 apt-get。
许多 Linux 发行版预装了 Python 2。在这样的系统上安装 Python 3 时,重要的是要记住我们并没有替换 Python 2 的安装。这样,当我们安装 Python 3 时,它可以与同一台机器上的 Python 2 并行安装。安装 Python 3 后,可以使用 Python3 可执行文件调用 python 解释器。
在 Windows 上安装 Python
Windows 用户可以从主 Python 网站获取安装程序:www.python.org/ftp/python/2.7.15/python-2.7.15.msi。只需双击安装程序,然后按照安装步骤进行安装。它应该在C:/Python27/
创建一个目录;这个目录将有Python.exe
解释器以及所有默认安装的库。
Python 安装允许您自定义环境的安装位置。Python 2.7.14 的默认位置是C:\Python27
,尽管您可以指定其他位置。当寻找特定模块和工具时,这个路径将是相关的。
如果要包括文档或安装一系列实用程序(如pip
软件包管理器或 IDLE 开发环境,用于编辑和执行脚本),则可以自定义安装。建议您保留已标记的选项,以便安装它们,使我们拥有尽可能完整的环境:
重要的是要检查“将 python.exe 添加到路径”框。这将允许您从任何路径直接从命令提示符运行 Python,而无需转到安装目录。
在安装 Python 版本的 Windows 时,您还可以看到 IDLE 可用,这是 Python 的编辑器或 IDE(集成开发环境),它将允许我们编写和测试代码。安装完成后,我们可以验证一切是否正确:
-
打开安装的文件夹
-
输入
C:\Python27\Lib\idlelib
-
双击运行
**idle.bat**
文件
Windows 用户的另一个选择是 WinPython,可以在winpython.github.io上找到。
WinPython 是一个 Python 发行版;您可以在 Windows 7/8/10 操作系统上安装它进行科学和教育用途。
这个发行版与其他发行版不同,因为它:
-
无需安装:WinPython 完全存在于自己的目录中,无需任何操作系统安装
-
便携式:您可以轻松地压缩您的 Python 项目并在其他机器上进行安装
在 Linux 上安装 Python
Python 默认安装在大多数 Gnu/Linux 发行版中。如果我们想要在 Ubuntu 或基于 Debian 的发行版中安装它,我们可以通过apt-get
软件包管理器来实现:
sudo apt-get install python2.7
Python 集合
在本节中,我们将回顾不同类型的数据集合,如列表、元组和字典。我们将看到用于管理这些数据结构的方法和操作,以及一个实际示例,我们将在其中回顾主要用例。
列表
Python 中的列表相当于 C 等编程语言中的动态向量结构。我们可以通过在一对方括号之间封装它们的元素并用逗号分隔来表示文字。列表的第一个元素的索引为 0。索引运算符允许访问元素,并通过在方括号中添加其索引来在列表中表达语法上:
考虑以下示例:程序员可以通过使用append()
方法添加项目来构建列表,打印项目,然后在再次打印之前对它们进行排序。在以下示例中,我们定义了一个协议列表,并使用 Python 列表的主要方法,如 append、index 和 remove:
>>> protocolList = []
>>> protocolList.append("ftp")
>>> protocolList.append("ssh")
>>> protocolList.append("smtp")
>>> protocolList.append("http")
>>> print protocolList
['ftp','ssh','smtp','http']
>>> protocolList.sort()
>>> print protocolList
['ftp','http','smtp','ssh']
>>> type(protocolList)
<type 'list'>
>>> len(protocolList)
4
要访问特定位置,我们使用index
方法,要删除一个元素,我们使用 remove 方法:
>>> position = protocolList.index("ssh")
>>> print "ssh position"+str(position)
ssh position 3
>>> protocolList.remove("ssh")
>>> print protocolList
['ftp','http','smtp']
>>> count = len(protocolList)
>>> print "Protocol elements "+str(count)
Protocol elements 3
要打印整个协议列表,请使用以下代码。这将循环遍历所有元素并将它们打印出来:
>>> for protocol in protocolList:
>> print (protocol)
ftp
http
smtp
列表还有一些方法,可以帮助我们操纵其中的值,并允许我们在其中存储多个变量,并为 Python 中的对象数组提供更好的排序方法。这些是最常用的用于操纵列表的方法:
-
.append(value): 在列表末尾添加一个元素
-
.count('x'): 获取列表中'x'的数量
-
.index('x'): 返回列表中'x'的索引
-
.insert('y','x'): 在位置'y'插入'x'
-
.pop(): 返回最后一个元素并从列表中删除它
-
.remove('x'): 从列表中删除第一个'x'
-
.reverse(): 反转列表中的元素
-
.sort(): 按字母顺序升序或按数字顺序升序对列表进行排序
反转列表
我们在列表中拥有的另一个有趣的操作是通过reverse()
方法返回列表的可能性:
>>> protocolList.reverse()
>>> print protocolList
['smtp','http','ftp']
执行相同操作的另一种方法是使用-1
索引。这种快速简便的技术显示了如何以相反的顺序访问列表的所有元素:
>>> protocolList[::-1]
>>> print protocolList
['smtp','http','ftp']
理解列表
理解列表允许您创建一个可迭代对象的新列表。基本上,它们包含必须为迭代每个元素的循环内的表达式。
基本语法是:
new_list = [expression for_loop_one_or_more conditions]
列表理解也可以用于迭代字符串:
>>> protocolList = ["FTP", "HTTP", "SNMP", "SSH"]
>>> protocolList_lower= [protocol.lower() for protocol in protocolList]
>>> print(protocolList_lower) # Output: ['ftp', 'http', 'snmp', 'ssh']
元组
元组类似于列表,但其大小和元素是不可变的,也就是说,其值不能被更改,也不能添加比最初定义的更多的元素。元组由括号括起来。如果我们尝试修改元组的元素,我们会收到一个错误,指示元组对象不支持元素的赋值:
字典
Python 字典数据结构允许我们将值与键关联起来。键是任何不可变对象。与键关联的值可以通过索引运算符访问。在 Python 中,使用哈希表实现字典。
Python 字典是一种存储键值对的方法。Python 字典用大括号{}
括起来。字典,也称为关联矩阵,得名于将键和值相关联的集合。例如,让我们看一个具有名称和数字的协议字典:
>>> services = {"ftp":21, "ssh":22, "smtp":25, "http":80}
字典的限制在于我们不能使用相同的键创建多个值。这将覆盖重复键的先前值。字典的操作是唯一的。我们可以使用update
方法将两个不同的字典合并为一个。此外,update
方法将在元素冲突时合并现有元素:
>>> services = {"ftp":21, "ssh":22, "smtp":25, "http":80}
>>> services2 = {"ftp":21, "ssh":22, "snmp":161, "ldap":389}
>>> services.update(services2)
>>> print services
这将返回以下字典:
{"ftp":21, "ssh":22, "smtp":25, "http":80,"snmp":161, "ldap":389}
第一个值是键,第二个是与键关联的值。作为键,我们可以使用任何不可变的值:我们可以使用数字、字符串、布尔值或元组,但不能使用列表或字典,因为它们是可变的。
字典与列表或元组的主要区别在于,存储在字典中的值不是通过它们的索引访问的,因为它们没有顺序,而是通过它们的键,再次使用[]
运算符。
与列表和元组一样,您也可以使用此运算符重新分配值:
>>> services["http"]= 8080
构建字典时,每个键都用冒号与其值分隔,我们用逗号分隔项。.keys()
方法将返回字典的所有键的列表,.items()
方法将返回字典中所有元素的完整列表。
以下是使用这些方法的示例:
-
services.keys()
是一个方法,将返回字典中的所有键。 -
services.items()
是一个方法,将返回字典中所有项目的完整列表。
从性能的角度来看,字典中的键在存储时被转换为哈希值,以节省空间并在搜索或索引字典时提高性能。还可以打印字典并按特定顺序浏览键。以下代码提取字典元素,然后对其进行排序:
>>> items = services.items()
>>> print items
[('ftp', 21), ('smtp',25), ('ssh', 22), ('http', 80), ('snmp', 161)]
>>> items.sort()
>>> print items
[('ftp', 21), ('http', 80), ('smtp', 25), ('snmp', 161), ('ssh', 22)]
我们可以提取字典中每个元素的键和值:
>>> keys = services.keys()
>>> print keys
['ftp', 'smtp', 'ssh', 'http', 'snmp']
>>> keys.sort()
>>> print keys
['ftp', 'http', 'smtp', 'snmp', 'ssh']
>>> values = services.values()
>>> print values
[21, 25, 22, 80, 161]
>>> values.sort()
>>> print values
[21, 22, 25, 80, 161]
>>> services.has_key('http')
True
>>> services['http']
80
最后,您可能希望遍历字典并提取和显示所有的“键:值”对:
>>> for key,value in services.items():
print key,value
ftp 21
smtp 25
ssh 22
http 80
snmp 161
Python 函数和异常管理
在本节中,我们将回顾 Python 函数和异常管理。我们将看到一些声明和在脚本代码中使用它们的示例。我们还将回顾我们可以在 Python 中找到的主要异常,以便在我们的脚本中包含。
Python 函数
在 Python 中,函数提供了有组织的可重用代码块。通常,这允许程序员编写一块代码来执行单个相关操作。虽然 Python 提供了许多内置函数,程序员可以创建用户定义的函数。除了通过将程序分成部分来帮助我们编程和调试外,函数还允许我们重用代码。
Python 函数是使用 def 关键字定义的,后面跟着函数名和函数参数。函数的主体由要执行的 Python 语句组成。在函数的末尾,您可以选择向函数调用者返回一个值,或者默认情况下,如果您没有指定返回值,它将返回 None 对象。
例如