使用免费工具进行逆向和利用:第15部分

admin 2022年4月15日10:27:05使用免费工具进行逆向和利用:第15部分已关闭评论39 views字数 4960阅读16分32秒阅读模式

使用免费工具进行逆向和利用:第15部分

原作者:Ricardo Narvaja

翻译作者:梦幻的彼岸

更新日期:2022年2月1日


正如我们在第14部分中所看到的,这个rop将不会像我们以前看到的那样简单。

使用RADARE进行逆向分析练习2--32位

我们打开我们保存的项目,每个命令的解释在第14部分。

打开已保存的项目 (po)

r2 ConsoleApplication9.exe
Po ROP32
afl ~main
s pdb._main
pdf

使用免费工具进行逆向和利用:第15部分

重命名功能(AFN)

现在我们又到了main,我将重新命名pdb._main和pdb._fcp,p main和f,这样更容易访问。

对命令的疑问(?)

如果你对某个命令有任何疑问,在它后面加上"?",我们就能得到帮助。

使用免费工具进行逆向和利用:第15部分

afn我将重命名我所在的函数,因为我在pdb.main中用afn main它将被重命名。

使用免费工具进行逆向和利用:第15部分

然后我将用s pdb._f进入pdb._f,用afn f重命名。

使用免费工具进行逆向和利用:第15部分

我们看到你将其重命名为fcn.f.

我们以v进入视觉模式

使用免费工具进行逆向和利用:第15部分

我们看到我们通过按键: 按Ps ROP32保存的重命名的函数。

浏览菜单 (M)

使用免费工具进行逆向和利用:第15部分

我们看到,通过M键和方向键,我们可以浏览菜单

我所选择的是标有颜色的,但还有很多

使用免费工具进行逆向和利用:第15部分

我们可以在可视模式下配置要显示的面板以及大小,例如:

使用免费工具进行逆向和利用:第15部分

我发现在我的例子中,功能面板和符号太大了,我们可以添加和删除面板,扩大我们想要的面板,并保存布局。

例如,要放大反汇编面板,我们可以使用w键进入窗口模式。

窗口模式(w)

使用免费工具进行逆向和利用:第15部分

使用免费工具进行逆向和利用:第15部分

让我们知道我们处于窗口模式。

用突出显示的箭头显示我想要此资源的面板,我可以更改它的大小。

使用免费工具进行逆向和利用:第15部分

然后用Shift+H,J,K或L的组合,我可以放大或缩小,在我的例子中,我想把它放大到右边,所以我会重复用Shift+L。

使用免费工具进行逆向和利用:第15部分

那里看起来更好,我可以看看我可以添加哪些窗口。

我用w退出WINDOW模式,用M进入菜单,转到VIEW。

使用免费工具进行逆向和利用:第15部分

我可以添加一个反编译窗口

使用免费工具进行逆向和利用:第15部分

我只能按ENTER键聚焦此面板

使用免费工具进行逆向和利用:第15部分

如果我把main放在反编译器的列表视图中,main也会显示在反编译器中。

如果我想把它从面板上移走,我会用W进入窗口模式,然后用SHIFT+X。

使用免费工具进行逆向和利用:第15部分

搜索

如果我们回到菜单,我们会看到一个字符串的搜索。

使用免费工具进行逆向和利用:第15部分

使用免费工具进行逆向和利用:第15部分

让我们看看他找到了什么。

使用免费工具进行逆向和利用:第15部分

在这里我发现了一个可以克服的错误,但是当你重新打开一个项目的时候,有些东西和你第一次运行的时候不一样,我们看到的是字符串的地址,你必须把基地址加到其中才能得到真正的地址。

Python>hex(0x510000+ 0x1a008)
'0x52a008'

而如果我在另一个控制台中打开它而不加载项目,我就会加载符号,进行解析,然后去同一个菜单中寻找字符串。

使用免费工具进行逆向和利用:第15部分

