zoukankan      html  css  js  c++  java
  • [转]Building a Basic Fuzzer with GDB: The Five Minute GDB Scripting Tutorial

    link:http://www.praetorian.com/blog/building-a-basic-fuzzer-with-gdb-the-five-minute-gdb-scripting-tutorial

    A few weeks ago, I built a basic fuzzer in GDB for an iPhone application I was testing and I thought it would be worthwhile to share.  Before I get started, I should point out two very useful resources concerning Mac OSX and iOS reversing.  First, nemo’s article is a very informative piece, that helps shed a little light on how easy it is to reverse engineering Objective-C (Obj-C) code [1].  Then there is another site, “Reverse Engineering Mac OS X”, which offers some useful information and a very handy gdbinitrc script [2].

    Building a basic fuzzer in GDB is quite trivial once you understand how to leverage all the GDB commands and define GDB commands.  I must mention that even though the current GDB does support Python, the version of GDB on my MacBook was only 6.3, so there was no Python support built in.

     

    First, lets familiarize ourselves with the commands we will use:

    gdb$ help call
    Call a function in the program.
    The argument is the function name and arguments, in the notation of the
    current working language.  The result is printed and saved in the value
    history, if it is not void.

    call, as you can presume, is going to be used to call several functions, malloc, srand, random, and time.  One item to note is assigning values after gdb calls a function.  I was not sure how to perform a traditional assignment, so I had perform call (return_type) function(parameters, …), then grab the result using the $ operator.  For example:

    call (char *)malloc($size)
    set $buf = $

    Now, lets briefly touch on the define command.

    gdb$ help define
    Define a new command name.  Command name is argument.
    Definition appears on following lines, one command per line.
    End with a line of just “end”.
    Use the “document” command to give documentation for the new command.
    Commands defined in this way may have up to ten arguments.

    The next command we are going to use is define, shown above.  The define command is used to create commands that execute as a gdb command, they start with define and end with end.  An important caveat is naming convention.  The gdb scripting environment lacks scope, so everything is accessible every where.  For example:

    gdb$ set $blah = 10d
    gdb$ define test
    >set $blah = 0xbaad
    >p $blah
    >end
    gdb$ test
    $2 = 0xbaad
    gdb$ p $blah
    $3 = 0xbaad
    gdb$

    Arguments are passed in like so:

    gdb$ define control_flow
    >set $end = $arg1
    >set $beg = $arg0
    >set $ret_value = 0
    >while $beg < $end
    >set $counter = $beg + $ret_value
    >set $beg = $beg + 1
    >end
    >end
    gdb$ control_flow 1 10
    gdb$ p $ret_value
    $5 = 0x78

    Also note above that there is some rudimentary control flow (e.g. while … end).  gdb does not support fancy logic statements, so keep it basic. Now lets write our basic random fuzzer.

    define build_fuzz_buf
    set $size = $arg0
    call (char *)malloc($size)
    set $buf = $
    set $i = 0
    call (int)time(0)
    set $time = $
    call (int) srand($time)
    while $i < $size
    call (char) rand()
    set *(char *)($buf + $i) = $
    set $i = $i+1
    end
    printf “buf: 0xx len: %d ”, $buf, $size
    p $buf
    end

    First, we are going to pass in our argument, which will contain the size of the buffer.  Then we call malloc to create the buffer, and assign it to the $buf variable.  Next we initialize our array counter $i, and then we initialize random with a call to time to get the basic time and srand with our $time value as a parameter.  In the loop, we call rand and then assign the char value to the ith array element. After the loop completes, we print a formatted string with the basic info from the script and we print the address for our buffer with p $buf.

    Now lets apply this to building an Obj-C object.  In this case we will look at a referenced NSString.  Basically, we are going to create an Obj-C NSString to pass on to a function.  Now some of the values were taken at run-time, so they may not reflect the values on your system.

    define get_mem
    call (void*) malloc($arg0)
    set $MALLOC_R = (int)$
    printf “Allocated memory.  $MALLOC_R: 0x%0x ”, $MALLOC_R
    end

    get_mem is a helper function, and I am just using it to allocate memory.  $MALLOC_R is the global return value that I use.  I mention this separately as a courtesy for the reader.  Below is the real magic:

    set $STRING_TYPE_VAL = 0x01393fc0
    set $STRING_REF_VAL = 0x010007ad
    set $STRING_DIRECT_VAL = 0x0100078c

     

    define build_ref_fuzz_string
    get_mem 0x28
    set $STRING_R = $MALLOC_R
    set *$STRING_R = $STRING_TYPE_VAL
    set *($STRING_R+4) = $STRING_REF_VAL
    build_fuzz_buf $arg0
    set *($STRING_R+8) = $
    set $STRING_DATA = *($STRING_R+8)
    printf “Done setting up a direct string. $STRING_R: 0x%0x and data goes here: $STRING_DATA 0x%0x ”, $STRING_R, $STRING_DATA
    end

    In this command, I create a shell Obj-C NSString with the data elements, and it worked for my purposes.  I am sure I missed a few details, which would have caused a crash in the client later down the line, but it worked great against the server.  So basically I allocate a buffer for my NSString object, and then I set the OBJ-C typing information which, $STRING_TYPE_VAL points to the class information and $STRING_REF_VAL is the type of string it is.  Don’t quote me on it, that was just my best guess.  Next, I call my build_fuzz_buf command and then assign the resulting address to the place where the data pointer needs to go.

    A couple of comments related to this script.  I spent a little while staring at the memory dumps trying to make sense of the information, and the pointers and type values were the sum of my effort.  What I mean by this, is my explanation may be wrong but it worked for me.

    Now for context.  As I mentioned a few months ago, I was performing an iPhone assessment, and the client did an awesome job at locking everything down.  Given this fact, I resorted to attacking their server through the iPhone Application.  Truth be told, many people don’t expect to have this happen, but the debugger can be a very powerful tool.  I like to think of it as my Mega Man Arm Cannon, and when I knock down bosses, I get to put another type of ammo into it.  Hope you enjoyed the post.

    [1] nemo. “The Objective-C Runtime:  Understanding and Abusing”, Phrack Vol. 66 File 4.
    [2] fG. “Reverse Engineering Mac OS X”.

  • 相关阅读:
    js:delete 操作符
    ActiveReports 代码控制报表连续打印
    ActiveReports 打印条码无法设置纸张大小?
    《JavaScript高级程序设计》读书笔记之一:几个与原始类型等价的引用类型的常用方法和属性
    js:字符串类型快速转化成数字类型和数字类型快速转化为字符串类型
    js:for...in 语句(JavaScript For...In Statement)
    Internet Explorer Developer Toolbar
    javascript 定义对象的方法
    关于 输入框输入一定数以后跳转的问题
    javascript 关于弹出关闭的例子
  • 原文地址:https://www.cnblogs.com/Proteas/p/3547776.html
Copyright © 2011-2022 走看看