mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-11-05 14:57:30 +01:00
first pass at badchars checking tool
git-svn-id: file:///home/svn/framework3/trunk@7921 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
6a1f43b3df
commit
7a6c8af0f7
141
tools/find_badchars.rb
Executable file
141
tools/find_badchars.rb
Executable file
@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env ruby
|
||||
#
|
||||
# This script is intended to assist an exploit developer in deducing what
|
||||
# "bad characters" exist for a given input path to a program.
|
||||
#
|
||||
|
||||
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
||||
|
||||
require 'rex'
|
||||
|
||||
OutStatus = "[*] "
|
||||
OutError = "[-] "
|
||||
|
||||
$args = Rex::Parser::Arguments.new(
|
||||
"-b" => [ true, "The list of characters to avoid: '\\x00\\xff'" ],
|
||||
"-h" => [ false, "Help banner" ],
|
||||
"-i" => [ true, "Read memory contents from the supplied file path" ],
|
||||
"-t" => [ true, "The format that the memory contents are in (empty to list)" ])
|
||||
|
||||
def usage
|
||||
$stderr.puts("\n" + " Usage: #{File.basename($0)} <options>\n" + $args.usage)
|
||||
exit
|
||||
end
|
||||
|
||||
def show_format_list
|
||||
$stderr.puts("Supported formats:\n")
|
||||
$stderr.puts(" raw raw binary data\n")
|
||||
$stderr.puts(" windbg output from windbg's \"db\" command\n")
|
||||
$stderr.puts(" gdb output from gdb's \"x/bx\" command\n")
|
||||
end
|
||||
|
||||
def debug_buffer(name, buf)
|
||||
str = "\n#{buf.length} bytes of "
|
||||
str << name
|
||||
str += ":" if buf.length > 0
|
||||
str += "\n\n"
|
||||
$stderr.puts str
|
||||
if buf.length > 0
|
||||
$stderr.puts Rex::Text.to_hex_dump(buf)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Input defaults
|
||||
badchars = ''
|
||||
fmt = 'raw'
|
||||
input = $stdin
|
||||
|
||||
# Output
|
||||
new_badchars = ''
|
||||
|
||||
# Parse the argument and rock that shit.
|
||||
$args.parse(ARGV) { |opt, idx, val|
|
||||
case opt
|
||||
when "-i"
|
||||
begin
|
||||
input = File.new(val)
|
||||
rescue
|
||||
$stderr.puts(OutError + "Failed to open file #{val}: #{$!}")
|
||||
exit
|
||||
end
|
||||
when "-b"
|
||||
badchars = Rex::Text.hex_to_raw(val)
|
||||
when "-t"
|
||||
if (val =~ /^(raw|windbg|gdb)$/)
|
||||
fmt = val
|
||||
else
|
||||
if val.nil? or val.length < 1
|
||||
show_format_list
|
||||
else
|
||||
$stderr.puts(OutError + "Invalid format: #{val}")
|
||||
end
|
||||
exit
|
||||
end
|
||||
when "-h"
|
||||
usage
|
||||
end
|
||||
}
|
||||
|
||||
if input == $stdin
|
||||
$stderr.puts(OutStatus + "Please paste the memory contents in \"" + fmt + "\" format below (end with EOF):\n")
|
||||
end
|
||||
|
||||
|
||||
|
||||
# Working data set
|
||||
from_msf = Rex::Text.charset_exclude(badchars)
|
||||
from_dbg = ''
|
||||
|
||||
|
||||
# Process the input
|
||||
from_dbg = input.read
|
||||
case fmt
|
||||
when "raw"
|
||||
# this should already be in the correct format :)
|
||||
|
||||
when "windbg"
|
||||
translated = ''
|
||||
from_dbg.each_line do |ln|
|
||||
translated << ln.chomp[10,47].gsub!(/(-| )/, '')
|
||||
end
|
||||
from_dbg = Rex::Text.hex_to_raw(translated)
|
||||
|
||||
when "gdb"
|
||||
translated = ''
|
||||
from_dbg.each_line do |ln|
|
||||
translated << ln.chomp.split(':')[1].gsub!(/0x/, '\x').gsub!(/ /, '')
|
||||
end
|
||||
from_dbg = Rex::Text.hex_to_raw(translated)
|
||||
end
|
||||
|
||||
|
||||
|
||||
=begin
|
||||
# Uncomment these to debug stuff ..
|
||||
debug_buffer("BadChars", badchars)
|
||||
debug_buffer("memory contents", from_dbg)
|
||||
debug_buffer("Rex::Text.charset_exclude() output", from_msf)
|
||||
=end
|
||||
|
||||
|
||||
# Find differences between the two data sets
|
||||
minlen = from_msf.length
|
||||
minlen = from_dbg.length if from_dbg.length < minlen
|
||||
(0..(minlen-1)).each do |idx|
|
||||
ch1 = from_msf[idx]
|
||||
ch2 = from_dbg[idx]
|
||||
if ch1 != ch2
|
||||
str = "Byte at index 0x%04x differs (0x%02x became 0x%02x)" % [idx, ch1, ch2]
|
||||
$stderr.puts OutStatus + str
|
||||
new_badchars << ch1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# show the results
|
||||
if new_badchars.length < 1
|
||||
$stderr.puts(OutStatus + "All characters matched, no new bad characters discovered.")
|
||||
else
|
||||
$stderr.puts(OutStatus + "Proposed BadChars: \"" + Rex::Text.to_hex(new_badchars) + "\"")
|
||||
end
|
Loading…
Reference in New Issue
Block a user