$ nmap -p- --min-rate 3000 -Pn 192.168.208.116
Starting Nmap 7.93 ( https://nmap.org ) at 2023-07-21 14:41 +08
Nmap scan report for 192.168.208.116
Host is up (0.17s latency).
Not shown: 65530 closed tcp ports (conn-refused)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
139/tcp open netbios-ssn
445/tcp open microsoft-ds
8080/tcp open http-proxy
SMB Enumeration
smbmap shows that we have one share we can read and write to:
$ smbmap -H 192.168.208.116
[+] IP: 192.168.208.116:445 Name: 192.168.208.116
Disk Permissions Comment
---- ----------- -------
print$ NO ACCESS Printer Drivers
Samantha Konstan READ, WRITE Backups and Recycler files
IPC$ NO ACCESS IPC Service (Samba 4.10.4)
We cam connect to that via smbclient.
$ smbclient //192.168.208.116/Samantha\ Konstan
Password for [WORKGROUP\kali]:
Anonymous login successful
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Fri Jul 21 14:42:40 2023
.. D 0 Fri Sep 25 01:38:10 2020
recycler.ser N 0 Thu Sep 24 09:35:15 2020
readme.txt N 478 Fri Sep 25 01:32:50 2020
spring-mvc-quickstart-archetype D 0 Fri Sep 25 01:36:11 2020
thymeleafexamples-layouts D 0 Fri Sep 25 01:37:09 2020
resources.html N 42713 Fri Sep 25 01:37:41 2020
pom-bak.xml N 2187 Fri Oct 2 04:28:46 2020
There are loads of files, including a .ser file within. I noticed that this was running a Java application, based on the spring file, which was a Java framework. The readme.txt included some interesting information:
$ cat readme.txt
The recycler is a critical piece of our industrial infraestructure.
Please be careful with it!
The .ser file holds all the last data saved from the process, it can
be readed from the upper management dashboard app.
Remember to set the location of the file to my home directory "~/backups".
Set this directory to share access so the remote system can access the
file via SMB.
Any concerns or suggestions, please reach at samantha@loca.host.
Samantha Konstan
Java Mantainer
.ser seems to be an important file. There was also mention of a 'dashboard app`, which was likely one of the web applications hosted on this.
Web Enumeration -> Web Creds
Port 80 hosted a corporate website:
I was rather static, so I did a gobuster scan on it using a few wordlists. Using common.txt reveals a hidden directory:
Seems that we have source code. Before delving into this, let's check out port 8080, which hosted the dashboard mentioned in the readme.txt from SMB.
The WebSecurityConfig.java file contained credentials needed to access the dashboard:
publicUserDetailsServiceuserDetailsService() {UserDetails user =User.withDefaultPasswordEncoder().username("recycler").password("DoNotMessWithTheRecycler123").roles("USER").build();returnnewInMemoryUserDetailsManager(user); }
Source Code -> Deserialisation RCE
There was some functionality for this, so let's read the source code to find how it checks status and saves the current values. The code for this can be found within DashboardController.java:
publicclassDashboardController {String filename ="/home/samantha/backups/recycler.ser"; @GetMapping("/check")publicStringCheck( String name,Model model) {Recycler r =newRecycler();FileInputStream fis =null;ObjectInputStream in =null;try { fis =newFileInputStream(filename); in =newObjectInputStream(fis); r = (Recycler) in.readObject();in.close(); } catch (Exception ex) {ex.printStackTrace(); }model.addAttribute("date","Now()");model.addAttribute("total",r.total);model.addAttribute("liquid",r.solid);model.addAttribute("solid",r.liquid);return"dashboard"; } @GetMapping("/save")publicStringSave(Model model) {int tons =ThreadLocalRandom.current().nextInt(1,20);int solid =ThreadLocalRandom.current().nextInt(1,100);int liquid =100-solid;model.addAttribute("date","Now()");model.addAttribute("total", tons);model.addAttribute("liquid", solid);model.addAttribute("solid", liquid);Recycler r =newRecycler();r.setDate("Now()");r.setTotal(""+tons);r.setSolid(""+solid);r.setLiquid(""+liquid);try {FileOutputStream file =newFileOutputStream(filename); ObjectOutputStream out =newObjectOutputStream(file); out.writeObject(r);out.close(); file.close(); } catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace(); } return"dashboard"; }}
We can see that the recycler.ser file is being used for both functions, where /save writes to it using the current values on screen, and /check reads from it. The thing that stood out was the readObject() function being used to read from recycler.ser, which could potentially allow for Deserialisation attacks.
First we need to check if its vulnerable by searching all the SMB and Recycler files for mention of commons-collections.
You must use Java 8 to make it work. The latest versions of Java cannot run ysoserial.jar properly.
This would generate a serialised object that we can use. Afterwards, place this within the share and click on Check Status on the website to get a reverse shell:
Privilege Escalation
Sudoedit Double Wildcard -> Arbitrary Write
I checked our sudo privileges, and saw this:
[samantha@cassios ~]$ sudo -l
Matching Defaults entries for samantha on cassios:
env_keep+="LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET", env_keep+="QTDIR
KDEDIR"
User samantha may run the following commands on cassios:
(root) NOPASSWD: sudoedit /home/*/*/recycler.ser
We can abuse this by creating a symlink to the /etc/passwd file named as recycler.ser and add a new root user to it using this line:
This would bring up the /etc/passwd file, where we can add the new hacker user and use :wq to save the changes made. Then, su to hacker with hello123 as the password: