Thursday, February 17, 2011

Importing metasploit tools into gdb

By reading http://www.vnsecurity.net/2011/01/padocon-2011-ctf-karma-400-exploit-the-data-re-use-way/, I found longld use the pattern_create and pattern_offset metasploit tools directly into gdb. Because I am an eternal jealous I've imported it into .gdbinit with the following :

# pattern_create
define pattern_create
    if $argc != 1
        help pattern_create
    else
        shell ruby /opt/metasploit/tools/pattern_create.rb $arg0 
    end
end
document pattern_create
Usage: pattern_create length
end

# pattern_offset
define pattern_offset
    if $argc != 2
        help pattern_offset
    else
        shell ruby /opt/metasploit/tools/pattern_offset.rb $arg0 $arg1
    end
end
document pattern_offset
Usage: pattern_offset <search item> <length of buffer>
Default length of buffer if none is inserted: 8192
This buffer is generated by pattern_create() in the Rex library automatically
end

This is a first shot coded with feet, but that fit really well with the perfect http://reverse.put.as/wp-content/uploads/2010/04/gdbinit73. As I don't use [set a/b/c] they are not present here, but maybe in an updated version :) The <search item> and <length of buffer> switch of longld remains an opaque mystery!

Code available here :
http://paste.pocoo.org/show/340161/

EDIT: sh4ka enlighted me with the pvefindaddr implementation (http://redmine.corelan.be:8800/projects/pvefindaddr/repository/entry/release/v1.8/pvefindaddr.py) of metasploit pattern functions. It requires python, but it is far lighter than metasploit :). Just add the following to your .gdbinit :

python
import gdb
import binascii

class Pattern_create(gdb.Command):
    '''pattern_create <size>'''

    def __init__(self):
        super(Pattern_create, self).__init__("pattern_create", gdb.COMMAND_SUPPORT, gdb.COMPLETE_FILENAME)

    def invoke(self, arg, from_tty):
        size=arg.split(" ")[0]
        char1="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        char2="abcdefghijklmnopqrstuvwxyz"
        char3="0123456789"
        charcnt=0
        pattern=""
        max=int(size)
        for ch1 in char1:
           for ch2 in char2:
               for ch3 in char3:
                  if charcnt<max:
                    pattern=pattern+ch1
                    charcnt=charcnt+1
                  if charcnt<max:
                    pattern=pattern+ch2
                    charcnt=charcnt+1
                  if charcnt<max:
                    pattern=pattern+ch3
                    charcnt=charcnt+1
        print pattern

class Pattern_offset(gdb.Command):
    '''pattern_offset <pattern> <size>'''

    def __init__(self):
        super(Pattern_offset, self).__init__("pattern_offset", gdb.COMMAND_SUPPORT, gdb.COMPLETE_FILENAME)

    def invoke(self, arg, from_tty):
        searchpat=arg.split(" ")[0]
        size=arg.split(" ")[1]
        mspattern=""
        patsize=int(size)
        mspattern=self.pattern_create(size)
        if len(searchpat)==4:
           ascipat2=searchpat
           print("Looking for %s in pattern of %d bytes" % (ascipat2,patsize))
           if ascipat2 in mspattern:
              patpos = mspattern.find(ascipat2)
              print(" - Pattern %s found in Metasploit pattern at position %d" % (ascipat2,patpos))
           else:
              print(" - Pattern %s not found in Metasploit pattern" % ascipat2)
        if len(searchpat)==8:
              searchpat="0x"+searchpat
        if len(searchpat)==10:
              hexpat=searchpat
              ascipat3=toascii(hexpat[8]+hexpat[9])+toascii(hexpat[6]+hexpat[7])+toascii(imm,hexpat[4]+hexpat[5])+toascii(hexpat[2]+hexpat[3])
              print("Looking for %s in pattern of %d bytes" % (ascipat3,patsize))
              if ascipat3 in mspattern:
                 patpos = mspattern.find(ascipat3)
                 print(" - Pattern %s (%s) found in Metasploit pattern at position %d" % (ascipat3,hexpat,patpos))
              else:
                 #maybe it's reversed
                 ascipat4=toascii(hexpat[2]+hexpat[3])+toascii(hexpat[4]+hexpat[5])+toascii(hexpat[6]+hexpat[7])+toascii(hexpat[8]+hexpat[9])
                 print("Looking for %s in pattern of %d bytes" % (ascipat4,patsize))
                 if ascipat4 in mspattern:
                   patpos = mspattern.find(ascipat4)
                   print(" - Pattern %s (%s reversed) found in Metasploit pattern at position %d" % (ascipat4,hexpat,patpos))
                 else:
                   print(" - Pattern %s not found in Metasploit pattern" % ascipat4)

    def pattern_create(self, size):
        char1="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        char2="abcdefghijklmnopqrstuvwxyz"
        char3="0123456789"
        charcnt=0
        pattern=""
        max=int(size)
        for ch1 in char1:
           for ch2 in char2:
               for ch3 in char3:
                  if charcnt<max:
                    pattern=pattern+ch1
                    charcnt=charcnt+1
                  if charcnt<max:
                    pattern=pattern+ch2
                    charcnt=charcnt+1
                  if charcnt<max:
                    pattern=pattern+ch3
                    charcnt=charcnt+1
        return pattern

   def toascii(self, n):
      try:
         asciiequival=binascii.a2b_hex(n)
      except:
         asciiequival=" "
         #print sys.exc_info()[0]
      return asciiequival

Pattern_create()
Pattern_offset()

end

This is a simple way to define gdb commands in python, read more at http://sourceware.org/gdb/wiki/PythonGdbTutorial.

Code available here :
http://paste.pocoo.org/show/Arg0fmMLsO3cVoSCclXo/

No comments:

Post a Comment