top of page

Offensive-S3c: Assignment - OffSec PG


<Introduction>

Hey all, I am Pragmat1c_0n3. In this blog post, I will be conducting a detailed walkthrough of the OffSec Proving Grounds Assignment vulnerable host.



<WHATS COVERED>

I'll provide a comprehensive walkthrough from reconnaissance to post-exploitation. This will include:

  • Port scanning

  • Service enumeration

  • Indirect Object Reference (IDOR)

  • Remote code execution (RCE)

  • Privilege escalation


If you find this content informative and you are interested in cybersecurity, please check back regularly for updates on Cyb3r-S3c. Also for more free content please like and subscribe to the Cyb3r-0verwatch YouTube channel.



<OVERVIEW>

Assignment is a vulnerable host created by Irogir designed to help users practice ethical hacking techniques. Accessible through the OffSec Proving Grounds virtual training lab, this virtual machine features vulnerabilities such as Insecure Direct Object Reference (IDOR), Remote Code Execution (RCE), and various security misconfigurations.



<Recon: Enumerating All the Things>


First, I launched my target host, Assignment. As shown on the screen, it now has an IP. I'll start with active reconnaissance to gather information about the target host and understand its attack surface. This usually involves port scanning and service enumeration to find out what ports are open and what services are running.


To gather detailed information about the target host, I'll execute a comprehensive Nmap discovery scan using the following command shown in the CLI:

  • -sS: Runs a TCP SYN scan to probe open ports without fully completing the TCP connection.

  • -A: Enables “aggressive” mode, augmenting the scan with OS detection, version scanning, and script scanning to provide more detailed results.

  • -T4: Accelerates the scan by increasing the timing template to a faster level.

  • -vv: Generates highly verbose output allowing for a more granular look into the scan's progress and findings.



<Recon: Analyzing the Results>


After thoroughly analyzing the Nmap scan results, I observed that three ports are open on the target host: port 22 (SSH), port 80 (HTTP), and port 8000 (HTTP).

 

The Nmap scan also provided valuable information regarding the operating system and services running on the vulnerable host. The data indicates that the target Assignment, is likely a Linux host. This conclusion is supported by the detected OS type, CPE, and the presence of the SSH service. With the initial discovery scan completed, I will now concentrate my efforts on the HTTP services running on ports 80 and 8000. These ports typically host web services and could potentially reveal additional vulnerabilities or entry points that can be exploited further.



<Recon: HTTP_The Weakest Link>


Browsing to port 80 reveals a login page for the 'notes.pg' web application. From this page, I can gather some preliminary information, such as the existence of a potential user named Jane. The login page also featured both register and login functions that I will need to test further.


Upon reviewing the page source, I didn't find any immediately useful information. To ensure a thorough examination, I manually browsed through the content and scrutinized the page source. Simultaneously, I ran a web fuzzer to search for hidden directories and endpoints. This approach helps save time and ensures that no potential entry points are overlooked.


Browsing to port 8000 brought me to a Gogs page, a self-hosted GitHub service. The page includes both registration and login functionalities that warrant testing.


Upon reviewing the Gogs page source, I found no useful information. To maximize efficiency, I ran a web fuzzer before testing the login and registration functionalities.


I ran Feroxbuster to check on whether it could detect any hidden directories. During its scan it detected 13 directories and pages. 


To validate the Feroxbuster findings, I ran Ffuf with a different wordlist and obtained identical results. After manually reviewing the discovered resources, I decided that testing the login and registration functionalities was necessary.



<Recon: Poking Around the Web Application>


Before I run any tests on the webapp’s register/login functionality I want to setup my web proxy. I set my scope to the webapps running on port 80 and port 8000, as was detected in the Nmap scan. I also set my webproxy to drop all out-of-scope requests to reduce the clutter. I am using Burpsuite because its probably the best tool to use for webapp testing. This toolkit provides a variety of tools, such as the proxy, intruder, repeater, etc… This tool’s capability is too expansive to sum up in this video.


Now that I have Burpsuite setup, I’ll register a test account as shown on the screen.


After clicking submit, Burpsuite displays the request. I can see that it displays the “authenticity_token” along with the “username”, “password”, and “confirm password” data.


