Heap Exploitation-unlink
Heap Exploitation - unsafe unlink原理unlink是glibc里的一个宏,是一段代码片段,通常在内存管理系统中使用。为了避免堆内存过度碎片化,当一个非fast bins的堆块被释放时,libc会查看前后堆块是否是释放状态,是就取出合并,这就是unlink。
unlink主要是从双向链表结构中移除一个节点,该节点通常用于跟踪空闲内存块。目的是将某一空闲的chunk从其所处的bin中脱链。在malloc_consolidate()函数中将fast bins中的空闲chunk,整理到unsorted bins中,在malloc()函数中用于将unsorted bins中的空闲chunk整理到small bins中或者large bins中,以及在malloc()中获得堆空间时,均可能调用unlink()宏。
在执行free()时会执行int_free()函数,int_free()函数中调用了unlink宏
#define unlink(AV, P, BK, FD)static void _int_free (mstate av, mchunkptr p, in ...
博客搭建
博客搭建博客崩了一直没修,重搭一下,写一点东西记录一下搭建过程踩的坑。
前置步骤
注册github
下载GitGit (git-scm.com)
绑定自己的github账号
购买域名(这个可以不用买,买的话建议用阿里云,腾讯云的解析记录只能添加三个,有点过于城市化了。)
以上几步跟着文章做就好,比较简单,注意github已将默认分支master改为main,例如文章中git push origin master的master要改为main。
其次,如果提示fatal unable to access ‘httpsgithub.comxxxxxxxxxxx.git’ Recv failure Connection was reset,可以尝试进行如下操作:
在进行过第三步绑定的操作后,输入git config --global -l应该会输出用户名和邮箱
如果没有,或者与实际不符,可以通过
git config --global user.email "你的新邮箱地址"git config --global user.name "你的新用户名" ...
Heap Exploitation-tcache
Heap Exploitation - tcachetcache是glibc2.26(ubuntu17.10)之后引入的一种技术,目的是堆管理的性能,在检测机制上有些变化,也新增了一些利用方式。
TCache全名为Thread Local Caching,它会为每个线程创建一个缓存,里面包含一些小堆块,无需对arena上锁即可使用,提升了分配性能。
数据结构glibc在编译时使用USE_TCACHE条件开启tcache机制,默认开启
#if USE_TCACHE/* We want 64 entries. This is an arbitrary limit, which tunables can reduce. */# define TCACHE_MAX_BINS 64# define MAX_TCACHE_SIZE tidx2usize (TCACHE_MAX_BINS-1)/* Only used to pre-fill the tunables. */# define tidx2usize(idx) (((size_t) idx) * MALLO ...
Heap Exploitation-内存管理概述
Heap Exploitation - 内存管理概述本来想全看完源码写的,发现源码有亿点点多。看了后面忘前面,从效率上来说几乎没有效率,只能先了解大概,然后再慢慢看源码。
堆初始化主要是调用了一个核心函数_int_malloc,所以主要是int_malloc函数的相关操作。以下基于glibc2.23,pwn堆基础题也是基于该版本,后续版本的glibc增加了一些结构和检测机制,在堆管理上也有变化。
内存各结构之前在基础知识已经学习过各个结构,这里再次说明各结构在内存管理中的作用,以便于理解分配与释放过程。
arena分为main_arena(主分配区)和non_main_arena(非主分配区),主分配区通过系统调用brk()和内存映射系统调用mmap()来分配,非主分配区只能够通过mmap来分配。
chunkchunk的第二个域的最低一位为P,表示前一个块是否正在使用,为0即表示前一个chunk空闲,这时prev_size才有效,prev_size表示前一个chunk的size,通过这个值可以找到前一个chunk的开始地址。chunk空闲时,M状态不存在,只有AP状态,原本的用户数据区 ...
Heap Exploitation-Off by one
Heap Exploitation - Off By One原理off-by-one指单字节缓冲区溢出,是一种特殊的栈溢出漏洞,指向缓冲区写入时,写入的字节数超过缓冲区本身申请的字节数并只越界一个字节。这种漏洞的产生往往与边界验证不严和字符串操作有关。off-by-one可以基于各种缓冲区,栈、堆。bss段等等都可以,CTF中常见的是堆中的off-by-one。
循环边界不严谨
int my_gets(char *ptr,int size){ int i; for(i = 0; i <= size; i++) { ptr[i] = getchar(); } return i;}int main(){ char *chunk1,*chunk2; chunk1 = (char *)malloc(16); chunk2 = (char *)malloc(16); puts("Get Input:"); my_gets(chunk1, 16); ...
Stack Overflow-高级ROP
Stack Overflow - 高级ROP只有一部分,基础不太好,等基础学完再填坑。
ret2dlreslove原理之前学习过ELF使用了延迟绑定,基本思想就是当函数第一次被调用的时候才进行绑定(符号查找、重定位等)。
在Linux中,程序使用_dl_runtime_resolve(link_map_obj, reloc_offset) 来对动态链接的函数进行重定位。如果可以控制相应的参数及其对应地址内容就可以控制解析的函数。要注意的是,32位的reloc_arg和64位的有区别:32位使用reloc_offset, 64位使用reloc_index。
具体一点,动态链接器在解析符号地址时所使用的重定位表项、动态符号表、动态字符串表都是从目标文件中的动态节 .dynamic 索引得到的。如果可以修改其中的某些内容,使得最后动态链接器解析的符号是我们想要解析的符号,那么攻击就达成了。
在linux下,二进制引用的外部符号加载方式有三种,FULL_RELRO、PARTIAL_RELRO、NO_RELRO,在PARTIAL_RELRO和NO_RELRO的情况下,外部符号的地址延迟加载。在 ...
Heap Exploitation-内存的分配
Heap Exploitation - _libc_malloc源码分析堆初始化堆初始化是在用户第一次申请内存时执行 malloc_consolidate 再执行 malloc_init_state 实现的。
malloc_consolidate函数是定义在malloc.c中的一个函数,用于将fastbin中空闲的chunk合并整理到 unsorted_bin 中以及进行初始化堆的工作。该函数是free的一个小的变体,专门用于处理fastbin中的空闲chunk,并且负责堆管理中的初始化工作。
malloc_state 的初始化操作由函数 malloc_init_state(av) 完成,该函数先初始化除 fastbins 之外的所有的bins,再初始化 fastbins,清空 fastbins。判断当前 malloc_state 结构体中的 fastbin 是否为空,如果为空就说明整个 malloc_state 都没有完成初始化,需要对malloc_state 进行初始化。
源码:
/* ------------------------- malloc_consolidate -- ...
Heap Exploitation-基础知识
Heap Exploitation - 基础知识堆程序运行过程中,堆可以提供动态分配的内存,允许程序申请大小未定的内存。堆其实就是程序虚拟空间的一块连续的线性区域,它由低地址向高地址生长,并称管理堆的程序为:堆管理器
堆管理器位于程序与内核之间,主要进行以下的工作:
响应用户的申请内存请求,向操作系统申请内存,并将其返回给用户程序。为了保持用户程序的高效性,内核一般都会分配一块很大的连续内存,让堆管理器通过某种算法对其进行管理。只有当堆空间不足时,才会与操作系统进行再次交互
管理用户释放的内存,用户释放的内存并不是直接返回给操作系统,而是由堆管理器进行管理,这样释放的内存可以来响应用户新申请的内存的请求
目前Linux标准发行版中使用的堆分配器是glibc中的堆分配器:ptmalloc2。ptmalloc2主要是通过malloc/free来分配和释放内存块。
堆和栈堆
程序员分配释放,程序员不释放就操作系统回收,分配方式类似于链表。程序自己申请,比如malloc和new这样的。
操作系统有个记录空闲地址的链表,申请后就遍历这个链表,找空间大于申请空间的堆结点,找到第一个 ...
Canary保护绕过
Canary保护绕过基本原理之前学习的栈溢出,有很多都是没有限制输入长度或限制不严格的函数等向栈中写入构造的数据,传统的防御机制就是开启 Canary保护,Canary 实现和设计思想都比较简单, 就是插入一个值,在stack overflow发生的高危区域的栈空间尾部放入一串8字节的随机数据,当函数返回时检测Canary的值是否经过了改变,以此来判断stack/buffer overflow是否发生。若发生改变则说明栈被改变了,进入__stack_chk_fail。验证成功则跳到leave 和 ret正常的返回。
当程序启用Canary编译后,在函数序言部分会取fs寄存器0x28处的值,存到EBP - 0x4(32位)或RBP - 0x8(64位)的位置。 这个操作即为向栈中插入Canary值,代码如下:
mov rax, qword ptr fs:[0x28]mov qword ptr [rbp - 8], rax
栈结构大致如下:
High Address | | +----------------- ...
Linux下的ELF文件、链接、加载与库
Linux下的ELF文件、链接、加载ELF文件ELF文件的三种形式ELF的全称为:Executable and Linkable Format,即 ”可执行、可链接格式“。
在Linux下,可执行文件、动态库文件、目标文件(可重定向文件)都是同一种文件格式,称之为ELF文件格式。虽然都是ELF文件格式但不相同,可以通过file filename查看文件的格式信息
可重定向文件(relocatable)目标文件:通常是.o文件,包含二进制代码和数据,但它的代码及数据都没有指定绝对地址,可以在编译时与其他可重定向目标文件合并起来创建一个可执行目标文件
可执行(executable)目标文件:是完全链接的可执行文件,即静态链接的可执行文件。包含二进制代码和数据,其代码和数据都有固定的地址 (或相对于基地址的偏移 ),可以被直接复制到内存并执行
共享(shared)目标文件:通常是.so动态链接库文件或者动态链接生成的可执行文件。一种特殊的可重定向目标文件,可以在加载或者运行时被动态地加载进内存并链接。动态库文件和动态链接生成的文件都属于这一类。
显然这里的三个ELF文件形式要么是可执行的 ...