初试IDA与gdb

pwn学习-任务一:

  1. 安装ida;
  2. 安装linux虚拟机,gdb插件,ROPgadget,ropper,pwntools;
  3. 熟悉ida的基本使用–完成sysmagic题目。
  4. 学会使用markdown格式


知识储备:

看书《IDA pro 权威指南》,了解反汇编过程的基础知识及IDA基本使用,在i春秋【CTF精品实战课程】进行IDA基本操作实验。
This is an IDA pro 使用初探. 简单笔记如下:

  1. 反汇编器:撤销汇编过程,因此,我们可以得到汇编语言形式的输出结果(以机器语言作为输入)。需要进行反汇编的常见情况包括以下几种。分析恶意软件;分析闭源软件的漏洞;分析闭源软件的互操作性;分析编译器生成的代码,以验证编译器的性能和准确性;在调试时显示程序指令。

  2. 基本反汇编算法:线性扫描(linear sweep)和递归下降
    (recursive descent)是两种最主要的反汇编算法。
    [1] 确定进行反汇编的代码区域。
    [2]知道指令的起始地址后,读取该地址(或文件偏移量)所包含的值,并执行一次表查找,将二进制操作码的值与它的汇编语言助记符对应起来。
    [3]获取指令并解码任何所需的操作数后,需要对它的汇编语言等价形式进行格式化,并将其在反汇编代码中输出。
    [4]输出一条指令后,继续反汇编下一条指令,并重复上述过程,直到反汇编完文件中的所有指令。

  3. 逆向与反汇编工具:绝不要根据文件的扩展名来确定文件的类型,这是最基本的原则。在脑子里建立起“文件扩展名并无实际意义”的印象.
    [1] 分类工具:

    file:试图通过检查文件中的某些特定字段来确认文件的类型。file 能够识别大量的文件格式,包括数种 ASCII文本文件、各种可执行文件和数据文件。file执行的幻数检查由幻数文件(magic file)所包含的规则控制.
    PE Tools:一组用于分析 Windows 系统中正在运行的进程和可执行文件的工具。
    PEiD:主要用于识别构建某一特定 Windows PE 二进制文件所使用的编译器,并确定任何用于模糊 Windows PE 二进制文件的工具。
    

    [2] 摘要工具:

    nm :列出目标文件每一个符号以及与符号有关的一些信息。大写字母表示全局符号,小写字母则表示局部符号。
    ldd:(list dynamic dependencies),列举任何可执行文件所需的动态库。
    objdump: 可用于显示以下与目标文件有关的信息(以及其他更多信息):节头部,程序文件每节的摘要信息;专用头部,程序内存分布信息,还有运行时加载器所需的其他信息,包括由 ldd 等工具生成的库列表;调试信息,提取出程序文件中的任何调试信息;符号信息,以类似 nm 的方式转储符号表信息;反汇编代码清单,objdump 对文件中标记为代码的部分执行线性扫描反汇编。
    otool :可用于解析与 OS X Mach-O 二进制文件有关的信息,显示与文件的头部和符号表有关的信息,并对文件的代码部分进行反汇编。
    

    [3] 深度检测工具:

    strings: 提取文件中的字符串内容,通常,使用该工具不会受到文件格式的限制。
    反汇编器:PE、ELF 和 MACH-O 文件可分别使用 dumpbin、objdump 和 otool 进行反汇编。两个用于 x86 指令集的流式反汇编器(stream disassembler):ndisasm 和 diStorm。
    
  4. IDA使用切记:
    [1] IDA 不提供撤销功能!也无法命令历史记录列表;

     几乎所有的操作都有其对应的菜单项、热键和工具栏按钮。
     IDA提供方便的、基于上下文的鼠标右键操作菜单。
    

    [2] IDA 对于二进制文件,IDA 不会进行任何初始反汇编,除非你至少确定了一个代码字节。

     它没有可用的文件头信息区分二进制文件中的代码字节和数据字节。这时,IDA 会提醒用户指定文件中的一个地址作为入口点,告诉 IDA 将这个地址的字节转换成代码(C 是用于强制 IDA 将字节作为代码处理的热键)。
    

    [3]IDB文件: 通常,人们说到 IDA 数据库时实际上指的是 IDB 文件。

     IDA 会创建一个数据库,其组件分别保存在 4 个文件中,这些文件的名称与选定的可执行文件的名称相同,扩展名分别为.id0、.id1、.nam 和.til
    .id0 文件是一个二叉树形式的数据库。
    .id1 文件包含描述每个程序字节的标记。
    .nam 文件包含与 IDA 的 Names 窗口中显示的给定程序位置有关的索引信息。
    .til 文件用于存储与一个给定数据库的本地类型定义有关的信息。
     在关闭当前项目时,这 4 个文件将被存档,还可以选择将它们压缩成一个 IDB文件。
    

    [4]加载器:根据程序文件头包含的信息,确定一个虚拟内存布局,并对数据库进行相应的配置
    [5]处理器:确定位于该地址的指令的类型、长度,以及从这个地址继续执行指令的位置(例如,是当前的指令序列还是分支)。

  5. pwntools:CTF框架和漏洞利用开发库,用Python开发,由rapid设计,旨在让使用者简单快速的编写exploit。 ROPgadget.

    扫描二维码关注公众号,回复: 11066953 查看本文章
  6. Ropper : 显示有关不同文件格式的二进制文件的信息 Ropper.

  7. 基本应用软件:静态分析:IDA Pro;动态调试:gdb;Exploit:pwntools(没用到)

  8. 逆向工程:比如你看到别人写的某个exe程序能够做出某种漂亮的动画效果,你通过反汇编、反编译和动态跟踪等方法,分析出其动画效果的实现过程,这种行为就是逆向工程;不仅仅是反编译,而且还要推倒出设计,并且文档化,逆向软件工程的目的是使软件得以维护。

  9. 参考博文IDA 快捷键.