After forwarding the requests and responses, the 'notes.pg' webapp brought me to the login screen. 


I went ahead and tried to login as the test account. Reviewing the Burpsuite intercept of the request, I can see it shows the authenticity token, as well as the username and password data. 


I was able to login as the test account. Now that I am logged in I need to do  some recon to see what information is available and what I may need to test.


From the "Dashboard", I clicked “Members” and I was able to view the member accounts. I noticed what looked to be post request data listed as a user account. I will get to that later.


I clicked on the test account and I could see in the URL the test account user ID was 14 and the role is “member”.


The first thing I decided to test, was whether I could access another users account by modifying the user ID in the URL. I modified the 14 to a 1 and pressed enter.


The page loaded the Jane account and I could see the Jane account role was “owner”. Based on this test, I was able to access different a account just by modifying the user ID in the URL.  I decided to test out if I can access anything else.


I’m now on the test account dashboard. I’ll go ahead and create a note by clicking “Create”. 


I created a note called “test” and could see that in the URL the note was identified by a number, in this case ID 6. If changing the ID number worked for the member accounts, it may work for the member notes as well. Let me see if I can indirectly access other members notes.


I tried accessing notes for ID 5 and I got an error that the page did not exist. One interesting thing is I did not get an error advising that I did not have the permission to execute this function. 


I tried to access notes for ID 4 and I got an error “insufficient rights”. This tells me that the account associated with ID4 exists and ID5 did not. The error also tells me that with the member role I will not have the necessary rights to access ID4. 


As noted earlier reviewing the members page, I could see other member accounts. The first one is the Jane account, which I had seen earlier because the Jane account email address was in the contact section, so I am assuming that account is the administrator of the webapp.


Also as noted earlier the Jane accounts role was “Owner”.


Reviewing the other accounts, I can see there is an account called 'forged_owner'. As I noted earlier there appears to be a post request output that shows the “authenticity_token”, username “forged_owner”, and password as “forged_owner”.


When I clicked on the “forged_owner” account, I can see that the account role is also “owner” similar to the Jane account. I’ll try to login with “forged_owner” and see if the post request output is valid.


Using the information on the members page that appeared to display credentials for the “forged_owner” account, I was able to login. 


I’ll go ahead and create a test note. 


Now that the test note has been created I can test if I can access the Jane account, since the “forged_owner” account’s role is owner.


It looks like changing the note ID from 7 to 1 allowed me to verify that this webapp is affected by IDOR (Indirect Object Reference). It allowed me to view the Jane accounts notes. In the notes it looks like it displays Jane's Gogs credentials.


Using the credentials obtained on the 'notes.pg' webapp, I was able to login to the Jane account on the Gogs webapp.


Performing some reconnaissance, I clicked the “Admin Panel” to see what was available. Immediately, I can see the version of Gogs is 0.12.9.



<Exploit Research: Searching for A Way In>


When I googled “gogs 0.12.9 exploit”, I could see a wealth of information pertaining to remote code execution. 


After researching the vulnerability, I decided to try Ressurect0’s proof of concept. 


I’ll go ahead and copy the Git url so that I can clone the PoC on Kali.



<Exploitation: Preparing the Battlespace>


I ran the following Git command shown in the CLI in order to download a copy to Kali.

 

I ran 'ls -la' to verify that I downloaded the exploit successfully. 


I changed directory to the Gogs RCE folder and also did an 'ls -la' to review the contents of the folder. I can already see that I will need to run 'chmod' on the Gogs Python script to make it executable. 


I ran the 'chmod' command as shown in the CLI to make the Python script executable and I also ran the 'ls -la' command to verify that 'chmod' was successful.


In order to execute this exploit, you will need to verify that the dependencies are installed as directed by the Gogs RCE github page. 


To verify that they were already installed, I went ahead and ran the apt command shown in the CLI. As the output shows, Kali already has the latest version installed.


Reviewing the “How to use” section will give you a good understanding of how to execute this exploit.


One thing of note, in the process of running the Gogs Python script I was receiving a “pwn not found” error. This caused the exploit script to fail. To resolve this, I needed to verify that the following packages for “Pwntools” were installed as shown on the screen.



