Week1--漏洞学习

Posted theffth-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Week1--漏洞学习相关的知识,希望对你有一定的参考价值。

来源于天问之路知识星球的每日安全推送。

ASAN检测不到的bugs

文章链接: https://nandynarwhals.org/bugs-asan-doesnt-detect/

这篇文章是关于三个能够绕过ASAN检测的bugs,之前我没有接触过ASAN,借此了解一下。

在gcc/g++下使用ASAN只需要在编译的时候加上-fsanitize=address,在此选项下编译简单的存在double free的C文件,运行时可以看到检测到double free:

//TODO

在源文章代码的基础上稍加修改在Linux Ubuntu16.04的环境下可以得到预期结果的源代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

struct sample {
    char buf[8];
    uint32_t val;
};

void choice1() {
    puts("1. Overflowing a buffer within a struct.");

    struct sample sample_struct;
    printf("sample_struct.val = 0x%x
", sample_struct.val);
    strncpy(sample_struct.buf, "ccccccccdddd", 12);
    printf("sample_struct.val = 0x%x
", sample_struct.val);
}
/*
void choice2() {
    puts("2. Arbitrary write with integer overflows skipping over shadow mem.");

    char canary[10] = "IAMCANARY";
    char buf[10];

    printf("Canary = "%s"
", canary);

    int position = 2147483616;
    position = position * 2;
    printf("position = %d
", position);
    for (int i = 0; i < 9; i++) {
        buf[position + i] = ‘X‘;
        printf("buf[%d] = ‘X‘
", position + i);
    }

    printf("Canary = "%s"
", canary);
}
*/
void choice2() {
    puts("2. Skipping over shadow memory.");

    char canary[10] = "IAMCANARY";
    char buf[10];

    printf("Canary = "%s"
", canary);

    int position = -64;
    printf("position = %d
", position);
    for (int i = 0; i < 9; i++) {
        buf[position + i] = ‘X‘;
        printf("buf[%d] = ‘X‘
", position + i);
    }

    printf("Canary = "%s"
", canary);
}

void f1(int ** p) {
    int dangle = 0x41414141;
    *p = &dangle;
}

void f2() {
    int override1 = 0x42424242;
    long long int a=1;
    long long int b=2;
    long long int c=3;
    long long int d=4;
    long long int e=5;
    long long int f=6;
    long long int g=7;
    long long int h=8;
    long long int i=9;
    int j=10;
}

void choice3() {
    puts("3. Use of stack variable after returning from a function.");

    int * p = 0;
    printf("p = %p
", p);
    printf("*p = undefined
");

    f1(&p);
    printf("p = %p
", p);
    printf("*p = 0x%x
", *p);

    f2();
    printf("p = %p
", p);
    printf("*p = 0x%x
", *p);
}

int main(int argc, char ** argv) {

    choice1();
    choice2();
    choice3();

    return 0;
}

结果如下:

//TODO

其中choice1对应第一种漏洞:结构体中的缓冲区溢出。首先打印出了栈上未初始化的垃圾数据,其次利用结构体上的变量连续存储,第一个变量溢出,覆盖后一个本不该被赋值的变量,此缓冲区溢出不会被ASAN检测到。

choice2对应第二种漏洞:跳过shadow memory。(由于我在查了一些资料后,对ASAN中的shadow memory仍然不是非常理解,这一部分先翻译原文章的内容。)此漏洞利用在二进制文件上启用了ASAN来执行相同的缓冲区上溢/下溢,通过计算一些偏移量来跳过保护缓冲区的shadow字节。

choice3对应第三种漏洞:从函数返回后使用栈变量。在函数调用返回后,栈空间被销毁,下一次再次调用其他函数时不应该影响上一次调用的结果。但是由于在主函数中连续两次调用函数,会开拓同一段栈空间,因此可能会出现stack-use-after-return的bugs。choice3展示了该bug的一种情况,可以看到ASAN不会检测到使用指向已销毁栈帧的指针的情况。

跟我一起写Makefile

文章链接: https://seisman.github.io/how-to-write-makefile/index.html

Makefile可以实现“自动化编译”,使用make命令就可以实现整个工程完全自动编译。

规则

Makefile的规则包含两个部分:依赖关系、生成目标的方法

target ... : prerequisites ... 
#或者 target : prerequisites ; command
 	command
 	...

target: 目标文件/可执行文件/label

prerequisites:生成该target所依赖的文件或target

command:必须以Tab键开头,说明该target所要执行的命令(任意的shell命令)

==> target依赖于prerequisites中的文件,其生成规则定义在command中。

prerequisites中如果有一个以上的文件比target文件要新,就会执行command定义的命令。

一般来说,make命令会以UNIX的标准Shell,/bin/sh执行命令

书写规则

Makefile中只应该有一个最终目标,第一条规则中的第一个目标会成为最终的目标,也就是make命令所完成的目标。

如果某一行过长,可以使用反斜杠作为换行符。

make支持三个通配符:*?~

Makefile包含的五个部分

  • 显示规则

    说明了如何生成一个或多个目标文件,包括要生成的文件、文件的依赖文件和生成的命令

  • 隐晦规则

    GNU的make可以自动推导文件以及文件依赖关系后面的命令,make看到一个.o文件,就会自动的把.c文件加在依赖关系中,并且推导出cc -c xxx.c命令

  • 变量的定义

    makefile的变量也就是一个字符串:定义字符串xxx=...,则可以通过$(xxx)来使用这个变量

  • 文件指示

    通过inlcude <filename>可以在一个Makefile中引用另一个Makefile文件;make也会引用环境变量MAKEFILES值所代表的所有Makefile,但引入Makefile的“目标”不起作用。

  • 注释

Makefile的文件名

默认情况下:make命令会在当前目录下按顺序寻找文件名为"GNUmakefile","makefile","Makefile",其中"GNUmakefile"只能由GNU的make识别。

GNU make的工作方式

  1. 读入所有的Makefile
  2. 读入被include的其它Makefile
  3. 初始化文件中的变量
  4. 推导隐晦规则,并分析所有规则
  5. 为所有的目标文件创建依赖关系链
  6. 根据依赖关系,决定哪些目标要重新生成
  7. 执行生成命令

当变量出现在依赖关系的规则中,只有当这条依赖被决定要使用了,那么变量才会在其内部展开。

//UNDONE

以上是关于Week1--漏洞学习的主要内容,如果未能解决你的问题,请参考以下文章

个人作业-week1

python3.X学习笔记(week1)老男孩20160114

个人作业-Week1

00.Andrew机器学习week1

Coursera机器学习week1 笔记

Python学习 Week1