在将项目主题固定到搜索中之前,我们可以看到比较,基本图像必须添加到搜索中,而直接打开并分析它是不必要的,引用和标记也可以很好地工作。

所以我再次打开它,我可以复制并粘贴所有后续的命令到一个控制台上,然后一次执行所有后续的命令,所以如果我复制所有我执行的命令(但是看看项目的rc文件,它们就保存在那里了)

C:\Users\XXXXX\.local\share\radare2\projects\\ROP32

使用免费工具进行逆向和利用:第15部分

还有一个命令可以查看您运行的命令的历史记录。

使用免费工具进行逆向和利用:第15部分

让我们假设,如果我复制重要的命令并将它们粘贴到控制台中,如果我按当时执行它们的顺序放置它们,它们就会一个接一个地执行,而不提示,一切都是一样的,所以在它们修复项目主题之前,我们必须保存我们执行的命令列表。

r2 ConsoleApplication9.exe
idp ConsoleApplication9.pdb
aaa
afvb -1032 buffer int32_t @ 0x511040
afvb -8 pbuffer int32_t @ 0x511040
afvb -1 temp_char char @ 0x511040
s pdb._main
afn main
s pdb._f
afn f
eco bright
pdf

使用免费工具进行逆向和利用:第15部分

我们看到,它被留在以前,现在我可以用v进入。

使用免费工具进行逆向和利用:第15部分

现在菜单中的一切匹配也要搜索ROP GADGETS、HEXA CHAINS等。现在从控制台搜索有很好的机会。

使用免费工具进行逆向和利用:第15部分

找到引用

我们看到各种各样的搜索,尽管对于找到引用来说,/命令不是那么快,如果我输入/calc,它就会找到它。

使用免费工具进行逆向和利用:第15部分

我们看到它显示了字符串calc的地址,它位于整个字符串 “A ejecutar la calculadora”的中间,问题是如果我寻找calc的引用,它不会有,而整个字符串的起始地址却有,使用这个其他命令izz。

使用免费工具进行逆向和利用:第15部分

我们可以看到,即使我搜索的是calc,整个字符串也被设置了,并返回起始地址0x52a008,从这里我可以很容易地用axt命令找到代码中的引用。

在这里,我们看到了找到引用的所有可能性。

使用免费工具进行逆向和利用:第15部分

使用免费工具进行逆向和利用:第15部分

在那里我们看到在main的地址0x51109a,它使用了这个字符串,我可以在listing中看到它,方法是进入v,然后突出listing面板,按g并输入地址。

使用免费工具进行逆向和利用:第15部分

并显示列表中的字符串。

使用免费工具进行逆向和利用:第15部分

如果我们想搜索十六进制字节序列,我们进行如下操作

使用免费工具进行逆向和利用:第15部分

使用免费工具进行逆向和利用:第15部分

这里不需要搜索引用,结果在代码中,我使用v,然后g,在偏移量中输入我想要去的地址

使用免费工具进行逆向和利用:第15部分

使用免费工具进行逆向和利用:第15部分

可以使用冒号作为通配符进行搜索。

使用免费工具进行逆向和利用:第15部分

使用免费工具进行逆向和利用:第15部分

我们看到我可以用地址或标签进入序列

使用免费工具进行逆向和利用:第15部分

使用免费工具进行逆向和利用:第15部分

寻找GADGET

我可以搜索gadgets来创建ROP。

使用免费工具进行逆向和利用:第15部分

在我的案例中,我设置了gadget的长度为2。

e.rop.len

然后是命令

/R comando1 ; comando2; etc ~..

任何列表末尾的修饰符(~...)使得用回车键和pg向上、pg向下滚动成为可能,避免了长的无法阅读的列表。

使用免费工具进行逆向和利用:第15部分

我可以用ENTER或PG DOWN继续向下列举。

将长度改为3

e.rop.len =3

使用免费工具进行逆向和利用:第15部分

你可以用/R/命令使用regexp来查找gadget

