pwnable.tw刷题记录
前言pwnable.tw的题目很不错,故在此记录一下
1.Start解题思路:32位,无保护,代码直接用的系统调用。
存在栈溢出,且未开NX,考虑第一次劫持程序流回到程序0x8048087位置泄露栈地址,而后栈溢出写入shellcode
调试分析:明显padding的长度为0x14就能到返回地址,而后劫持程序流回到0x8048087,泄露出栈地址,而后padding一下再劫持程序流到栈上,在栈上布置shellcode就可以了
完整EXP:12345678910111213141516from pwn import *context.log_level = 'DEBUG'r=process("./start")#gdb.attach(r,"b * 0x804808D")payload = 'a'*0x14 + p32(0x08048087)r.recvuntil(':')r.send(payload)#leak stack_addraddr = u32(r.recv(4))+0x14sh ...
ROACTF_2a1
前言ROACTF一道题,劫持方式有点特别,调试的时候也发现劫持link_map结构体能够做到劫持程序流回到main函数之类的,特此记录一下调试过程
解题思路64位的,保护全开
给出libc,存在任意地址泄露8字节,并且能够任意地址写入一个堆地址,堆内容可控
因为没有其他的骚操作,所以关键是在__libc_start_main中调用的exit()函数
首先程序开启了NX,在堆里写shellcode并将堆地址写入_rtld_global结构体里的_dl_rtld_lock_recursive是行不通的
其次题目给的堆块太小了,我们没办法伪造fake_chunk而后劫持_IO_all_list,并且因为太小了,我们劫持IO的vtable也无法将_IO_new_file_setbuf改为one_gadget
在阅读_dl_fini源码,我发现两处可以劫持的地方,这就是我最初的思路(虽然行不通),接下来讲讲调试过程
调试过程首先_dl_fini有一块很有意思的地方
123456789#define DT_FINI_ARRAY 26if (l->l_info[DT_FINI_ARRA ...
NCTF2020
前言NCTF的题目质量都很高,故记录一下调试分析
bruteforce解题思路:查保护,未开PIE,got表可写
只有三个功能:add、edit、delete
add:只能开辟0x30大小的堆,堆地址存储在0x4040B0
edit:能编辑堆内容,存在UAF
delete:free后未置零
虽然是UAF,但是因为限制我们仅能释放一个堆块到fastbin中,而got表头处0x404000存放了地址0x403e20,而我们的chunk的大小固定为0x40,所以我们考虑利用UAF,在got表头处开堆,而后劫持got表中的free,将其改为printf的plt表,而got表头开堆处我们写入一个格式化字符串,这样就当我们调用free的时候就会泄露基地址,得到libc后将free劫持为system,而写入的格式化字符串改为”/bin/sh”即可拿到shell
调试过程:首先确定我们在got表头开堆的位置:
然后写入格式化字符串和printf的plt表
123456add()delete()edit(p64(0x403ffa))add()add()edit("%17$p"+& ...
House_of_Muney
前言:看到大佬博客有一篇关于House_Of_Muney的介绍,觉得挺新奇的,故尝试分析原理。
博客链接:https://maxwelldulin.com/BlogPost?post=6967456768
POC:https://github.com/mdulin2/house-of-muney
关于动态链接库:从Github上clone的POC要使用里面给的libc版本,而且作者也给了修改动态链接库的脚本,不过我本地却有问题,所以记录一下修改动态链接库。
首先把2.31文件夹里的libc-2.31.so改成libc.so.6
然后用patchelf工具,修改ELF文件的动态链接库
1patchelf --set-interpreter 2.31/ld-2.31.so --set-rpath 2.31 ./munmap_rewrite
这样就能运行和调试了,按照作者给出的POC,直接运行是可以弹出shell的
调试分析:0x00先进行初始化操作
123456789clearenv(); // Need to not crash once the shell is popped o ...
铁人三项线上赛pwn题
1.namepie题目分析:除去GOT表可写,其他保护全开,存在两次栈溢出,有后门函数,第一次直接泄露出canary,第二次溢出覆盖返回地址低一个字节,覆盖为后门函数偏移
基本思路:存在两次输入,第一次可以覆盖掉canary的低一个字节,固定为”\x00”,这样通过printf函数可以将canary泄露出来
因为开启了PIE,泄露出了canary后,后续的栈溢出,我们只需要覆盖掉返回地址的低一个字节,覆盖为”\x71”
因为后门函数的偏移是a71,返回地址最后三个十六进制必为axx故我们只需覆盖成”\x71”即可
完整EXP:1234567891011121314151617from pwn import *context.log_level = "debug"#r=process("./namepie")r=remote("172.20.14.170",9999)payload="a"*0x29r.sendafter("Name:",payload)#gdb.attach(r)r ...
glibc-2.31下double free思路
前言在glibc-2.27到glibc-2.28,由于tcache机制没有加入检查机制,仅需要double free两次相同的堆块就可以形成环,我们利用tcache机制可以比fastbin attack更方便的地址任意写,因为它不像fastbin attack存在检查size
但是在glibc-2.29到glibc-2.31,tcache机制加入了检查机制,而tcache的stash机制能让glibc-2.29到glibc-2.31下的double free有一种新的姿势
Tcache检查首先在chunk中插入了指向所属tcache结构体的*key指针
123456typedef struct tcache_entry{ struct tcache_entry *next; //链表指针,对应chunk中的fd字段 /* This field exists to detect double frees. */ struct tcache_perthread_struct *key; //chunk的bk字段,指向所属的tcache结构体} tcache_ ...
Linux内核学习(二)
内存寻址内存地址逻辑地址:包含在机器语言指令中用来指定一个操作数或者一个一条指令的地址称为逻辑地址。
逻辑地址由一个段和偏移量组成。
逻辑地址组成的两部分:段标识符(16位)、指定段内相对地址的偏移量(32位)
段标识符字段称为段选择符
段选择符字段:
线性地址:一个32位无符号整数,也称为虚拟地址,可表示高达4GB(2^30^*2^2^)的地址空间
物理地址:内存芯片级内存单元寻址,由32位或36位无符号整数表示,与从微处理器的地址引脚发送到内存总线上的电信号相对应
内存控制单元(MMU)**通过分段单元,将逻辑地址转化为线性地址,再通过分页单元将线性地址转化为物理地址**
分段寻址硬件分段段寄存器:为了能够快速找到段选择符,处理器提供段寄存器,段寄存器的唯一目的是存放段选择符。
有cs、ss、ds、es、fs、gs六个段寄存器
特别的,cs寄存器还有一个两位的字段,用来表明CPU当前特权级别,0为最高优先级,3为最低优先级;Linux下只用0级和3级,表示内核态和用户态
段描述符:每个段由一个8字节(64位)的段描述符表示
段描述符通常存放在GDT(全局描述符表)或LDT( ...
Linux内核学习(一)
内核源码树根目录描述
目录
含义描述
arch
特定体系结构的源码
block
块设备 I/O层
crypto
加密API
Documentation
内核源码文档
drivers
设备驱动程序
firmware
某些驱动程序需要的设备固件
fs
VFS和各种文件系统
include
内核头文件
init
内核引导和初始化
ipc
进程间通信代码
kernel
调度程序的核心子系统
lib
通用内核函数
LICENSES
内核相关的lincese文件
mm
内存管理子系统和VM
net
网络子系统
samples
示例,示范代码
scripts
编译内核所用的脚本
security
Linux 内核安全模块
sound
语音子系统
tools
在Linux开发中有用的工具
usr
早期用户空间代码
virt
虚拟化基础结构
编译内核配置内核1make config //命令行界面,不建议使用
1make menuconfig //图形界面
1ma ...
House_of_Orange
前言:在做houseoforange_hitcon_2016时涉及了house_of_orange、unsorted bin attack和FSOP,特此复现一下
解题思路:有三个功能,开堆、编辑;堆只能开四个,大小限制在0x1000,编辑堆中存在堆溢出漏洞,而改程序没有free功能,那么需要靠
house of orange来间接使用free功能
House_of_orange
具体请看CTF-WIKI
malloc申请内存时候检测bin中的chunk是否有符合的chunk,若无则尝试使用topchunk,topchunk无法满足时候会尝试使用sysmalloc申请更多的空间,堆有mmap和brk两种分配方式,让堆以brk形式扩展,topchunk会放入unsortedbin中
伪造topchunk的size的条件
伪造的 size 必须要对齐到内存页
size 要大于 MINSIZE(0x10)
size 要小于之后申请的 chunk size + MINSIZE(0x10)
size 的 prev inuse 位必须为 1
调试过程:首先利用house_of_orange ...
从一道简单的堆题学习unlink
前言:做堆题刚入门时做的unlink,一直没机会写wp,现在写写wp复习一下
题目:https://www.jarvisoj.com/
[Xman]level_x64
解题思路:查保护可知got表可写。IDA恢复结构体后发现edit处可以编辑扩展,即在我们编辑的长度上扩展,这样可以造成溢出,我们进行free两个相隔的unsorted bin,然后覆盖第一个free掉的chunk的psize和size,使得泄露出堆的基地址。而malloc后的堆地址会存储在堆头
12345678910New("a"*0x80)#0New("a"*0x80)#1New("a"*0x80)#2New("a"*0x80)#3New("a"*0x80)#4Delete(3)Delete(1)Edit(0,'b'*0x80+'e'*0x10)#覆盖chunk1的psize和size,然后利用list可以泄露出heap_base
同理我们利用这个思路可以再把main_ar ...