Skip to content

Commit 660cbfa

Browse files
committed
update no-consolation script
1 parent 29717e1 commit 660cbfa

File tree

3 files changed

+74
-25
lines changed

3 files changed

+74
-25
lines changed

NoConsolation/bin/NoConsolation.x64.o

4.49 KB
Binary file not shown.

NoConsolation/bin/NoConsolation.x86.o

3.87 KB
Binary file not shown.

NoConsolation/no-consolation.py

+74-25
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11

22
import os
33
from havoc import Demon, RegisterCommand
4+
from datetime import datetime
45

56
def is_windows_path(path):
67
return re.match(r'^[a-zA-Z]:\\', path) is not None
78

89
def is_linux_path(path):
910
return re.match(r'^/[a-zA-Z]', path) is not None
1011

12+
def is_pe_name(path):
13+
return re.match(r'^[a-zA-Z].*\.exe', path) is not None
14+
1115
def noconsolation_parse_params( demon, params ):
1216
packer = Packer()
1317

@@ -20,6 +24,13 @@ def noconsolation_parse_params( demon, params ):
2024
alloc_console = False
2125
close_handles = False
2226
free_libs = False
27+
cmdline = None
28+
cmdwline = None
29+
pename = None
30+
dont_save = False
31+
list_pes = False
32+
unload_pe = None
33+
name_set = False
2334
timeout = 60
2435
path_set = False
2536
path = ''
@@ -66,15 +77,29 @@ def noconsolation_parse_params( demon, params ):
6677
close_handles = True
6778
elif param == '--free-libraries' or param == '-fl':
6879
free_libs = True
80+
elif param == '--dont-save' or param == '-ds':
81+
dont_save = True
82+
elif param == '--list-pes' or param == '-lpe':
83+
list_pes = True
84+
elif param == '--unload-pe' or param == '-upe':
85+
skip = True
86+
if i + 1 >= num_params:
87+
demon.ConsoleWrite( demon.CONSOLE_ERROR, "missing --unload-pe value" )
88+
return None, None
89+
unload_pe = params[i + 1]
6990
elif os.path.exists( param ) or is_windows_path( param ):
7091
path_set = True
7192
path = param
7293
break
7394
elif local is False and os.path.exists( param ) is False and is_linux_path( param ):
7495
demon.ConsoleWrite( demon.CONSOLE_INFO, f"Specified executable {path} does not exist" )
7596
return None, None
97+
elif local is False and is_pe_name( params[ i ] ):
98+
pename = params[ i ]
99+
name_set = True
100+
break
76101
elif param == '--help' or param == '-h':
77-
demon.ConsoleWrite( demon.CONSOLE_INFO, "Usage: noconsolation [--local] [--timeout 60] [-k] [--method funcname] [-w] [--no-output] [--alloc-console] [--close-handles] [--free-libraries] /path/to/binary.exe arg1 arg2" )
102+
demon.ConsoleWrite( demon.CONSOLE_INFO, "Usage: noconsolation [--local] [--timeout 60] [-k] [--method funcname] [-w] [--no-output] [--alloc-console] [--close-handles] [--free-libraries] [--dont-save] [--list-pes] [--unload-pe pename] /path/to/binary.exe arg1 arg2" )
78103
demon.ConsoleWrite( demon.CONSOLE_INFO, " --local, -l Optional. The binary should be loaded from the target Windows machine" )
79104
demon.ConsoleWrite( demon.CONSOLE_INFO, " --timeout NUM_SECONDS, -t NUM_SECONDS Optional. The number of seconds you wish to wait for the PE to complete running. Default 60 seconds. Set to 0 to disable" )
80105
demon.ConsoleWrite( demon.CONSOLE_INFO, " -k Optional. Overwrite the PE headers" )
@@ -84,7 +109,10 @@ def noconsolation_parse_params( demon, params ):
84109
demon.ConsoleWrite( demon.CONSOLE_INFO, " --alloc-console, -ac Optional. Allocate a console. This will spawn a new process" )
85110
demon.ConsoleWrite( demon.CONSOLE_INFO, " --close-handles, -ch Optional. Close Pipe handles once finished. If PowerShell was already ran, this will break the output for PowerShell in the future" )
86111
demon.ConsoleWrite( demon.CONSOLE_INFO, " --free-libraries, -fl Optional. Free all loaded DLLs" )
87-
demon.ConsoleWrite( demon.CONSOLE_INFO, " /path/to/binary.exe Required. Full path to the windows EXE/DLL you wish you run inside Beacon" )
112+
demon.ConsoleWrite( demon.CONSOLE_INFO, " --dont-save, -ds Optional. Do not save this binary in memory" )
113+
demon.ConsoleWrite( demon.CONSOLE_INFO, " --list-pes, -lpe Optional. List all PEs that have been loaded in memory" )
114+
demon.ConsoleWrite( demon.CONSOLE_INFO, " --unload-pe PE_NAME, -upe PE_NAME Optional. Unload from memory a PE" )
115+
demon.ConsoleWrite( demon.CONSOLE_INFO, " /path/to/binary.exe Required. Full path to the windows EXE/DLL you wish you run inside Beacon. If already loaded, you can simply specify the binary name." )
88116
demon.ConsoleWrite( demon.CONSOLE_INFO, " ARG1 ARG2 Optional. Parameters for the PE. Must be provided after the path" )
89117
demon.ConsoleWrite( demon.CONSOLE_INFO, "" )
90118
demon.ConsoleWrite( demon.CONSOLE_INFO, " Example: noconsolation --local C:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe $ExecutionContext.SessionState.LanguageMode" )
@@ -95,40 +123,56 @@ def noconsolation_parse_params( demon, params ):
95123
demon.ConsoleWrite( demon.CONSOLE_INFO, f"invalid argument: {param}" )
96124
return None, None
97125

