跳转至

Format String

约 766 个字 21 张图片 预计阅读时间 4 分钟

任务 1:使程序崩溃

首先我们从 server 中获取地址信息:

我们输入 10 个 %s,使程序将栈上 10 个 4 字节的数据当作字符串地址去读取,Payload 如下:

程序会崩溃:


任务 2:打印服务器程序的内存

任务 2.A:栈数据

我们输入一个数据 num,通过 100 个 %x 来读取栈上 100 个 4 字节的数据,Payload 如下:

得到 server 输出如下:

可以看到 num 出现在了第 64 个 %x 的位置上


任务 2.B:堆数据

我们通过之前的信息知道秘密字符串的位置在 0x080b4008,因此我们可以将这个当作一个地址,用 %s 来读取,Payload 如下:

得到 server 输出如下:

所以秘密字符串为 A secret message


任务 3:修改服务器程序的内存

任务 3.A:将值更改为不同的值

修改地址为 target 的地址,将之前的 %s 改为 %n,Payload 如下:

得到 server 输出如下:

可以看到我们成功修改了 target 的值,且说明了之前输出了 0xec=236 个字节


任务 3.B:将值更改为 0x5000

我们利用宽度控制符,限定地址以 %.8x 输出,再在最后一个 %x 补齐,控制输出的字节数为 0x5000 即可,Payload 如下:

得到 server 输出如下:

可以看到我们成功将 target 的值修改为 0x5000


任务 3.C:将值更改为 0xAABBCCDD

我们利用长度修饰符来减少填充的字符数,Payload 如下:

得到 server 输出如下:

可以看到我们成功将 target 的值修改为 0xAABBCCDD


任务 4:向服务器程序注入恶意代码

理解栈布局

根据我们获得的地址信息,标记为 ② 的位置的内存地址即为 myprintf() 函数的返回地址位置,即 ebp+4=0xffffd5dc,标记为 ③ 的位置的内存地址即为 buffer 的位置,即 0xffffd6b0,我们需要 64 个 %x 才能使参数指针移动到 ③


任务

根据上面得到的数据,设置跳转地址为 0xffffd8b0(NOP 区域),覆盖返回地址 0xffffd5dc,构造 Payload 如下:

运行即可获得 Reverse Shell:


任务 5:攻击 64 位服务器程序

首先获得服务器的地址信息:

同理,我们可以通过任务 2.A 的方法得知需要 34 个 %lx 就可以到达 buffer 的地址,由于地址存在 0x00 字节会导致 printf 函数将其后面的内容都不再当作格式字符串使用,所以我们将构造的格式字符串放在前面,将要覆盖的地址放在后面(offset 为 256),并通过 k$ 进行访问和覆写(其中第一个 2 字节的位置即为 \(\frac{256}{8}+34=66\)),构造 Payload 如下:

运行即可获得 Reverse Shell:


任务 6:解决问题

我们只要修改 format.c 的 printf 函数即可修复漏洞:

重新编译,可以看到,警告消失了:

进行任务 2.A 的攻击:

可以看到,我们没能读取出栈上的值,攻击失败

评论