To summarize the problem, there is a guy called Alex who works for a company called Recoverysoft . So one day he gets a mail from his friend Teo saying that there was a vulnerability on the webserver and to fix that Teo had sent a binary to fix the vulnerability. So Alex ran the binary.
But it turns out Teo mail account was hacked and the binary was malicious and it did some damage. So now we have to find out and fix the damage caused by the binary.
Alex gave us his ssh credentials and informed us that the malicious binary was in his home directory called fixutil.
So I tried to login in with the credentials that Alex gave me and we got the following message as Alex had mentioned us on the Introduction.
We did get on the box means the credentials were working but we were getting this message means there was an infinite loop printing the text on either .bashrc or .profile of Alex as these files are run when a user logs onto the system
So I tried to log in without executing both .bashrc and .profile.
$ ssh -t email@example.com /bin/bash --norc --noprofile
firstname.lastname@example.org's password: madeline
And it worked. we got a shell.
Upon inspection .bashrc had following code in the last line
So after deleting that line we got our first flag on the site hosted by Alex on port 1337.
But there was a problem with the shell as it kept dying in a few seconds. So after looking around, I found a script on /opt/
brilliant_script.sh was a very interesting file. Not only because it killed our running bash shell but it was owned by root, could be written by anyone and was running constantly probably as a cron job as root. So this could be our ticket for privilege escalation to root.
Instead of deleting the code which was killing the bash shell, I decided to get the stable shell by copying the /bin/bash binary as /tmp/aa and running it.
And now for privilege escalation, I generated ssh key pairs.
And I modified brilliant_script.sh with the following code.
cp /home/alex/id_rsa.pub /root/.ssh/authorized_keys
And after a few seconds, I logged on to the root account with the private key.
And on the website, we got 2 more flags.
At this point, I was thinking of reversing the binary that Alex was talking about, but before doing that I wanted to check the files modified by the attacker after he got into the machine. As Alex mentioned that the attacker encrypted all the files on the webserver so I searched and found the location of files.
root@recoveryserver:~# find / -type f -name *html 2>/dev/null
These files were last modified on Jun 17 which means the attacker was in the box on Jun 17. So I searched for files which were modified 2 days before and 2 days after when the attacker was on the box.
And I found a couple of files. By looking at the files, the attacker might have made changes with users as there was a change in files like /etc/shadow and /etc/passwd. The attacker might have created a cron job /etc/cron.d/evil. And there might be change on some HTML files which might be the encryption of files that Alex was talking about.
Now to know what the attacker actually did, I copied the binary fixutil to my box.
After decompiling on ghidra and looking at the main function, we got
Looking at the source code, there was a while loop appended in .bashrc which we had deleted already. Also the library file /lib/x86_64-linux-gnu/liblogging.so was copied to /tmp/logging.so
As something was written to /lib/x86_64-linux-gnu/liblogging.so, so i downloaded /lib/x86_64-linux-gnu/liblogging.so to my box and used ghidra to decompile the binary.
After decompiling, i found a function called LogIncorrectAttempt. For simplicity, I will show smaller chunks of this function.
Here the attacker
- Moved the original liblogging.so which was first copied to /tmp/logging.so to /lib/x86_64-linux-gnu/oldliblogging.so.
- Added a public key in /root/.ssh/authorized_keys
- Added a user named security with user id and group id as 0(root)
Reverting changes made by the attacker
- Replaced the new liblogging.so with the oldliblogging.so
2. We had already overwritten the authorized_keys during our privilege escalation.
3. Deleted the entry for user “security” from files /etc/shadow and /etc/passwd
And we got two more flags
Remaining part at the LoginCorrectAttempt function in liblogging.so
Looking at the code, there was a function called XOREncryptWebFiles.
- A random string is generated
- The random string gets written to a file /opt/.fixutil/backup.txt.
- GetWebFiles function gets the location of the folder from where apache2 serves the files.
4. Encrypting each file in the directory with function XORFile and with the first parameter being the filename and second being the secret string.
A small chunk of XORFile function
We can clearly see that the contents of the files are encrypted using repeating key XOR.
So I copied all the files of /usr/local/apache2/htdocs/ onto my box and decrypted using code below.
msg = open('filename','rb').read() # filename= encrypted file
key = b'AdsipPewFlfkmll' # key from /opt/.fixutil/backup.txt
length = len(key)
out = ‘’
i = 0
for ch in msg:
out += (chr(ch ^ (key[i%length]))) # xoring each character of msg with key
After decryption, I uploaded the decrypted files on the box using SCP.
$ scp ./* email@example.com:/dev/shm/
index.html 100% 997 2.2KB/s 00:00
reallyimportant.txt 100% 109 0.3KB/s 00:00
todo.html 100% 85 0.2KB/s 00:00
And replacing the encrypted files with the decrypted files.
root@recoveryserver:/dev/shm# cp ./* /usr/local/apache2/htdocs/
And after that, we get our final flag.
This article was first published on medium and regenerated using npm module medium-to-markdown.
You can read my article on medium