98-
if path_set is False:
126+
# allow users to close all handles without having to run a PE
127+
if unload_pe is None and list_pes is False and name_set is False and path_set is False and close_handles is False:
99128
demon.ConsoleWrite( demon.CONSOLE_INFO, "PE path not provided" )
100129
return None, None
101130

102-
if os.path.exists(path) is False and local is False:
131+
if path_set is True and os.path.exists(path) is False and local is False:
103132
demon.ConsoleWrite( demon.CONSOLE_INFO, f"Specified executable {path} does not exist" )
104133
return None, None
105134

106-
if local is False:
107-
pename = path.split("/")[-1]
135+
if path_set is True and list_pes is True:
136+
demon.ConsoleWrite( demon.CONSOLE_INFO, "The option --list-pes must be ran alone" )
137+
return None, None
108138

109-
try:
110-
with open(path, 'rb') as f:
111-
pebytes = f.read()
112-
except:
113-
demon.ConsoleWrite( demon.CONSOLE_INFO, f"could not read PE" )
114-
return None, None
139+
if unload_pe is not None and list_pes is True:
140+
demon.ConsoleWrite( demon.CONSOLE_INFO, "The option --list-pes must be ran alone" )
141+
return None, None
115142

116-
if len(pebytes) == 0:
117-
demon.ConsoleWrite( demon.CONSOLE_INFO, f"The PE is empty" )
118-
return None, None
143+
if unload_pe is not None and path_set is True:
144+
demon.ConsoleWrite( demon.CONSOLE_INFO, "The option --unload-pe must be ran alone" )
145+
return None, None
146+
147+
if path_set:
148+
if local is False:
149+
pename = path.split("/")[-1]
119150

120-
path = ''
121-
else:
122-
pename = path.split("\\")[-1]
151+
try:
152+
with open(path, 'rb') as f:
153+
pebytes = f.read()
154+
except:
155+
demon.ConsoleWrite( demon.CONSOLE_INFO, f"could not read PE" )
156+
return None, None
157+
158+
if len(pebytes) == 0:
159+
demon.ConsoleWrite( demon.CONSOLE_INFO, f"The PE is empty" )
160+
return None, None
161+
162+
path = ''
163+
else:
164+
pename = path.split("\\")[-1]
123165

124-
# Iterate through args given
125-
cmdline = pename
126-
for y in range(i + 1, len(params)):
127-
arg = params[ y ]
128-
arg = arg.replace('\\"', '"')
166+
if path_set or name_set:
167+
# Iterate through args given
168+
cmdline = pename
169+
for y in range(i + 1, len(params)):
170+
arg = params[ y ]
171+
arg = arg.replace('\\"', '"')
129172

130-
cmdline = f'{cmdline} {arg}'
173+
cmdline = f'{cmdline} {arg}'
131174

175+
packer.addstr(pename)
132176
packer.addbytes(pebytes)
133177
packer.addstr(path)
134178
packer.addbool(local)
@@ -142,6 +186,11 @@ def noconsolation_parse_params( demon, params ):
142186
packer.addbool(alloc_console)
143187
packer.addbool(close_handles)
144188
packer.addbool(free_libs)
189+
packer.addbool(dont_save)
190+
packer.addbool(list_pes)
191+
packer.addstr(unload_pe)
192+
packer.addstr("<unknown user>")
193+
packer.addstr(datetime.now().strftime('%H:%M:%S %Y-%m-%d'))
145194

146195
return packer.getbuffer(), pename
147196

@@ -165,4 +214,4 @@ def noconsolation( demonID, *params ):
165214

166215
return TaskID
167216

168-
RegisterCommand( noconsolation, "", "noconsolation", "Execute a PE inline", 0, "[--local] [--timeout 60] [-k] [--method funcname] [-w] [--no-output] [--alloc-console] [--close-handles] [--free-libraries] /path/to/binary.exe arg1 arg2", "--local C:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe $ExecutionContext.SessionState.LanguageMode" )
217+
RegisterCommand( noconsolation, "", "noconsolation", "Execute a PE inline", 0, "[--local] [--timeout 60] [-k] [--method funcname] [-w] [--no-output] [--alloc-console] [--close-handles] [--free-libraries] [--dont-save] [--list-pes] [--unload-pe pename] /path/to/binary.exe arg1 arg2", "--local C:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe $ExecutionContext.SessionState.LanguageMode" )

0 commit comments

Comments
 (0)