Exploit Development
Exploit Development
Exploit Development
License
This work by Z. Cliffe Schreuders at Leeds Metropolitan University is licensed under a Creative Commons
Attribution-ShareAlike 3.0 Unported License.
All included software source code is by Z. Cliffe Schreuders and is also licensed under the GNU General Public
License, either version 3 of the License, or (at your option) any later version.
Contents
General notes about the labs
Preparation
Getting started
Manual exploitation
Adding shellcode
Getting it working
Finishing touches
References
Conclusion
However, we aim to provide a well planned and fluent experience. If you notice any
mistakes in the lab instructions or you feel some important information is missing,
please feel free to add a comment to the document by highlighting the text and click
the comment icon ( ), and I (Cliffe) will try to address any issues. Note that your
comments are public.
The labs are written to be informative and, in order to aid clarity, instructions that you
should actually execute are generally written in this colour. Note that all lab content is
assessable for the module, but the colour coding may help you skip to the “next thing
to do”, but make sure you dedicate time to read and understand everything. Coloured
instructions in italics indicates you need to change the instructions based on your
environment: for example, using your own IP address.
You should maintain a lab logbook / document, which should include your answers
to the questions posed throughout the labs (in this colour).
Preparation
As with all of the labs in this module, start by loading the latest version of the LinuxZ
template from the IMS system. If you have access to this lab sheet, you can read
ahead while you wait for the image to load.
To load the image: press F12 during startup (on the boot screen) to access
the IMS system, then login to IMS using your university password. Load the
template image: LinuxZ (load the latest version).
Once your LinuxZ image has loaded, log in using the username and password
allocated to you by your tutor.
Using the VM download script (as described in a previous lab), download and start
these VMs:
The exploit you are going to write is not currently in Metasploit’s arsenal, and the MSF
example on ExploitDB does not work with the WinXP service pack you will use. So what
you are creating is somewhat unique!
Getting started
On the Windows XP VM (victim/debugger)
Download these files (also available via the network share in Z:\Software & VM &
ISO\Software\Debuggers\):
Copy each of these zip files to My Documents, and extract them to their own
subdirectories.
Start OllyDbg (by running OLLYDBG.exe), click Open, and select the Win32 FloatFTP
server executable.
Starting the debugger, by opening the program to debug
OllyDBG is similar to GNU GDB, which you have used previously, except that it is a
graphical program (a similar program for Linux is EDB -- both are available in Kali
Linux). Note that the Assembly instructions are displayed in a slightly different format
(AT&T vs Intel syntax).
At this point you may wish to move your Windows VM onto the host-only network, and
renew your IP address, so others on the network can’t interfere.
If you are prompted by the Windows firewall, allow the server access to the network
(click “Unblock”).
Manual exploitation
On the Kali Linux VM (attacker/exploit development)
First, manually test the vulnerability, by connecting directly to the vulnerable server
using Ncat:
USER anonymous
PASS anonymous
Manual exploitation
Note that FloatFTP has a buffer overflow when a MDK command is followed by a long
string.
Did you discover this vulnerability during the bug hunting lab?
Run MKD followed by a few lines of ‘A’s (at least 5 lines or so), then press Enter:
MKD AAAAAAAAAAAAAA(*A)
Manual exploitation crashing the program (the screenshot is cropped, so doesn't show the whole input)
OllyDdg will report an “access violation” (at the bottom in the status bar), and pause
the process.
Tip: if it doesn’t, you may not have entered a long enough input.
Hint: to make the directory path, you can run “mkdir -p /root/.msf4/modules/
exploits/windows/ftp/”
require 'msf/core'
include Msf::Exploit::Remote::Ftp
def initialize(info = {})
super(update_info(info,
'Name' => 'FloatFTP MKD overflow',
'Description' => 'My first MSF exploit module',
'Author' => [ 'Your name'],
'Version' => '$Revision: 1 $',
'Platform' => ['win'],
'Targets' => [ [ 'Windows XP SP2', { } ],],
'DefaultTarget' => 0,
'License' => GPL_LICENSE
))
end
def exploit
puts "My first Metasploit module!"
connect_login
disconnect
end
end
Note that MSF simplifies our code already, since it does the FTP authentication for
us. This code is Ruby, although you do not need to be overly familiar with the Ruby
programming language in order to develop exploits.
msfconsole
If things go well, you will have changed EIP to 0x41414141 (AAAA), and caused an
access violation.
OllyDbg access violation shown in the status bar
Your next step is to determine the offset within the input that overwrites the EIP: just
how many As would it take to overwrite EIP?
There are many ways you could determine the offset, one of which is to use
Metasploit’s pattern_create feature.
Edit the above code, so that bad is set to “pattern_create(1000)”, rather than a
sequence of As.
This generates a special pattern that can be used to calculate the offset, based on
having any section of the pattern. Your exploit will now generate the special pattern
and send it as the malicious input to the program. The aim is to use this pattern to
calculate the length of the offset before the EIP overwrite occurs.
msfconsole
/usr/share/metasploit-framework/tools/pattern_offset.rb
EIP-value 1000
So you now know the offset: the number of bytes from the start of the input, to the
part of the input that overwrites EIP.
Confirm this by updating your bad variable in the exploit code, so that it starts
with "A" * offset, then four Bs, then lots of Cs.
If you have correctly overwritten exactly the EIP you will have written the value
0x42424242 (since 0x42 is hex for ASCII 66, which represents a B).
Adding shellcode
Now that you can control execution of the vulnerable service, you need to decide
where to put the shellcode/payload. You could either place the shellcode before or
after the set of Bs representing your control of EIP, since you control both areas of
input.
Browse the Register and Stack panes, and find the As, Bs, and Cs.
Next,look to see if any of the registers are already pointing to the potential shellcode
areas. If so, you can jump directly to a register, which is an ideal situation (otherwise
you would need to find another way to jump to the shellcode).
Do you think the shellcode should be stored in the As section or the Cs section?
We have ESP and EDI both pointing somewhere in the Cs, which is good because there
also seems to be quite a bit of space for your shellcode. (Answer: so this is the a good
place to put your shellcode.)
Since you may not know exactly where the pointer will land within the Cs, you can add
a NOP slide…
Why can’t you just replace BBBB with the memory address that you can see the Cs
starting in OllyDb?
Part of the answer: you cannot simply write a memory address directly into that space,
since the memory addresses change each time the program runs. An alternative way
to get to your shellcode is to point EIP at an instruction within memory that jumps the
code to the ESP register.
Right click the instruction pane (top left), and Search for → Command.
When developing exploits it is often best to use return values that point to
libraries that ship with the program, rather than system libraries which may
change each Windows release. However, in this case there does not seem to be
any other choice.
Note: choose a return address that does not include 0x00, 0x0A, or 0x0D.
What return address have you found, and what library was it in?
For example, one solution is to search within shell32, and find the instruction at
0x7CA58265. However, you should try to find another one if you can.
Replace the “BBBB” in the exploit to a reversed (Little Endian) version of the return
address you have found. For example, 0x7CA58265 would become:
The program crashes due to your payload including characters that get
misinterpreted.
Getting it working
For now, lets assume the typical set of bad characters applies in this case: 0x00, 0x0A,
and 0x0D.
Update the module info at the start of the Metasploit exploit module, to include the
line:
This time the program terminates as soon as the exploit runs (rather than having an
access violation). This indicates that your exploit is not generating any errors, but is
causing the server to stop. This can be avoided by setting another Metasploit option.
Update the module info at the start of the Metasploit exploit module, to include the
line:
At this point your exploit should now be fully working! You will end up with a
meterpreter shell on the Windows system! Horray!
If your exploit did not work, there may be a problem with your selected “JMP
ESP”; you may have used a library that is randomised via address-layout
randomisation (ASLR), so the layout the the code may change each time the
library is used. Try finding another return address, or use the example provided
above.
Payload away!
meterpreter > ps
Finishing touches
Store the offset and return address with the Targets setting...
This line:
'Targets' => [ [ 'Windows XP SP2', {'Offset' => XXX, ‘Ret’ => 0xXXXXXXXX } ],],
(Where you should replace the values with the ones you identified earlier.)
target['Offset']
[target.ret].pack('V')
What is the difference between using 0x90 instructions verses using calls to
make_nops()? What is the advantage?
Test your changes: restart the debugger and msfconsole, and try re-running your
exploit.
Which of these would interfere with your exploit, how, and could you circumvent
them?
● ASLR
● DEP
● NX
● Stack pointer protection
● Access controls
● Firewalls
References
For further reading:
Conclusion
At this point you have:
● Figured out how to overwrite EIP with anything of your choosing (by calculating
the offset from the start of the input to the value that is restored from the stack
to EIP)