As a bonus to this week’s review of “Ruby By Example,” I'd like to give an applied security related example of Ruby by walking you through a chunk of code in the Metasploit Open Source Exploit Framework (www.metasploit.com). Metasploit is written entirely in Ruby and
has gained critical acclaim as the standard for open source exploit frameworks and should be a vital tool in any security guru's box.
The following it NOT an exploit walkthrough. This is simply a code analysis to point out parts of the framework which exude a certain amount of "Rubyness" and is a great research area to see why the developers of Metasploit chose Ruby as its language. I have taken code from both the actual framework as well as examples provided by the developer's documentation included in the source tarball of the download. This is meant to spark interest and curiosity - poke around the code to see if you find anything you could reuse or reimplement later on, whether it's security related or not. All examples assume you will be following on with Baird's 'Ruby by Example'.
The Metasploit framework is a prime example of modularization in
Ruby - there is a great hierarchial setup for the framework where much of the work has been done for you. Certain parts of the code can be extracted and used "as is", such as the NOP sled generator:
module Msf
module Nops
class Sample < Msf::Nop
def initialize
super(
'Name' => 'Sample NOP generator',
'Version' => '$Revision: 3215 $',
'Description' => 'Sample single-byte NOP generator',
'Author' => 'skape',
'Arch' => ARCH_X86)
end
#
# Returns a string of 0x90's for the supplied length.
#
def generate_sled(length, opts)
"\x90" * length
end
end
end
end
Notice the use of super in this case in order to grab the features of the already written Nop class. This allows any user to pull methods out of this class and manipulate in any fashion, offering quick code reuse and innovation. Read the chapter on modules and inheritance to get an understanding of the ease of use how the developers organized their classes in the framework.
Other parts of the framework leave it very simple to write your own module and include any exploits / shellcode you have written yourself:
module Msf
class Exploits::Sample < Msf::Exploit::Remote
#
# This exploit affects TCP servers, so we use the TCP client mixin.
#
include Exploit::Remote::Tcp
def initialize(info = {})
super(update_info(info,
'Name' => 'Sample exploit',
'Description' => %q{
This exploit module illustrates how a vulnerability could
be exploited in an TCP server that has a parsing bug.
},
'Author' => 'skape',
'Version' => '$Revision: 3215 $',
'Payload' =>
{
'Space' => 1000,
'BadChars' => "\x00",
},
'Targets' =>
[
# Target 0: Windows All
[
'Windows Universal',
{
'Platform' => 'win',
'Ret' => 0x41424344
}
],
],
'DefaultTarget' => 0))
end
#
# The sample exploit just indicates that the remote host is always
# vulnerable.
#
def check
return Exploit::CheckCode::Vulnerable
end
#
# The exploit method connects to the remote service and sends 1024 A's
# followed by the fake return address and then the payload.
#
def exploit
connect
print_status("Sending #{payload.encoded.length} byte payload...")
# Build the buffer for transmission
buf = "A" * 1024
buf += [ target.ret ].pack('V')
buf += payload.encoded
# Send it off
sock.put(buf)
sock.get
handler
end
end
end
When developing payloads one only has to insert values into
the payload hash and deliver as is - Metasploit has done the
work for you. You should look over chapters on hash declarations
as well as symbols and strings to gain an understanding of how
Ruby declares these variables.
One might ask "Whats so special about this code? It does this,
this, and this, anyone can see that". The fact that anyone can
read through the code and simply understand it is the whole point
of Ruby. There are no special tricks or isms when the developers
wrote the code for Metasploit. From the classes to its modules,
everything is very compartamentalized in a fashion which makes
it simple to extend, hence it only being a framework. The
fact that it can hide so much of its inner workings such as
how it implements assembly code and methods:
#
# Assembles the supplied assembly and returns the raw opcodes.
#
def self.assemble(assembly)
check
# Open the temporary file
tmp = Tempfile.new('nasmXXXX')
tpath = tmp.path
opath = tmp.path + '.out'
# Write the assembly data to a file
tmp.write("BITS 32\n" + assembly)
tmp.flush()
tmp.seek(0)
# Run nasm
if (system(@@nasm_path, '-f', 'bin', '-o', opath, tpath) == false)
raise RuntimeError, "Assembler did not complete successfully: #{$?.exitstatus}"
end
# Read the assembled text
rv = ::IO.read(opath)
# Remove temporary files
File.unlink(opath)
tmp.close
rv
end
There are prerequisites for this method (such as sanity checks on your nasm environment) but one can see the subtle use of writing the candidate assembly code to a temporary file and applying nasm to obtain raw opcodes. Rather than key this in by hand over and over you can see that Metasploit provides an extremely convenient method to modularize this which the user will never see (unless you go digging through the source code!) Baird's book has chapters on heavier text processing which involves the use of manipulating files - perhaps the reader could expand the previous example by providing code blocks to the write or open commands? The second half of the book provides a wealth of examples featuring proc blocks and lambdas which make functional programming key in file handling procedures.
Metasploit is the leading open source exploit framework for a reason – its ease of application and streamlining of development makes it a vital addition to any IT security team's toolbox. The fact that is is written in Ruby gives anyone the chance to sit down and dig through this code. I highly encourage anyone wanting to get a nice grasp of both Ruby and exploit development to poke around and trace through the source code. Metaploit even supplies its own developer's documentation which I have taken samples from to further illustrate the usefulness of Ruby. Combining this with a few good books by your side (such as Ruby by Example!) and you're well on your way to learning through doing!
Only registered users can write comments. Please login or register. Powered by AkoComment! |