2017-2018-1 20155306 《信息安全系统设计基础》第6周课上测试总结
第二章测试
第一项:(课上已提交)
-
参考附图代码,编写一个程序 “week0601学号.c",判断一下你的电脑是大端还是小端。
-
提交运行结果”学号XXXX的笔记本电脑是X端“的运行截图,要全屏,包含自己的学号信息
第二项:
-
调用附图代码,编写一个程序 “week0602学号.c",用show_int(), show_float()打印一下你的4位学号,参考教材P33打印出匹配的位序列。
-
提交运行结果截图,要全屏,要包含自己的学号信息
相关代码如下:
#include<stdio.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start,size_t len){
size_t i;
for(i=0;i<=len;i++)
printf("%.2x",start[i]);
printf("
");
}
show_int(int x){
show_bytes((byte_pointer) &x,sizeof(int));
}
show_float(float x){
show_bytes((byte_pointer) &x,sizeof(float));
}
void show_pointer(void *x){
show_bytes((byte_pointer) &x,sizeof(void *));
}
int main()
{
float x=5306;
int u=x;
printf("x=%f: ",x);
show_float( x);
printf("u=%d: ",u);
show_int(u);
}
运行截图如下:
未完成原因:
对于本题,当时编代码编了很久,没有结果。后来看同学们的运行截图才发现自己理解错了题意。本要求的是只输出学号的int float型十六进制格式,但我理解成了要把相匹配的位的序列以及相应的十六进制按书上的格式输出。以后上课要审清题意,再做题。
第三项:(课上已提交)
-
编写一个程序 “week0603学号.c",运行下面代码:
1 short int v = -学号后四位
2 unsigned short uv = (unsigned short) v
-
printf("v = %d, uv = %u ", v, uv);
-
在第三行设置断点用gdb调试,用p /x v; p /x uv 查看变量的值,提交调试结果截图,要全屏,要包含自己的学号信息
-
分析p /x v; p /x uv 与程序运行结果的不同和联系
课后练习2.96:
运行截图:
第三章测试
第一项:
- 通过输入gcc -S -o main.s main.c 将下面c程序”week0603学号.c“编译成汇编代码
int g(int x){
return x+3;
}
int f(int x){
int i = 学号后两位;
return g(x)+i;
}
int main(void){
return f(8)+1;
}
- 删除汇编代码中 . 开关的代码,提交f 函数的汇编代码截图,图中用矩形标出函数栈帧的形成和销毁的代码.
-
栈帧(stack frame),机器用栈来传递过程参数,存储返回信息,保存寄存器用于以后恢复,以及本地存储。为单个过程(函数调用)分配的那部分栈称为栈帧。栈帧其实 是两个指针寄存器,寄存器%ebp为帧指针(指向该栈帧的最底部),而寄存器%esp为栈指针(指向该栈帧的最顶部),当程序运行时,栈指针可以移动(大多数的信息的访问都是通过帧指针的,换句话说,就是如果该栈存在,%ebp帧指针是不移动的,访问栈里面的元素可以用-4(%ebp)或者8(%ebp)访问%ebp指针下面或者上面的元素)。总之简单 一句话,栈帧的主要作用是用来控制和保存一个过程的所有信息的。
-
假设过程P(调用者)调用过程Q(被调用者),则Q的参数放在P的栈帧中。另外,当P调用Q时,P中的返回地址被压入栈中,形成P的栈帧的末尾 (返回地址就是当程序从Q返回时应该继续执行的地方)。Q的栈帧从保存的帧指针的值开始,后面到新的栈指针之间就是该过程的部分了。
下面是汇编代码解释:
main:
.LFB0:
.cfi_startproc
pushq %rbp //压栈
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp //形成栈帧结构
.cfi_def_cfa_register 6
subq $16, %rsp //rsp下移,为栈帧分配空间
···
call __stack_chk_fail//调用
.L3:
leave
.cfi_def_cfa 7, 8
ret//出栈,把出栈的内容当作地址,程序跳转到该地址处
第二项:
1 通过输入gcc -S -o main.s main.c 将下面c程序”week0603学号.c“编译成汇编代码
int g(int x){
return x+3;
}
int f(int x){
int i = 学号后两位;
return g(x)+i;
}
int main(void){
return f(8)+1;
}
- 参考http://www.cnblogs.com/lxm20145215----/p/5982554.html,使用gdb跟踪汇编代码,在纸上画出f中每一条语句引起的eip(rip),ebp(rbp),esp(rsb),eax(rax)的值和栈的变化情况。提交照片,要有学号信息。
- 使用disassemble指令获取汇编代码,用i r指令查看各寄存器的值。
- display /i $pc命令在每次执行下一条汇编语句时,都会显示出当前执行的语句。
-x/na +地址,显示该寄存器的值。
第三项(补充实验:缓冲区溢出漏洞实验)
缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况。这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段。这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭,溢出会引起返回地址被重写。
- 通过下面命令,获得str地址。
gdb stack
disass main
-
根据语句 strcpy(buffer+100,shellcode); 我们计算shellcode的地址为 0xffffd020(十六进制)+100(十进制)=0xffffd084(十六进制)。
-
现在修改exploit.c文件!将 x??x??x??x?? 修改为 x84xd0xff
-
攻击漏洞程序并获得root权限。
-
通过命令”sudo sysctl -w kernel.randomize_va_space=2“打开系统的地址空间随机化机制,重复用exploit程序攻击stack程序,观察能否攻击成功,能否获得root权限。
无法获得root权限。
-
将/bin/sh重新指向/bin/bash(或/bin/dash),观察能否攻击成功,能否获得root权限。
无法获得root权限。