Peak Hill WalkThrough TryHackMe

Musyoka Ian
8 min readMay 23, 2020

--

Hello guys back again with another walkthrough peak hill from TryHackMe speaking the truth this box was a little frustrating for me since for the initial foothold you required knowledge on python coding. To escalate your privilege to the second user you required knowledge on how the python script worked. To elevate your privilege to root to required some knowledge on python programming it was a really nice learning experience for me and all thanks to John Hammond the creator of the box. Some people would rate the box as medium but according to me it was a hard box given the fact that you required prior knowledge on programming which i have very little

In Python, when we want to serialize and de-serialize a Python object, we use functions and methods from the module Python Pickle. Pickling, then, is the act of converting a Python object into a byte stream. We also call this ‘serialization’, ‘marshalling’, or ‘flattening’. Unpickling is its inverse, ie., converting a byte stream from a binary file or bytes-like object into an object. This box goes into depth on how this process happens. Without much say lets jump in

As always we’ll start of with a nmap scan of the box

And we get two ports are open and one port is closed

I did a Full port nmap scan and udp scan and got nothing. I decided to enumerate FTP since that’s the most likely attack vector because anonymous ftp login is allowed

Listing for files present in FTP share we get just one file test.txt

I decided to download it to my box

And we see it’s just a text file. I hit a dead end i decided to enumerate ftp further. Sometimes files can hidden if they begin with a dot (.) and if you don’t use the command to list hidden files you might miss it. Doing a listing again using a different command

We get a file called creds that is hidden. I downloaded it to my local box and opening it with a text editor it was a file with binary codes.

This files can be easily decoded with binary decoder tool that is online or offline. The site that is prefer to decrypt coded is cyber chef

Decoding the binary we get gibberish with come words like ssh user ans ssh pass

My first though was that this maybe a zip file and i downloaded the content to my box

And ran file command against it

The file could not be recognized i got stuck for a while here But after some time i realized that it was a serialized object and if you want to retrieve the data, we can with Python

I created the python script below to retrieve the data

import pickle
with open(“download.dat”, “rb”) as file:
pickle_data = file.read()
creds = pickle.loads(pickle_data)
print(creds)

By using this code you can reverse the object to get the exact information

Once we run the script we get the credentials to log into the box via ssh

It’s in an array format and each number represents a character,number or letter and when put together we get a username and password

This credentials can be used to log into the box. Logging into the box via ssh we get a file called cmd_service.pyc

Files of type .pyc are automatically generated by the interpreter when you import a module, which speeds up future importing of that module. These files are therefore only created from a .py file if it is imported by another .py file or module. We can use the uncompyle6 (A native Python cross-version decompiler and fragment decompiler. The successor to decompyle, uncompyle, and uncompyle2.) to get the original python file. I copied the code to my local box and looking at the contents of the file is really not is a friendly readable format

I decided to de-compile using uncompyle6 python library. uncompyle6 translates Python bytecode back into equivalent Python source code.

If you don’t have the library you can install using the command

sudo pip install uncompyle6

On running uncompyle6 we retrieve the python code

And we get the credential credentials that appears to be encrypted

And also from the python script we get that it’s starting a webserver on port 7321

Trying to connect to the web server it asks for credentials and if i supply a wrong credential the program exists after printing Wrong credentials!

So we had to decrypt the credential to log into the web server. I wrote a simple script that decrypts the credential

from Crypto.Util.number import long_to_bytes
username = 1684630636
password = 2457564920124666544827225107428488864802762356L
user= long_to_bytes(username)
passwd= long_to_bytes(password)

print (user+”:”+passwd)

Now that we have the credentials lets log into the web server

Sweet now we have logged into the web server and it seems we have command execution we can get a real shell as dill

But this didn’t work. I decided to create a bash script with a reverse shell which i then can execute

I decided to execute the bash file but it just hangs and we never get a shell

But i did not get a callback. So i decided to keep it simple and just ping myself and see the output

And we get 100% packet loose meaning they is either a firewall or iptables rules that is blocking outgoing connections meaning we can’t get a reverse shell from the box so i decided to manually enumerate the box but the shell we have is not persistent

Looking at dill home directory we get a .ssh directory

Listing the contents of that directory we get a ssh private key

i decided to cat the file and voila we have a ssh key that is not encrypted meaning we don’t have to crack the passphrase

I copied the ssh key back to my box and used it to log into the box as dill. Now we have a persistent shell

Now we can submit the user flag

I decided to run linpeas but remember that there is something blocking outbound connections so i used scp to copy linpeas to the box

And we get the file in gherkin’s home directory

Looking at linpeas output we see some files that had been modified in the last few minutes and we get get ufw.log

Ufw is a Ubuntu firewall program and i guess this is the reason why we were not able to get a reverse shell from the box . I continued looking at linpeas output and i got a binary that we can run as root without knowing the root’s password. This seems like the probable privilege escalation path

I tried executing the program as root it requires user input and it requites the input to be in base64

I decided to base64 my input

And when i ran the binary i got a message “this not grow did not grow on the Peak Hill Farm! :(”. Pickle (like any other serialization / deserialization library) provides a way to execute arbitrary command (even if few developers know it).

In order to do that, you simply have to create an object, and to implement a __reduce__(self) method. This method should return a list of n elements, the first being a callable, and the others arguments. The callable will be executed with underlying arguments, and the result will be the "unserialization" of the object.But we must remember that the object should be base64 encoded

I created a python script that will create the pickle object the source code you can copy below

import pickle
import os
import base64
class EvilPickle(object):
def __reduce__(self):
return (os.system, (‘/bin/bash’, ))
pickle_data = pickle.dumps(EvilPickle())
payload = base64.b64encode(pickle_data)
print (payload)

When we execute the script it will create a base64 encoded payload

Now i copied the payload and tried to execute using the binary

And we get a root shell on the box. Now we can submit the root flag and get the points

And that’s it for now guys till next time take care for reading materials you can get from the link below

  1. Explaining and exploiting deserialization vulnerability with Python (EN)

2. How to: Convert long to byte string

--

--

Musyoka Ian
Musyoka Ian

Written by Musyoka Ian

Penetration Tester/Analytical Chemist who Loves Cybersecurity. GitHub(https://github.com/musyoka101), ExploitDB(https://www.exploit-db.com/?author=10517)

No responses yet