/R/ pop e..; ret ~..

将搜索所有以e开头的pops gadget

使用免费工具进行逆向和利用:第15部分

使用免费工具进行逆向和利用:第15部分

您可以找到并搜索多个组合,我们当然会使用它们来解决本练习中的rop。

我们已经知道如何搜索gadget了,现在让我们来分析一下以创建脚本。

在此,我们可以通过按/键并键入pbuffer变量的名称来查看其使用位置。

使用免费工具进行逆向和利用:第15部分

另外,在视觉模式下,当我在图形模式下反复按p键时,我可以改变视觉化的方式,我最喜欢的是这个方式。

使用免费工具进行逆向和利用:第15部分

更加清晰了。

如果你继续按p,还有其他显示,你可以在某些时候使用。

它显示一个方框图,只标记CALL指令。

使用免费工具进行逆向和利用:第15部分

静态逆向

正如我们在下面分析的那样,buffer是变量pbuffer,它存储了缓冲区的地址,它是一个指针类型的变量。

使用免费工具进行逆向和利用:第15部分

我们可以通过命令t看到类型,我们添加了~。才能滚动查看结果。

使用免费工具进行逆向和利用:第15部分

Pbuffer变量是char类型*,我们可以用以下命令更改它

afvt pbuffer char *

或者如果我们更喜欢PCHAR

afvt pbuffer PCHAR

由于缓冲区的长度是0x400,因为缓冲区和下面的变量pbuffer相减后得到了这个距离,我们可以把它改名为

使用免费工具进行逆向和利用:第15部分

afvt buffer char[1024]

现在它更类似于每个变量的实际内容。

使用免费工具进行逆向和利用:第15部分

afvf命令向我显示了堆栈的静态位置,我们知道保存的ebp有4个字节长,返回地址也是4个字节长。(我需要在变量前面加上减号,我会加上的)。

-0x00000408buffer: char[1024]
-0x00000008pbuffer: char *
-0x00000001temp_char: char
0 stored ebp
+4 return address

因此我们看到,从缓冲区到返回地址的距离,我们有一个1024字节的缓冲区变量,然后是一个4字节的buffer变量,3个空字节,1字节的temp_char和4个存储的ebp。

1024(buffer) + 4 (pbuffer) + 3 (vacio) +1(temp_char) + 4 (stored ebp)= 1036

使用免费工具进行逆向和利用:第15部分

这就是我们应该在返回地址之前填充缓冲区的内容,所以我们的脚本应该是这样的。

使用免费工具进行逆向和利用:第15部分

但我们再看一下,问题是

1)我们要用这个来单步到返回地址吗?

2)我们在没有破坏任何东西的情况下到达retn ?

好吧,我们看到有一个无限循环,它有某种形式的输出。

使用免费工具进行逆向和利用:第15部分

在getchar里面读取一个字符并保存在temp_char中,与0x40进行比较,如果相等,则按绿色箭头的true退出循环,如果不等于0x40,则继续与0x10进行比较,如果不相等,则继续循环,这就等于说,如果等于0x10,则退出

如果它仍然在循环内(它不允许循环内的字符是0x40或0x10,正如我们所看到的),它将其保存在ECX的内容中,ECX有缓冲区的pbuffer地址,并指向缓冲区的开始。

保存后,它增加了buffer,以便在下一个循环保存下一个字符。

这似乎一切都是正确的,这意味着如果我们在你点击后加上一个0x40,返回的地址就会出来。

使用免费工具进行逆向和利用:第15部分

请记住,由于我们在Python 3中将b放在每个字节字符串的前面,在这种情况下,它将是b“\ x40”

我们可以用0x41424344单步到返回地址,然后放入一些字节,然后用0x40退出。

但是,它们并不都是flores ,还有一些问题。

使用免费工具进行逆向和利用:第15部分

回顾一下,在buffer下面,有一个变量pbuffer,它将在步入返回地址之前被步入。