<Exploitation: Gaining A Foothold>


Now that I reviewed the exploit, I will run the following command as shown in the CLI. The -s is for the target host, -u I entered Jane. For -p I entered the password obtained from 'notes.pg' webapp. The -t I set tls to false. The -r is for my IP and port I want the reverse-shell to launch.


Based on the result, it appears that the exploit failed. Reviewing the output it looks like the interpreter did not like the semicolons in the password.


To resolve this I went to the Jane account in Gogs where I reset the password by clicking the profile dropdown, selecting 'My Settings', clicking 'Password', then entering in 'Password1234'.


With the Jane account password changed, I’ll retry the exploit with the new password. 



<Exploitation: Time for Further Enumeration>


After running the command it looks like I successfully logged in as Jane, as shown in the CLI.


I ran 'cd ~' (tilde) to change directory to Janes home directory then ran 'ls -la' to view the contents. Looking at the results I can see the 'local.txt' file.


I ran the 'cat' command on the 'local.txt' to view the hash.


Noticing that my connection gets killed after hitting enter, I will need a more stable connection. I’ll grab a bash reverse-shell one-liner from the “Payload all the Things” Github page.


Now that I am reconnected to the target host, I can start my listener. I started my Netcat listener using the command shown in the CLI.


I used the following reverse-shell bash one-liner to connect to my Netcat listener using the command shown in the CLI.

 

Switching over to my Netcat listener it shows that the target host has connected. I ran the 'whoami' and 'bash -i' commands to verify the account I was logged as and to change the shell.


Now that I am connected via more stable shell, I can start my HTTP server. This will allow me to transfer over Linpeas to enumerate the target host for possible escalation paths.


I changed directory to the '/tmp' folder in order to upload Linpeas. I ran the following Wget command shown in the CLI to download linpeas from kali. Based on the output it looks like Linpeas downloaded successfully.


I ran the 'ls -la' command to verify Linpeas had downloaded successfully. I can see Linpeas in '/tmp', one other thing that I noticed is that Linpeas is not executable.


I ran the 'chmod' command shown in the CLI to make Linpeas executable. I also ran 'ls -la' to verify 'chmod' was successful. 


I’ll run the following command shown in the CLI. The -a tells Linpeas to run all checks and the -e flag tells Linpeas to perform extra enumeration.


Reviewing the “Analyzing .service files” section in the Linpeas output, it showed that the 'gogs.service' was 95% likely an escalation vector based on the Linpeas Legend.


When I 'cat' the 'gogs.service' file using the command shown in the CLI, I can see that the service file executes “/home/jane/gogs/gogs web”.  The Gogs file appears to be located in the Jane account.







This is where I initially started to go down a rabbit-hole. I ran the 'ls -la' command as shown in the CLI and it shows that the 'gogs.service' file is run by root.


Reviewing the Gogs file in the '/home/jane/gogs' folder, I can see that the file is modifiable by the Jane account.


Reviewing the Linpeas output it provided a link to hacktricks that described a method that could possibly be used to exploit the 'gogs service'. It would require me to point the 'gogs.service execstart' to running a reverse-shell script that connects to Kali.


I changed directory to the '/tmp' folder then ran the following command shown in the CLI to create a reverse-shell script that I could use in order to get the 'gogs-service' to try to execute. First I will need to make the bash script executable.


I ran the 'chmod' command shown in the CLI to make the script executable, then ran the ls -la command to verify 'chmod' was successful then the cat command to verify my one-liner.


With my script created I started my Netcat listener, as shown in the CLI.


I changed directory to the '/home/jane/gogs' folder then 

I replaced the Gogs file with the exploit script using the mv command as shown in the CLI. Unfortunately, I realized I had no way to restart the 'gogs.service'. So I need to look for another path.


Although at the moment I have been unsuccessful with escalating my privileges, this was an indication to me that I need to enumerate more. I decided to upload Pspy64 using the following command shown in the CLI. 







Pspy64 is a command-line tool for Linux that allows you to monitor running processes without needing root privileges. This is achieved by scanning the '/proc' folder and using file system watchers to catch even short-lived processes.


