20169219《Linux内核原理及分析》第十二周作业
格式化字符串漏洞实验
格式化字符串攻击原理是利用格式化函数(如printf())的沿着堆栈指针向下打印的特性,通过只提供格式化字符串但不提供对应的变量,读取栈内空间的内容。
更进一步,通过将某个要攻击的目标地址放入栈中,就可以利用格式化字符串读写里面的值。
因此,它的攻击分为两步:
(1)第一步,将目标地址放入栈中;
(2)第二步,设计格式化字符串,读写目标地址里的值。
格式化字符串漏洞是由像 printf(user_input) 这样的代码引起的,其中 user_input 是用户输入的数据,具有 Set-UID root 权限的这类程序在运行的时候,printf 语句将会变得非常危险。
实验一:
找出 secret[1]的值
输入命令:
ls
vi miao.c
gcc -z execstack -fno-stack-protector -o miao miao.c
其中miao.c的代码为
#include <stdlib.h>
#include <stdio.h>
#define SECRET1 0x44
#define SECRET2 0x55
int main(int argc, char *argv[])
{
char user_input[100];
int *secret;
long int_input;
int a, b, c, d; /* other variables, not used here.*/
/* The secret value is stored on the heap */
secret = (int *) malloc(2*sizeof(int));
/* getting the secret */
secret[0] = SECRET1; secret[1] = SECRET2;
printf("The variable secret's address is 0x%8x (on stack)\n", &secret);
printf("The variable secret's value is 0x%8x (on heap)\n", secret);
printf("secret[0]'s address is 0x%8x (on heap)\n", &secret[0]);
printf("secret[1]'s address is 0x%8x (on heap)\n", &secret[1]);
printf("Please enter a decimal integer\n");
scanf("%d", &int_input); /* getting an input from user */
printf("Please enter a string\n");
scanf("%s", user_input); /* getting a string from user */
/* Vulnerable place */
printf(user_input);
printf("\n");
/* Verify whether your attack is successful */
printf("The original secrets: 0x%x -- 0x%x\n", SECRET1, SECRET2);
printf("The new secrets: 0x%x -- 0x%x\n", secret[0], secret[1]);
return 0;
}
编译后进行执行
并定位 int_input 的位置,这样就确认了%s 在格式字符串中的位置
找到输出中和输入相同的数字,这就是int_input在栈中存储的位置。
下面把secret[1]的地址填进去,并打印相应地址中的内容。(记得做进制转换)同时在格式字符串中加入%s,
结果如图
得到输出结果为U,这正是ASCII码中0x55的对应字母
从打印信息中可以发现secret[0]和secret[1]位于堆,即实际地址在堆中。第
一个secret(即变量secret的值)的地址可以在栈中找到,因为变量secret位于栈中。换句话说,如果想重写secret[0],它的地址已经在栈中,格式化字符串可以利用这一信息。然而,
尽管secret[0]就在secret[1]后面, 但在栈中它的地址无效。
修改 secret[1]的值
修改secret[1]的方法非常简单,仅需把前面的%s替换为%n即可,它的功能是将%n之前printf已经打印的字符个数赋值给传入的指针。通过%n我们就可以修改内存中的值了。和%sleak内存一样,只要栈中有我们需要修改的内存的地址就可以使用格式化字符串的漏洞修改它。
修改的结果是,secret[1]综合那个存储前面输出的字符数。
修改 secret[1]为期望值
为了修改secret[1]为期望值,我们只需要控制前面输出的字符数量。对于每个%x,我们可以修改为%0?x来填充前置0,或使用%.?d来控制小数点后的位数,使其总长度达到特定位数。
实验二
现在让我们把第一个 scanf 语句去掉,并去掉与 int_input 变量相关的所有语句,同时设置关闭地址随机化选项。操作如下:
程序将一个格式化字符串写入了一个叫 mystring 的文件,前 4 个字节由任意你想放 入格式化字符串的数字构成,接下来的字节由键盘输入。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
char buf[1000];
int fp, size;
unsigned int *address;
/* Putting any number you like at the beginning of the format string */
address = (unsigned int *) buf;
*address = 0x113222580;
/* Getting the rest of the format string */
scanf("%s", buf+4);
size = strlen(buf+4) + 4;
printf("The string length is %d\n", size);
/* Writing buf to "mystring" */
fp = open("mystring", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (fp != -1) {
write(fp, buf, size);
close(fp);
} else {
printf("Open failed!\n");
}
}
修改 secret[0]的值
修改 test.c 后编译 test.c 与 write_string.c 然后通过 write_string 程序将内容输入进 mystring 文件中,文件内容包括代码中加入的头四个字节和你之后输入的内容。实验过程如下:
0x31=49=5*8+5个逗号+开头4个字节。
20169219《Linux内核原理及分析》第十二周作业的更多相关文章
- 2018-2019-1 20189221 《Linux内核原理与分析》第八周作业
2018-2019-1 20189221 <Linux内核原理与分析>第八周作业 实验七 编译链接过程 gcc –e –o hello.cpp hello.c / gcc -x cpp-o ...
- 2018-2019-1 20189221 《Linux内核原理与分析》第七周作业
2018-2019-1 20189221 <Linux内核原理与分析>第七周作业 实验六 分析Linux内核创建一个新进程的过程 代码分析 task_struct: struct task ...
- 2018-2019-1 20189221 《Linux内核原理与分析》第六周作业
2018-2019-1 20189221 <Linux内核原理与分析>第六周作业 实验五 实验过程 将Fork函数移植到Linux的MenuOS fork()函数通过系统调用创建一个与原来 ...
- 2018-2019-1 20189221《Linux内核原理与分析》第五周作业
2018-2019-1 20189221<Linux内核原理与分析>第五周作业 实验四 实验过程 当用户态进程调用一个系统调用时,cpu切换到内核态并开始执行一个内核函数. 在Linux中 ...
- 2018-2019-1 20189221《Linux内核原理与分析》第三周作业
2018-2019-1 20189221<Linux内核原理与分析>第三周作业 实验二 完成一个简单的时间片轮转多道程序内核代码 实验过程 在实验楼中编译内核 编写mymain.c函数和m ...
- 2019-2020-1 20199329《Linux内核原理与分析》第十三周作业
<Linux内核原理与分析>第十三周作业 一.本周内容概述 通过重现缓冲区溢出攻击来理解漏洞 二.本周学习内容 1.实验简介 注意:实验中命令在 xfce 终端中输入,前面有 $ 的内容为 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第十一周作业
<Linux内核原理与分析>第十一周作业 一.本周内容概述: 学习linux安全防护方面的知识 完成实验楼上的<ShellShock 攻击实验> 二.本周学习内容: 1.学习& ...
- 2019-2020-1 20199329《Linux内核原理与分析》第八周作业
<Linux内核原理与分析>第八周作业 一.本周内容概述: 理解编译链接的过程和ELF可执行文件格式 编程练习动态链接库的两种使用方式 使用gdb跟踪分析一个execve系统调用内核处理函 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第七周作业
<Linux内核原理与分析>第七周作业 一.本周内容概述: 对Linux系统如何创建一个新进程进行追踪 分析Linux内核创建一个新进程的过程 二.本周学习内容: 1.学习进程的描述 操作 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第六周作业
<Linux内核原理与分析>第六周作业 一.本周内容概述: 学习系统调用的相关理论知识,并使用库函数API和C代码中嵌入汇编代码两种方式使用getpid()系统调用 学习系统调用syste ...
随机推荐
- ZOJ2314 Reactor Cooling(有上下界的网络流)
The terrorist group leaded by a well known international terrorist Ben Bladen is buliding a nuclear ...
- zabbix上的宏(macro)介绍
宏:macro,预设的文本替换模式: 宏是一种抽象概念(Abstraction),它根据一些列预定义的规则替换一定的文本模式,而解释或编译器在遇到宏时会自动进行这一模式替换.类似地,zabbix基于宏 ...
- 利用TaskScheduler处理Queue、Stack等类型的操作队列(生产者消费者场景)
我们经常会遇到生产者消费者模式,比如前端各种UI操作事件触发后台逻辑等.在这种典型的应用场景中,我们可能会有4个业务处理逻辑(下文以P代表生产者,C代表消费者): 1. FIFO(先进先出) ...
- JQ选择器大全
jQuery 的选择器可谓之强大无比,这里简单地总结一下常用的元素查找方法 $("#myELement") 选择id值等于myElement的元素,id值不能重复在文档中只能有一个 ...
- java代码。继承。。。很戳我的心啊。。不太懂。super的真正用法
总结: package com.addd; //构造方法不能被继承,只能是调用 //属性不能被继承,方法可以 //关于继承练习啊 class fjdsk { String name; int age; ...
- Rails上传文件
1.view <%= form_tag({:method =>"post",:controller =>"welcome",:action=& ...
- 手机定位室内gps没信号
手机定位一般分3种,gps,手机信号基站,上网地点,其中gps信号一般只有户外有,所以在室外的时候只开启定位和gps就可以定位了,但是在室内没有gps的情况,就需要开网络定位了.
- apache http 跳到https
RewriteEngine OnRewriteCond %{HTTPS} !=onRewriteRule ^(.*) https://%{SERVER_NAME}/$1 [R,L]
- oracle 在xml中批量插入,批量修改及多组条件查询
最近公司用ibatis开发项目,本来可以用存储过程处理批量插入,批量修改及多组条件查询:但由于使用模块相对较小,暂时就在xml中配置,以前没有在xml做过类似处理,有必要记录一下:好了,代码如下: & ...
- Spring4新的javaConfig注解
1.@RestController spring4为了更方便的支持restfull应用的开发,新增了RestController的注解,比Controller注解多的功能就是给底下的RequestMa ...