解题过程:

1. checksec检测安全保护 ,发现程序是32位,并开启了RELRO和stack保护。

在这里插入图片描述
了解到,如果使用64位IDA Pro加载器打开32位程序,是无法正常使用反汇编功能,这也是很多新手IDA Pro使用者不能正常F5的主要原因之一。
查询:

RELRO(read only relocation):加强对 binary 数据段的保护的技术。gcc 默认编译就是 partial relro,部分区块在被动态装载(初始化)后,就被标记为只读区块。
Stack Guard:对栈溢出的保护机制,函数执行时,先在栈上放置一个随机标识符,函数返回前会先检查标识符是否被修改,如果被修改则直接触发中断来中止程序,可以有效的防止栈溢出攻击。Canary在后文解题中介绍。
PIE(position-independent executable, 地址无关可执行文件):没有开启的情况下数据段的地址是固定的。

详细介绍参考博文 二进制程序的一些保护措施.

2. 使用IDA Pro 7.0加载目标程序,找到函数 _main_0 ,然后使用快捷键 F5 反编译显示C伪代码如下:

在这里插入图片描述
查询:

函数setvbuf()用来设定文件流的缓冲区,其原型为: int setvbuf(FILE * stream, char * buf, int type, unsigned size);
【参数】stream为文件流指针,buf为缓冲区首地址,type为缓冲区类型,size为缓冲区内字节的数量。

了解到在打开文件流后,读取内容之前,调用setvbuf()可以用来设置文件流的缓冲区(而且必须是这样)。
参考博文IDA快捷键.

3. 双击get_flag()函数,代码前一百行左右均为变量定义,主体部分显示如下:

在这里插入图片描述
大致意思为:打开一文件,读取其中的随机数buf,等待输入某十进制数字v2,如果v2=buf,则进行循环异或运算。返回值的那个其实是canary的保护机制。
查询

canary是一种用来防护栈溢出的保护机制。
其原理是在一个函数的入口处,先从fs/gs寄存器中取出一个4字节(eax)或者8字节(rax)的值存到栈上,当函数结束时会检查这个栈上的值是否和存进去的值一致 。
若一致则正常退出,如果是栈溢出或者加粗样式其他原因导致canary的值发生变化,那么程序将执行___stack_chk_fail函数,继而终止程序。

在本题中保护措施在IDA中显示如下:

在这里插入图片描述
对应:
在这里插入图片描述
汇编指令,此处只列举本题出现的,详细指令参考博文 汇编指令大全.

    - MOV A,B :把B的值送给A其中,A与B可是寄存器或内存地址,也可同时是两个寄存器,但不能同都是内存地址。
    - CMP A,B :比较A与B其中A与B可以是寄存器或内存地址,也可同时是两个寄存器,但不能同都是内存地址。
    - EAX :可以作为累加器来使用,所以它是算术运算的主要寄存器。
    - EBX :一般在计算存储器地址时,它经常用作基址寄存器。
    - ECX: 常用来保存计数值,如在移位指令它用来装位移量、循环和串处理指令中作隐含的计数器。
    - Xor a:a异或操作,主要是用来将a清空
    - 进栈指令PUSH    direct	;(SP)+1 → SP ,(direct) → SP
    - 退栈指令POP    direct
    - ADD A,Rn ;加法指令(A)+(Rn)→A
    - SUB :减法指令 格式UB DST,SRC 执行的操作:(DST)<-(DST)-(SRC)
    - NOP :无作用,可以用来抹去相应的语句
    - 控制转移指令: JE 或JZ 若相等则跳
    - 程序转移指令:CALL 过程调用
    - lea:为加载有效地址(load dffective address)和mov用法一样,指令并不是从制定的位置读入数据,而是将有效地址写入到目的操作数值中。
    - jne:一个条件转移指令。当ZF=0,转至标号处执行。