I ran the 'ls -la' command to verify that Pspy64 downloaded successfully. As with Linpeas, I needed to run 'chmod' on Pspy64 in order to make it executable.


With that completed, I ran Pspy64, as shown in the CLI. 


Reviewing the output, it looks like a Cronjob is scheduled to run the “clean-tmp.sh” script is run every minute. 


Linpeas did detect the script in the “Other Interesting Files” section. Linpeas unfortunately did not document this script being run as a Cronjob every minute. 



<Post-Exploitation: Privilege Escalation>


I ran the 'cat' command on the clean-tmp script to see what it does. Reviewing the script it appears that the script runs the “find” command in “/dev/shm” looking for files (--type f) and when it finds a file it executes (-exec) a shell (sh) with the -c telling the shell to read the command string ‘rm {}’, the “rm” command tells it to remove any file found, the curly brackets is substituted with the name of the files found, and semicolon terminates the command. 


Analyzing the command further, the use of “sh -c” to execute the “rm” command potentially provides the ability to inject malicious code into the command string. This seems possible because the threat actor can control the filenames within '/dev/shm' folder because '/dev/shm' is like '/tmp', anyone can write to it. Allowing for the threat actor to inject malicious code into the command string, such as arbitrary commands on the system due to user input being allowed and not validated. Lets test this out.


I went ahead and started my Netcat listener on port 4444.


On the target host, I changed directory to '/dev/shm' and I’ll run the following command shown in the CLI. 


Touch is used to create an empty file that will be named after the command between the double quotes.


When executed by the “clean-tmp” script, the semi-colon will work as a command separator appending the Bash one-liner to the end of the “find” command one-liner. In short, if executed, this should cause the root account that runs the “clean-tmp” script to echo the bash one-liner in a Bash shell. 


The '/bin/bash -l' will be run in “login shell” mode, meaning the environment variables, define aliases, start in interactive mode, etc…


The output gets redirected and a TCP connection is created via '/dev/tcp'.


 0<&1 redirects standard input (fd 0) to standard output (fd 1) and 2>&1 redirects standard error (fd 2) to standard output (fd 1) merging both user input and error messages. 


Then pipes the entire command to another instance of bash. This ensures that the command is executed even in a restricted environment where direct execution may be blocked.


After running the command, I got an error that noted that Bash was not found. Based on what I can tell the error may be occurring because spacing in the command or Bash shell encounters a command with multiple redirection operators that it cannot interpret clearly.


To try to resolve the issue, I tried to encode my payload in Base64. I ran the following command shown in the CLI.


With my payload encoded, I replaced my bash one-liner with my encoded payload. 


I typed the “touch” command to create a file.


I typed the 'echo' command to output my encoded payload.


I then piped the output to Base64 to decode.


 Finally piping the decoded payload to a new instance of Bash.


After executing the command on the target host, I checked my Netcat listener. It showed I had a connection from the target host. 



<Post-Exploitation: I Am gRoot>


I ran the 'whoami', 'bash -i', and 'ls -la' commands as shown in the CLI. The output showed that I was root and spawned an interactive shell showing a root prompt. The 'ls -la' command did not execute.


I ran the 'ls -la' command and I could see I was in the root home directory and the 'proof.txt' file was visible.


I ran the 'cat' command on the 'proof.txt' file to view the contents. I was able to retrieve the hash, and with that complete the host.



 </CONCLUSION>


In conclusion, I employed a range of techniques to progress from initial reconnaissance to obtaining root privileges on the Assignment vulnerable host. My initial reconnaissance efforts provided essential information and by following a systematic approach, I was able to gain a foothold on the target. This foothold enabled me to escalate my privileges and ultimately capture the root flag.


Thank you for checking out this walkthrough of OffSec Proving Grounds Assignment vulnerable host. If you find this content informative and you are interested in cybersecurity, please regularly check back on Cyb3r-S3c for updates. For more free content, please like and subscribe to the Cyb3r-0verwatch Youtube channel. Until next time keep learning, the only way to improve is to keep learning.


/Signing Off,

Pragmat1c_0n3

Comments


bottom of page