Brother
Professional
- Messages
- 2,590
- Reaction score
- 544
- Points
- 113
You can see the practical part on how to get likes on social networks, steal cryptocurrency and get access to the biggest secrets of users here and here.
Today we will talk about serialization vulnerabilities and authentication bypass.
This technology is extremely interesting and useful, it makes it easier to save the state of the program between runs or transfer data over the network, helping to save developer time. We can represent an object as a file, transfer it to another server, it is processed there with the same code, and we will receive the same object in memory on another server.
There are quite a few serialized data transfer protocols:
For example, we have serialized some object (here is a Java class). Having written it to a file, most likely, we will see some kind of binary data, where it will obviously not be possible to understand anything.
However, if you start to parse the format of this data, you can see that everything is quite structured and understandable, you just need to read the specification. For example, this header is also different for a ZIP archive. You can understand this by two bytes.
If we further disassemble this format, we will see that you can find the value and change it. All serialization vulnerabilities are based on this. If you look at history, a huge number of different libraries, serious web applications, application servers, and even the frameworks themselves contained these problems.
Let's go back to our serializable object. We have some class that is responsible for the username on the system.
This class has a name (string) field and a userIsAdmin (boolean) field. An important point: in the data that is serialized, only field values are serialized. We cannot serialize the function code itself. Therefore, the only thing you can rely on is changing the value of these fields.
If we serialize an object, then after passing a certain value, the server will write to us: "Hello, Steph!". In this case, the value of the steph field will be the serialized object. And the value of byte 00 indicates the value of the boolean variable. But since this data comes from the user, nothing prevents us from changing it, for example, to 1:
Thus, when this object is deserialized on the server, it will see that the user is now an administrator. This way you can bypass the authorization.
Another interesting example. The 2015 CodeIgniter framework had a serialization issue. The object was not signed, and the user could find data in the cookies that he could change and compromise the server.
I would also like to note a very interesting software - Ysoserial, which contains a list of vulnerable libraries. If our software uses one of them (we may not even assume about it), then we can serialize a special object, which would then be deserialized and, as a result, triggered a vulnerability in the serialized library. This would lead to the execution of the code in our application.
I would also like to draw on special functions (or magic methods) that are called when objects are deserialized and can be overridden in the code. They will be constantly called if there is any internal function such as "execute a console command" inside. And there may already be problems.
If this topic is interesting, I recommend an even larger collection of Alexey Tyurin's GitHub links related to this topic. This is probably one of the most comprehensive repositories on this topic.
There are a few more approaches that can help you avoid problems. In Whitelist, we can define all classes that can be deserialized. The approach is quite effective and, one might say, correct. With BlackList, we can define a list of classes that cannot be deserialized. But it is still possible to get around it.
This allows an attacker to bypass authorization and gain access to system resources by changing the value of the parameter used to reference the object. This is a direct result of the application accepting user input in order to return an object without doing any authorization checks.
In this example, the application loads messages based on the identifier in the URL. For verification, you can specify the identifier of another user's letter.
Let's assume that such a request is sent when you change your own profile settings. For verification, it is worth changing the value "me" to the identifier of another user.
The value for the "user" parameter tells the web application which user needs to change the password. Here, for verification, you can substitute a different username and change its password.
In case the IDs are not incremental, you can quickly check a large range of values using the Intruder tool in Burp Suite. To do this, we specify the tested parameter for enumeration, the search range and the step. After choosing a data type (for example, Numbers), we analyze the results by the size of the response and / or the HTTP status:
Therefore, you need to configure access control so that users cannot perform actions outside their rights and can only access the data they need.
You cannot rely on the complexity of identifiers such as UUID4. The difficulty of "guessing" cannot be an authorization check and does not guarantee that identifiers are not revealed in any other functionality of the web application.
Let's say there is some form of authentication on the site. One of the most common problems is using weak passwords or default accounts. And if you analyze any service, you can even come across an administrative panel.
For example, if the service uses Application Service Tomcat, then in some cases you can go to port 8080 and see the Tomcat management panel and then try to use some default account - for example, tomcat / tomcat. Sometimes it even works, which makes it possible to execute arbitrary code and compromise the service.
On the other hand, this is extremely rare on the Internet, because a huge number of 24 * 7 attackers scan all ranges of IP addresses, looking for such services and picking up access.
Consider a problem that has an authentication form. It is proposed to determine what users generally exist in the system, and try to find several such default accounts - logical ones that would be present in the system (admin, root, etc.).
Suppose we have a router panel (which one is unknown). What are the default account names that can be tested to authenticate? Obviously there is admin, root. Perhaps router, user, or guest. You can also use brands of popular routers - Cisco, Huawei, etc. Sometimes there are even funny root roots. And even if everything has been changed a long time ago, guest can remain open, without a password.
The second option is when the system displays a message that the password is an incorrect password, and as a result, the attacker knows for sure that the user exists in the system, the password is simply incorrect. This is one of the most common authentication problems and one of the most common mistakes.
By the way, before trying these or those passwords, an attacker can look at the registration form on the site and find out what password can be used to register. And immediately reduce the number of rebounds by throwing out those passwords with which you cannot register.
Also, quite often some users use passwords that are somehow related to the service, company, dates and "other memorabilia." Perhaps someone from the MegaBurgerBank company (any matches are random) could use the password for their MegaBurgerBank account! @ # (Any matches are random) or MegaBurgerBank2020 (any matches are random).
To avoid this, it's a good idea to have a list of forbidden passwords on hand. Alternatively, one could generate such a list to carry out a password spraying attack using various tools - for example, this one.
Today we will talk about serialization vulnerabilities and authentication bypass.
Serialization vulnerabilities
Serialization has been around for a very long time. It is the process that converts an object to a stream of bytes. The reverse process - deserialization - restores the original structure of the object without creating a separate text I / O file.
This technology is extremely interesting and useful, it makes it easier to save the state of the program between runs or transfer data over the network, helping to save developer time. We can represent an object as a file, transfer it to another server, it is processed there with the same code, and we will receive the same object in memory on another server.
There are quite a few serialized data transfer protocols:
- RMI (Remote Method Invocation);
- JMX (Java Management Extension);
- JMS (Java Messaging System).
- Exchange of objects between two applications that are not related to each other, for example, Client - Server;
- Caching;
- Cookies, API tokens;
- Saving and restoring the object.
- Binary: Java Serialization, Ruby Marshal, Protobuf, Thrift, Avro, MS-NRBF, Android Binder / Parcel, HOP
- Mixed: PHP Serialization, Python pickle, Binary XML / JSON
- "Readable": XML, JSON, YAML - we ourselves can see what is contained therein
Attack vectors
Comprehensive material on serialization vulnerabilities can be found here. There are exactly two main vectors of attacks related to serialization:- Violations of the logic of the program;
- Remote code / command execution (in some cases).
For example, we have serialized some object (here is a Java class). Having written it to a file, most likely, we will see some kind of binary data, where it will obviously not be possible to understand anything.
However, if you start to parse the format of this data, you can see that everything is quite structured and understandable, you just need to read the specification. For example, this header is also different for a ZIP archive. You can understand this by two bytes.
If we further disassemble this format, we will see that you can find the value and change it. All serialization vulnerabilities are based on this. If you look at history, a huge number of different libraries, serious web applications, application servers, and even the frameworks themselves contained these problems.
Let's go back to our serializable object. We have some class that is responsible for the username on the system.
Code:
Cookie: user=base64(serialized(User.class))
This class has a name (string) field and a userIsAdmin (boolean) field. An important point: in the data that is serialized, only field values are serialized. We cannot serialize the function code itself. Therefore, the only thing you can rely on is changing the value of these fields.
If we serialize an object, then after passing a certain value, the server will write to us: "Hello, Steph!". In this case, the value of the steph field will be the serialized object. And the value of byte 00 indicates the value of the boolean variable. But since this data comes from the user, nothing prevents us from changing it, for example, to 1:
Thus, when this object is deserialized on the server, it will see that the user is now an administrator. This way you can bypass the authorization.
Another interesting example. The 2015 CodeIgniter framework had a serialization issue. The object was not signed, and the user could find data in the cookies that he could change and compromise the server.
I would also like to note a very interesting software - Ysoserial, which contains a list of vulnerable libraries. If our software uses one of them (we may not even assume about it), then we can serialize a special object, which would then be deserialized and, as a result, triggered a vulnerability in the serialized library. This would lead to the execution of the code in our application.
I would also like to draw on special functions (or magic methods) that are called when objects are deserialized and can be overridden in the code. They will be constantly called if there is any internal function such as "execute a console command" inside. And there may already be problems.
If this topic is interesting, I recommend an even larger collection of Alexey Tyurin's GitHub links related to this topic. This is probably one of the most comprehensive repositories on this topic.
Correction and prevention
As always, if the source is untrusted, then it is best to always check what data comes from it.There are a few more approaches that can help you avoid problems. In Whitelist, we can define all classes that can be deserialized. The approach is quite effective and, one might say, correct. With BlackList, we can define a list of classes that cannot be deserialized. But it is still possible to get around it.
Authorization and authentication vulnerabilities
Let's start with perhaps the simplest and most obvious vulnerability to understand - Insecure Direct Object References (IDOR, insecure direct object references) occurs when an application provides direct access to objects based on user input without checking the user's access rights to this object. Well, or doing it incorrectly.This allows an attacker to bypass authorization and gain access to system resources by changing the value of the parameter used to reference the object. This is a direct result of the application accepting user input in order to return an object without doing any authorization checks.
A small example
Code:
GET /mail/message/162974011515471087
In this example, the application loads messages based on the identifier in the URL. For verification, you can specify the identifier of another user's letter.
Code:
PUT /api/v1/profile/me
Let's assume that such a request is sent when you change your own profile settings. For verification, it is worth changing the value "me" to the identifier of another user.
Code:
POST /changepassword.do?user=ivanpetrov
The value for the "user" parameter tells the web application which user needs to change the password. Here, for verification, you can substitute a different username and change its password.
In case the IDs are not incremental, you can quickly check a large range of values using the Intruder tool in Burp Suite. To do this, we specify the tested parameter for enumeration, the search range and the step. After choosing a data type (for example, Numbers), we analyze the results by the size of the response and / or the HTTP status:
Testing
During testing, it is necessary for each role, each function and request that are executed after authentication to check:- Is it possible to access the resource even if the user is not authenticated?
- Is it possible to access the resource after logging out?
- Is it possible to gain access to functions and resources that should be available only to a user with different rights?
- Is it possible to access administrative functions through a user with standard privileges?
- Is it possible to use these functions through a user with a different role?
Correction and prevention
The main problem that leads to the vulnerability is missing or insufficient access rights checks.Therefore, you need to configure access control so that users cannot perform actions outside their rights and can only access the data they need.
You cannot rely on the complexity of identifiers such as UUID4. The difficulty of "guessing" cannot be an authorization check and does not guarantee that identifiers are not revealed in any other functionality of the web application.
Errors in authentication mechanisms
Let's look at a few trivial examples of authentication flaws that are ubiquitous, but mostly present on websites.Let's say there is some form of authentication on the site. One of the most common problems is using weak passwords or default accounts. And if you analyze any service, you can even come across an administrative panel.
For example, if the service uses Application Service Tomcat, then in some cases you can go to port 8080 and see the Tomcat management panel and then try to use some default account - for example, tomcat / tomcat. Sometimes it even works, which makes it possible to execute arbitrary code and compromise the service.
On the other hand, this is extremely rare on the Internet, because a huge number of 24 * 7 attackers scan all ranges of IP addresses, looking for such services and picking up access.
Consider a problem that has an authentication form. It is proposed to determine what users generally exist in the system, and try to find several such default accounts - logical ones that would be present in the system (admin, root, etc.).
Suppose we have a router panel (which one is unknown). What are the default account names that can be tested to authenticate? Obviously there is admin, root. Perhaps router, user, or guest. You can also use brands of popular routers - Cisco, Huawei, etc. Sometimes there are even funny root roots. And even if everything has been changed a long time ago, guest can remain open, without a password.
Using error messages
When guessing a username / password, an attacker can learn something useful for himself even from the system error messages. For example, according to the message "User not found", one can understand whether such a user exists in the system or not.The second option is when the system displays a message that the password is an incorrect password, and as a result, the attacker knows for sure that the user exists in the system, the password is simply incorrect. This is one of the most common authentication problems and one of the most common mistakes.
Frequently used passwords
There are millions of articles about the most commonly used passwords. Naturally, many of these passwords are rather weak and have been compromised for a long time, but even their use can be quite common.By the way, before trying these or those passwords, an attacker can look at the registration form on the site and find out what password can be used to register. And immediately reduce the number of rebounds by throwing out those passwords with which you cannot register.
Also, quite often some users use passwords that are somehow related to the service, company, dates and "other memorabilia." Perhaps someone from the MegaBurgerBank company (any matches are random) could use the password for their MegaBurgerBank account! @ # (Any matches are random) or MegaBurgerBank2020 (any matches are random).
To avoid this, it's a good idea to have a list of forbidden passwords on hand. Alternatively, one could generate such a list to carry out a password spraying attack using various tools - for example, this one.