读懂这些指令对后面理解程序是怎样进行的有很大帮助。

4. gdb调试命令:gdb sys

在这里插入图片描述
可怜的英文水平迫使我一个个查询单词意思。
systemd是Linux系统最新的初始化系统(init),作用是提高系统的启动速度,尽可能启动较少的进程,尽可能更多进程并发启动。
systemd对应的进程管理命令是systemctl,systemctl命令管理systemd的资源Unit
大致就是一些服务,跟解题无关

5. gdb sysmagic,(sysmagic是本题目文件名),调试这个程序

在这里插入图片描述
没有找到调试符号,因为还没运行程序

6. 运行指令 r,任意输入个值,自然buf与v2不等,跳出if语句,结束程序。 在if语句之前加个断点,使程序运行到该处暂停

在这里插入图片描述
成功在get_flag()处设置了本程序的第一个断点(序号为1);断点处的代码地址为:0x80485a4(此值只在本次调试过程中有效)。回过头去看IDA中反汇编窗口源代码:恰好是get_flag第一个可执行语句:

在这里插入图片描述
将静态与动态联合起来,能很快理解题目思路。

7. 运行程序

在这里插入图片描述在这里插入图片描述在这里插入图片描述
在刚设置断点处中止了。

8. gdb指令:n

  • s(单步进入): 执行一行源程序代码,如果此行代码中有函数调用,则进入该函数;
  • n(单步不进入): 执行一行源程序代码,此行代码中的函数调用也一并执行。

在这里插入图片描述在这里插入图片描述
可以看见程序向下进行了一步,继续此操作,程序一直向下进行,到等待输入数值时停止,从IDA静态调试可更方便看见程序执行情况:在这里插入图片描述
此时到达scanf处,任意输入数值,程序继续运行:
在这里插入图片描述在这里插入图片描述
观察程序:
call之前参数进栈;
scanf第一个参数是%d,第二个参数是&v2。ebp-0x7c是v2这个变量的内存地址,将这个地址压栈,然后call scanf的时候根据这个地址,将输入的数据写到这个内存地址里面。
下一步应该通过if条件,要使edx=eax即可。为方便直接明了看见该步骤前后因v2值不同导致程序执行状况的不同,再设置一断点,让程序在scanf &v2处中止.

*9. 查ebp-0x80地址,在scanf处加断点,命令为:b 0x8048712

在这里插入图片描述
转换为10进制数,:(在python中可一步转换)
在这里插入图片描述
继续运行,程序在第一个断点处中止,将十进制数输入,执行命令c,程序在第二个断点处中止。重复上述查询步骤,继续运行,输入第二次查询的十进制值,即成功。显示界面如下:
在这里插入图片描述
GDB查看指定内存地址:

指令:x/  <n/f/u>  <addr>
n:正整数,显示内存的长度,从当前地址向后显示几个地址(units)的内容。
f:显示的格式(format)
  - d (signed decimal)按十进制格式显示变量 
  - a (address)按十六进制格式显示地址,并显示距离前继符号的偏移量(offset)。常用于定位未知地址(变量)。 
u:the unit size)从当前地址往后请求的位宽大小。如果不指定的话,GDB默认是4个bytes。
  -u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字 节,g表示八字节。
  -当我们指定了位宽长度后,GDB会从指内存定的内存地址开始,读写指定位宽大小,并把其当作一个值取出来。

博文推荐,一好用的 gdb速查手册.

本题栈内存储:Why is my teamwork Orange so angry?



markdown格式

  • 标题:

    这是一级标题

    这是二级标题

    这是六级标题
  • 字体:
    这是加粗的文字 这是倾斜的文字`这是斜体加粗的文字
    这是加删除线的文字

  • 引用:

    这是引用的内容

    这是引用的内容

    这是引用的内容

  • 分割线:




  • 图片:

alt:显示在图片下面的文字,相当于对图片内容的解释。
title:图片的标题,当鼠标移到图片上时显示的内容。title可加可不加
center居中,left居左,right居右

列表:

  • 列表内容
  • 列表内容
  • 列表内容
  1. 列表内容
  2. 列表内容
  3. 列表内容

序号- + * \跟内容之间均有空格

  • 表格:
表头 表头 表头
内容 内容 内容
内容 内容 内容

第二行分割表头和内容。文字默认居左;两边加:表示文字居中;右边加:表示文字居右。原生语法两边都要有| 。

  • 代码:

() 代码... 代码... 代码... ()

  • 流程图:
Created with Raphaël 2.2.0 开始 My Operation Yes or No? End yes
发布了6 篇原创文章 · 获赞 7 · 访问量 301

猜你喜欢

转载自blog.csdn.net/weixin_44222568/article/details/105303880
IDA
GDB