mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-10-02 07:40:19 +02:00
Add compiler support when mingw is available
This commit is contained in:
parent
4e0111f119
commit
37d3c296ad
4
LICENSE
4
LICENSE
@ -15,6 +15,10 @@ License: BSD-3-clause
|
||||
# Last updated: 2013-Nov-04
|
||||
#
|
||||
|
||||
Files: data/headers/windows/c_payload_util/beacon.h
|
||||
Copyright: 2022, Copyright Help/Systems LLC and its group of companies.
|
||||
License: Apache 2.0
|
||||
|
||||
Files: data/exploits/mysql/lib_mysqludf_sys_*.so
|
||||
Copyright: 2007 Roland Bouman
|
||||
2008-2010 Roland Bouman and Bernardo Damele A. G.
|
||||
|
69
data/headers/windows/c_payload_util/beacon.h
Normal file
69
data/headers/windows/c_payload_util/beacon.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Beacon Object Files (BOF)
|
||||
* -------------------------
|
||||
* A Beacon Object File is a light-weight post exploitation tool that runs
|
||||
* with Beacon's inline-execute command.
|
||||
*
|
||||
* Additional BOF resources are available here:
|
||||
* - https://github.com/Cobalt-Strike/bof_template
|
||||
*
|
||||
* Cobalt Strike 4.x
|
||||
* ChangeLog:
|
||||
* 1/25/2022: updated for 4.5
|
||||
*/
|
||||
|
||||
/* data API */
|
||||
typedef struct {
|
||||
char * original; /* the original buffer [so we can free it] */
|
||||
char * buffer; /* current pointer into our buffer */
|
||||
int length; /* remaining length of data */
|
||||
int size; /* total size of this buffer */
|
||||
} datap;
|
||||
|
||||
DECLSPEC_IMPORT void BeaconDataParse(datap * parser, char * buffer, int size);
|
||||
DECLSPEC_IMPORT char * BeaconDataPtr(datap * parser, int size);
|
||||
DECLSPEC_IMPORT int BeaconDataInt(datap * parser);
|
||||
DECLSPEC_IMPORT short BeaconDataShort(datap * parser);
|
||||
DECLSPEC_IMPORT int BeaconDataLength(datap * parser);
|
||||
DECLSPEC_IMPORT char * BeaconDataExtract(datap * parser, int * size);
|
||||
|
||||
/* format API */
|
||||
typedef struct {
|
||||
char * original; /* the original buffer [so we can free it] */
|
||||
char * buffer; /* current pointer into our buffer */
|
||||
int length; /* remaining length of data */
|
||||
int size; /* total size of this buffer */
|
||||
} formatp;
|
||||
|
||||
DECLSPEC_IMPORT void BeaconFormatAlloc(formatp * format, int maxsz);
|
||||
DECLSPEC_IMPORT void BeaconFormatReset(formatp * format);
|
||||
DECLSPEC_IMPORT void BeaconFormatAppend(formatp * format, char * text, int len);
|
||||
DECLSPEC_IMPORT void BeaconFormatPrintf(formatp * format, char * fmt, ...);
|
||||
DECLSPEC_IMPORT char * BeaconFormatToString(formatp * format, int * size);
|
||||
DECLSPEC_IMPORT void BeaconFormatFree(formatp * format);
|
||||
DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value);
|
||||
|
||||
/* Output Functions */
|
||||
#define CALLBACK_OUTPUT 0x0
|
||||
#define CALLBACK_OUTPUT_OEM 0x1e
|
||||
#define CALLBACK_OUTPUT_UTF8 0x20
|
||||
#define CALLBACK_ERROR 0x0d
|
||||
|
||||
DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len);
|
||||
DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...);
|
||||
|
||||
|
||||
/* Token Functions */
|
||||
DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token);
|
||||
DECLSPEC_IMPORT void BeaconRevertToken();
|
||||
DECLSPEC_IMPORT BOOL BeaconIsAdmin();
|
||||
|
||||
/* Spawn+Inject Functions */
|
||||
DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
|
||||
DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
|
||||
DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
|
||||
DECLSPEC_IMPORT BOOL BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
|
||||
DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
|
||||
|
||||
/* Utility Functions */
|
||||
DECLSPEC_IMPORT BOOL toWideChar(char * src, wchar_t * dst, int max);
|
@ -24,10 +24,11 @@ module Rex
|
||||
'Beacon Object File Loader'
|
||||
end
|
||||
|
||||
DEFAULT_ENTRY = 'go'
|
||||
DEFAULT_ENTRY = 'go'.freeze
|
||||
|
||||
@@execute_bof_opts = Rex::Parser::Arguments.new(
|
||||
['-h', '--help'] => [ false, 'Help Banner' ],
|
||||
['-c', '--compile'] => [ true, 'Compile the input file (requires mingw).' ],
|
||||
['-e', '--entry'] => [ true, "The entry point (default: #{DEFAULT_ENTRY})." ],
|
||||
['-f', '--format-string'] => [ true, 'bof_pack compatible format-string. Choose combination of: b, i, s, z, Z' ]
|
||||
)
|
||||
@ -54,6 +55,8 @@ module Rex
|
||||
return tab_complete_filenames(str, words) if words.length == 1
|
||||
|
||||
fmt = {
|
||||
'-c' => [ nil ],
|
||||
'--compile' => [ nil ],
|
||||
'-e' => [ true ],
|
||||
'--entry' => [ true ],
|
||||
'-f' => [ true ],
|
||||
@ -63,7 +66,7 @@ module Rex
|
||||
end
|
||||
|
||||
def cmd_execute_bof(*args)
|
||||
if args.length == 0 || args.include?('-h') || args.include?('--help')
|
||||
if args.empty? || args.include?('-h') || args.include?('--help')
|
||||
cmd_execute_bof_help
|
||||
return false
|
||||
end
|
||||
@ -72,9 +75,12 @@ module Rex
|
||||
bof_args_format = nil
|
||||
bof_cmdline = []
|
||||
entry = DEFAULT_ENTRY
|
||||
compile = false
|
||||
|
||||
@@execute_bof_opts.parse(args) do |opt, _idx, val|
|
||||
case opt
|
||||
when '-c', '--compile'
|
||||
compile = true
|
||||
when '-f', '--format-string'
|
||||
bof_args_format = val
|
||||
when '-e', '--entry'
|
||||
@ -104,7 +110,12 @@ module Rex
|
||||
print_status('No argument format specified, executing bof with no arguments.')
|
||||
end
|
||||
|
||||
bof_data = ::File.binread(bof_filename)
|
||||
if compile
|
||||
bof_data = compile_c(bof_filename)
|
||||
return unless bof_data
|
||||
else
|
||||
bof_data = ::File.binread(bof_filename)
|
||||
end
|
||||
|
||||
# loading all data will hang on invalid files like DLLs, so only parse the 20-byte header at first
|
||||
parsed = Metasm::COFF.decode_header(bof_data[0...20])
|
||||
@ -145,6 +156,35 @@ module Rex
|
||||
|
||||
private
|
||||
|
||||
def compile_c(source)
|
||||
if client.arch == ARCH_X86
|
||||
mingw = Metasploit::Framework::Compiler::Mingw::X86.new
|
||||
elsif client.arch == ARCH_X64
|
||||
mingw = Metasploit::Framework::Compiler::Mingw::X64.new
|
||||
else
|
||||
print_error("Unsupported client architecture: #{client.arch}")
|
||||
return
|
||||
end
|
||||
|
||||
unless mingw.class.available?
|
||||
print_error("#{mingw.mingw_bin} is unavailable, can not compile source code")
|
||||
return
|
||||
end
|
||||
|
||||
::Dir::Tmpname.create([::File.basename(source, '.c'), '.o']) do |destination|
|
||||
output, status = Open3.capture2e(mingw.mingw_bin, '-c', source, '-I', Metasploit::Framework::Compiler::Mingw::INCLUDE_DIR, '-o', destination)
|
||||
unless status.exitstatus == 0
|
||||
print_error("Compilation exited with error code: #{status.exitstatus}")
|
||||
print_line(output) unless output.blank?
|
||||
return
|
||||
end
|
||||
|
||||
bof_data = ::File.binread(destination)
|
||||
::File.delete(destination)
|
||||
return bof_data
|
||||
end
|
||||
end
|
||||
|
||||
def get_executable_symbols(coff)
|
||||
executable_symbols = []
|
||||
coff.symbols.each do |sym|
|
||||
|
Loading…
Reference in New Issue
Block a user