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\n”, $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\n”, $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\n”, $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”.

[转]Building a Basic Fuzzer with GDB: The Five Minute GDB Scripting Tutorial的更多相关文章

  1. [gdb][python][libpython] 使用gdb调试python脚本

    https://devguide.python.org/gdb/ https://sourceware.org/gdb/current/onlinedocs/gdb/Python.html#Pytho ...

  2. gdb调试手册 一 gdb概述

    一 gdb概述 gdb调试器的目的是让你了解其他的程序在执行的时候发生了什么或者其他程序崩溃时正在做什么 gdb主要能够在运行中做四类事情(包括这些事情中的一些附加的事情)来帮助你获取bugs a 运 ...

  3. Qtcreator远程调试出现“The selected build of GDB does not support Python scripting.It cannot be used .."

      版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/aristolto/article/details/77370853 之前使用的是Qt4.7后来换 ...

  4. gdb常用命令及gdb调试多进程/线程程序&coredump

    一.常用普通调试命令 1.简单介绍GDB 介绍: gdb是Linux环境下的代码调试⼯具.使⽤:需要在源代码⽣成的时候加上 -g 选项.开始使⽤: gdb binFile退出: ctrl + d 或 ...

  5. 使用GDB 追踪依赖poco的so程序,core dump文件分析.

    前言 在windows 下 系统核心态程序蓝屏,会产生dump文件. 用户级程序在设置后,程序崩溃也会产生dump文件.以方便开发者用windbg进行分析. so,linux 系统也有一套这样的东东- ...

  6. gdb 技巧

    现实数组: 比如说要显示a[10]中全部的内容用 p a显示的是地址,用p *a显示的是第一个元素显示全部或某一个:p (int [10])*a或者p *a@10 如果你使用 p *a@3 或 p * ...

  7. c语言,gdb

    Get gdb call stack http://blog.csdn.net/zoufeiyy/article/details/1490241 Debugging with GDB - Examin ...

  8. 学习的例子gcc+gdb+make

    1 小侃GCC 在正式使用gcc之前,我们先来侃侃gcc是啥玩意儿? 历史 如今的GCC是GNU Compiler Collection的简称.既然是Collection,就是指一些工具链的集合. 最 ...

  9. mac下配置gdb调试golang

    mac下配置gdb调试golang 原文链接 https://sourceware.org/gdb/wiki/BuildingOnDarwin Building GDB for Darwin Crea ...

随机推荐

  1. Windows移动开发(一)——登堂入室

    開始本博客之前先分享一个自己的好消息吧,2014年3月31日起,正式就职于北京****集团Win8project师.主要负责将IOS和Android应用移植到Win8.1平板上,目标客户是银行,闲话不 ...

  2. linux后台server开发环境的部署配置和验证(nginx+apache+php-fpm+FASTCGI(C/C++))

    linux后台server开发环境部署配置 引言 背景 随着互联网业务的不断增多.开发环境变得越来越复杂,为了便于统一server端的开发部署环境,特制定本配置文档. 使用软件 CentOS 6.3( ...

  3. HDU 2616 Kill the monster (暴力搜索 || 终极全阵列暴力)

    主题链接:HDU 2616 Kill the monster 意甲冠军:有N技能比赛HP有M怪物,技能(A,M),能伤害为A.当怪兽HP<=M时伤害为2*A. 求打死怪兽(HP<=0)用的 ...

  4. 只有有lua编译能力不足200K代码吧?NO! Python 有可能。

    如今Python给人的感觉是大,东西多,在Windows上安装后竟然要占100多兆的空间. lua给人的感觉是非常小,非常轻便.Python 2.7在linux下编译出来的代码在strip之后也有3M ...

  5. MVC4

    MVC4 本地正常运行,发布到IIS7->403 - 禁止访问: 访问被拒绝. 摘要: 上周五代码编写完成,计划发布一个版本测试,没想到发布到IIS7 竟然报错“403-禁止访问”.还真第一次遇 ...

  6. C++中public,protected,private访问

    对于公有继承方式: (1)父类的public成员成为子类的public成员,允许类以外的代码访问这些成员:(2)父类的private成员仍旧是父类的private成员,子类成员不可以访问这些成员:(3 ...

  7. Lua的多任务机制——协程(coroutine)

    并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上有这么两种多任务技术,一种是抢占式多任务(preemptive multitasking),它让操作系统来决定 ...

  8. &lt;&lt;Python基础课程&gt;&gt;学习笔记 | 文章13章 | 数据库支持

    备注:本章介绍了比较简单,只是比较使用样品,主要假设是把握连接,利用数据库.和SQLite做演示样本 ------ Python数据库API 为了解决Python中各种数据库模块间的兼容问题,如今已经 ...

  9. Windows下C语言的Socket编程例子(TCP和UDP)

    原文:Windows下C语言的Socket编程例子(TCP和UDP) 刚刚学windows编程,所以想写学习笔记,这是一个简单的Socket程序例子,开发环境是vc6: 首先是TCP server端: ...

  10. Android高效的应用程序开发工具集1---ant构建一个简单的Android工程

    在java编译那些事通过提到ant编译Java工程,如今扩大到用它来构建Android目,事实上道理是相通的.变化的仅仅是使用的形式.ant构建相比IDE的优点是多个子项目使用自己定义jar包时,an ...