这意味着如果我以0x41414141为例对其进行单步,例如,在下一个循环中,我将尝试写入[0x41414141]

使用免费工具进行逆向和利用:第15部分

如果pbuffer使用0x4141414,我会在那里写mov byte[ECX],DL,我们就不能再使用返回地址了。

现实情况是,buffer是一次步进1个字节,所以我们可以步进最低的字节,并让它稍后写入,以跳过写入地址的其他三个字节。

让我们运行脚本并附加它以在 x64dbg 中查看它

使用免费工具进行逆向和利用:第15部分

让我们转到f函数,然后用g看到图形模式。

使用免费工具进行逆向和利用:第15部分

在这里我们有一个pbuffer的块,如果我们把硬件断点放在写上,每次递增它都会停止,所以在它缓冲的地方放一个断点没有什么意义。

使用免费工具进行逆向和利用:第15部分

演示运行并接受MessageBox。

我们可以通过ECX-FOLLOW IN DUMP观察缓冲区在每个周期内的填充情况。

使用免费工具进行逆向和利用:第15部分

找到pbuffer的位置,它应该在下面。

在下一行中,从0x19ff14读取,在那里变量保存从1递增的缓冲区地址。

使用免费工具进行逆向和利用:第15部分

所以当你单步到0x19ff14时,我们将改变它在下一个循环中复制的地址。

使用免费工具进行逆向和利用:第15部分

我们可以将硬件按上述方向写入,这样它就不会在每个周期停止,就像我们将硬件放在同一个pbuffer中一样。

使用免费工具进行逆向和利用:第15部分

我们移除之前设置的断点,只留下这个断点,这样当缓冲区满了时,它就会停止,而这个断点正好要到达指针,让我们运行。

使用免费工具进行逆向和利用:第15部分

在这里,它将跳过前面的4个字节,然后它将跳过pbuffer的最后一个字节,如果我们让最后一个字节为0x18,下一次它将写入0x19ff18,并跳过顶部的3个字节。

使用免费工具进行逆向和利用:第15部分

pbuffer下面有多少字节?

使用免费工具进行逆向和利用:第15部分

也就是说,我们应该写1024字节,然后是0x18,然后我们将停留在返回地址,因为我们继续写在pbuffer下面,我们有3个空字节的temp_char字节,和4个存储的ebp。

3 + 1+ 4 = 8 bytes

使用免费工具进行逆向和利用:第15部分

让我们看看情况是否如此

使用免费工具进行逆向和利用:第15部分

它到达地址的低字节,因此在下一个循环中它应该写入 0x19ff18 并且不触及地址的剩余 3 个字节让我们继续循环跟踪。

使用免费工具进行逆向和利用:第15部分

我在纠结一个问题

在步过它之后增加指针,所以我们要么用0x17步过它,要么我们运行一个完整的字节,我最好用 0x17 来步过它。

使用免费工具进行逆向和利用:第15部分

让我们再试一次。

使用免费工具进行逆向和利用:第15部分

复制0x17让我们继续用F8跟踪循环。

使用免费工具进行逆向和利用:第15部分

现在,如果你从0x19FF18开始写0x24,让我们通过删除所有断点来到达RET。

使用免费工具进行逆向和利用:第15部分

开始ropear的基本脚本。

```python

!/usr/bin/env python

-- coding: utf-8 --

import sys
from subprocess import Popen, PIPE
import struct
import sys
import codecs
import random
import string

payload = b"A" * 1024 + b"\x17" + 8* b"B"+ struct.pack("<L", 0x41424344) + "ABCDEFG" + b"\x40"
p1 = Popen(r"ConsoleApplication9.exe", stdin=PIPE)

print("PID: %s" %hex(p1.pid))
print("Enter para continuar")
p1.communicate(payload)
p1.wait()
```

现在我们已经准备好了,我们将在下一个部分进行。

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月15日10:27:05
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   使用免费工具进行逆向和利用:第15部分http://cn-sec.com/archives/913065.html