Demystifying PHP Object Injection

Hello readers, in this blog post, our consultant Aditya has discussed the PHP Object Injection vulnerability. He explains the vulnerability details, minimum requirements, vulnerability techniques, vulnerability chaining with other vulnerabilities, recommendations, practice labs, and much more.

PHP’s popularity has been consistent since its beginning, and statistics show that it is a preferred language for many web application developers. This is one of the reasons why PHP has long piqued the curiosity of the information security community. Another reason PHP is well-known in the information security field is because of its use in various Content Management Systems (CMS), the source codes for which are publicly available on platforms such as GitHub. Since the source codes are open source in nature, several vulnerabilities have been uncovered that are particular to applications and systems that use PHP as their preferred language.

The variety and number of vulnerabilities discovered in PHP-based applications are significant. However, not all of the discovered vulnerabilities are easy to comprehend and detect, and hence the majority of security professionals and developers overlook or ignore those vulnerabilities. PHP Object Injection is one such vulnerability that falls into this category, which we will discuss in this blog so that the reader has a better understanding of this obscure vulnerability, why it exists, and how an attacker might exploit it. In addition, we have created a compilation of four practice labs on our platform Vulnmachines where you may navigate and gain hands-on experience with various real-life scenarios.

TL;DR

  1. PHP Object Injection occurs as a result of the deserialization of data from insecure sources, such as user-supplied input, and the absence of integrity verification measures.
  2. PHP Object Injection makes use of magic methods, which are predefined PHP methods that help in the exploitation of this vulnerability.
  3. Several vulnerabilities such as Command Injection, Path Traversal, Authentication Bypass, and others can be chained with PHP Object Injection to enhance the impact.
  4. An intentionally vulnerable testing playground is available on Vulnmachines for hands-on practice.

Serialization and the serialize() method

Serialization is the process of transforming an object into a value representation to store it in a memory buffer or transfer it to a database, via a network, or to a file. When serialization is performed it is ensured that the state of the object is also maintained, which implies that the properties of the object, as well as their allocated values, are retained. The primary goal of serialization is to store an object’s state, so that it may be recreated when needed.

The ‘serialize()’ method in PHP accepts a single parameter which is the data we want to serialize and converts it into a storable representation of value that can be returned by the method as a serialized string. Other than resource-type data, such as references to external resources and certain objects, the ‘serialize()’ method can handle all types of values. 

The table below outlines the basic structure of a PHP serialized string, which will assist in understanding the serialized strings explained in the subsequent code samples throughout the log post.

Annotation

Description

O:4

Represents an object with the length of class name as 4

s:4:”test”

Represents the parameter name as a string of 4 characters i.e., “test”

a:2

Represents an array of 2 elements

i:2

Represents an element at index two

b:1

Represents a Boolean

d:1.1

Represents a Float

The following table summarizes the technical details associated with the serialize() method:

Syntax

serialize(value)

Parameter Value

Mandatory

Return Type

String

Return Value

A String of byte-stream representation of the specified parameter value, which could be stored anywhere.

Example:

The preceding code snippet creates a ‘SerializationExample’ class object and then generates the serialized string representation of that object:

O:20:”SerializationExample”:1:{s:4:”data”;a:3:{i:0;s:3:”The”;i:1;s:6:”SecOps”;i:2;s:5:”Group”;}}

A better understanding of the above-serialized string representation of the object can be obtained from the below table:

Annotation

Description

O:20

Represents an object with the length of class name as 20

s:4:”data”

Represents the parameter name as a string of 4 characters i.e., “data”

a:3

Represents an array of 3 elements

i:0

Represents an element at index zero

Deserialization and the unserialize() method

Deserialization is the process of reassembling an object or data structure from a single serialized variable into a PHP value.

When a serialized string containing an object and its properties is passed to the ‘unserialize()’ method, the ‘unserialize()’ method will perform Object Instantiation, which is the process of recreating an instance of the provided initially serialized object in memory. Once the object has been recreated in memory, PHP will attempt to invoke the ‘__wakeup()’ magic method and execute the code in the ‘__wakeup()’ method; if a ‘__wakeup()’ method exists, the code will be performed in the existing method.

The ‘__wakeup()’ magic method can recreate any properties that the original object has had. The ‘__wakeup()’ magic method is meant to be used to restore any database connections that may have been lost during serialization and to execute additional reinitialization operations. When no reference to the deserialized object instance exists, the ‘__destruct()’ magic method of that class is invoked.

Example:

The preceding code snippet recreates the ‘SerializationExample’ class object from the serialized string representation of that object.

The following table summarizes the technical details associated with the ‘unserialize()’ method:

Syntax

unserialize(string, options)

Parameter String

Mandatory (Serialized String)

Parameter options

Optional (Could be an array of class names, false for no classes and true for all classes)

Return Type

String, Boolean, Array, Float, Integer, or Object

Return Value

The unserialized value

What is PHP Object Injection?

When the user-supplied input is not properly validated and sanitized before being sent to the ‘unserialize()’ PHP function, PHP Object Injection occurs. Since PHP supports object serialization, attackers could supply arbitrary serialized strings to a susceptible ‘unserialize()’ method, resulting in the injection of arbitrary PHP object(s) into the application. PHP Object Injection allows for the unrestricted alteration of object content, which must be unserialized using the PHP ‘unserialize()’ function.

Prerequisites

The following prerequisites must be satisfied in order to properly exploit a PHP Object Injection vulnerability:

  • On the injection points, the application must not have a comprehensive input validation mechanism.

  • The application must not validate the serialized data’s integrity and must enable deserializing data from untrusted sources.

  • A class that implements at least one PHP magic method must be present in the vulnerable application (In the parts that follow, there will be further information about these).

  • All of the classes used during the attack must be declared when the vulnerable ‘unserialize()’ is being called, otherwise object autoloading must be supported for such classes.

Impact

The impact of PHP Object Injection depends largely on the context where it is discovered; however, it enables an attacker to execute a variety of malicious attacks, including but not limited to Code Injection, SQL Injection, Path Traversal, and Application Denial of Service, among others.

Since we now understand what PHP Object Injection is and what prerequisites must be satisfied for it to exist, and what impact it has, let us now look at the showstopper, i.e., the magic methods, which play a critical part in the existence of this exotic vulnerability.

Magic Methods

PHP magic methods are methods that are automatically invoked when specific criteria are satisfied. As they are predefined methods, one cannot have functions with these names in any of the classes unless users desire the accompanying magic functionality. A magic method is easily distinguished from conventional methods since it begins with a double underscore in PHP.

PHP includes 15 magic methods that can lead to PHP Object Injection, all of which are listed in the table below:

Magic Method

Details

__call()

When a non-existing or inaccessible method is called by an object, PHP will automatically invoke the ‘__call()’ magic method using the name of the method you requested to call and the argument you provided as parameters.

The below-mentioned code snippet utilizes the ‘getAnyRandomData’ method, which is not declared anywhere in the above code snippet, and therefore the ‘__call()’ magic method is invoked.

__callStatic()

When an inaccessible static method of a class is called by an object, PHP will automatically invoke the ‘__callStatic()’ method.

The below-mentioned code snippet utilizes the ‘getAnyRandomData’ static method, which is not declared anywhere in the above code snippet, and therefore the ‘__callStatic()’ magic method is invoked.

__clone()

When an object is cloned in PHP with the clone keyword, the ‘__clone()’ magic method is invoked. After the object has been cloned, the ‘__clone()’ magic method is used to manipulate the object’s state.

The below-mentioned code snippet utilizes the ‘clone’ keyword as a result of which PHP invokes the ‘__clone()’ magic method.

__construct()

Due to the fact that it is used to configure a class when it is initialized, PHP’s ‘__construct()’ method is the most frequently used magic method. Classes with a constructor method utilize this method on newly formed objects, making it ideal for any initialization that the object may require before it is utilized. Classes with a ‘constructor’ method utilize this method on newly formed objects, making it ideal for any initialization that the object may require before it is utilized.

The below-mentioned code snippet utilizes the ‘__construct()’ magic method which is invoked by PHP when the object of the ‘constructMagicMethod’ class is created.

__debugInfo()

The ‘__debugInfo()’ magic method is executed when an object is utilized inside the ‘var_dump()’ method to dump information for debugging purposes. The ‘__debugInfo()’ magic returns an array of variables that might be helpful while performing debugging.

The below-mentioned code snippet utilizes the ‘__debugInfo()’ magic method which is invoked by PHP when the object of the ‘debugInfoMagicMethod’ class is used inside the ‘var_dump()’ method as a parameter.

__destruct()

PHP automatically invokes the ‘__destruct()’ magic method when the object is destroyed at the end of the program and no longer serves usage.

The below-mentioned code snippet utilizes the ‘__destruct()’ magic method which is automatically invoked by PHP when the object of the ‘destructMagicMethod’ class is destroyed at the end of the program and no longer serves usage.

__get()

The ‘__get()’ magic method is invoked when an inaccessible private or protected variable, or a variable that does not exist, is used.

The below-mentioned code snippet utilizes the ‘__get()’ magic method inside the ‘getMagicMethod’ class which is invoked by PHP when a non-existing variable is used.

__invoke()

When an object is treated as a function, the ‘__invoke()’ magic method is called. The major function of the ‘__invoke()’ method is that you may implement it if you wish to represent your objects as callable.

The below-mentioned code snippet utilizes the ‘__invoke()’ magic method which is called automatically by PHP when the object of the ‘invokeMagicMethod’ class is treated as a function.

__isset()

The ‘__isset()’ magic method is triggered when a call is made to the ‘empty()’ or ‘isset()’ method on an inaccessible or non-existent object property.

The below-mentioned code snippet uses the ‘isset()’ function on the Test property, which is absent from the ‘issetMagicMethod’ class, and thus the ‘__isset()’ magic method is triggered.

__set()

When an inaccessible variable, such as a private or public variable, or a non-existent variable, is edited or altered, PHP automatically invokes the ‘__set()’ magic method.

The below-mentioned code snippet utilizes the ‘__set()’ magic method inside the ‘setMagicMethod’ class which is invoked automatically by PHP when a non-existing variable i.e., ‘$absentVariable’ is used or altered.

__set_state()

The ‘__set_state()’ magic method is a static method that works with the ‘var_export()’ function. When using this magic method to export classes, the ‘var_export()’ function must be specified in the class.

In the below-mentioned code snippet PHP automatically invokes the ‘__set_state()’ magic method when the object of the ‘setstateMagicMethod’ class is passed to the ‘var_export()’ function.

__sleep()

The ‘__sleep()’ magic method is triggered when the ‘serialize()’ function is invoked on an object. Specific properties are saved during serialization under certain cases, and the ‘__sleep()’ magic method returns an array containing the names of properties that must be serialized.

The below-mentioned code snippet utilizes the ‘__sleep()’ magic method which will be invoked when the object of the ‘sleepMagicMethod’ class will be passed to the ‘serialize()’ function and only the properties i.e., ‘firstName’, ‘middleName’, and ‘lastName’ will be preserved.

__toString()

When an object is represented or processed as a string, PHP automatically invokes the ‘__toString()’ magic method. Essentially, this magic method assists in expressing what must be showcased when the object is processed as a string. If the ‘__toString()’ magic method is not available and the class object is used by ‘print’ or ‘echo’, an error message will be displayed.

The below-mentioned code snippet utilizes the ‘__toString()’ magic method, which is invoked automatically by PHP when the object of the ‘toStringMagicMethod’ is passed to ‘echo’ and therefore treated as a string.

__unset()

PHP invokes the ‘__unset()’ magic method when an ‘unset()’ function is used on an inaccessible private, protected, or non-existent object property.

The code snippet below invokes the ‘unset()’ function on the ‘Test’ property, triggering the ‘__unset()’ magic method, which restores the ‘Test’ property’s original state.

__wakeup()

When the ‘unserialize()’ function is invoked on the object, the ‘__wakeup()’ magic method is intended to re-establish any connections that may have been lost during serialization and perform other reinitialization tasks.

The code snippet below utilizes the ‘connectionmethod()’ function, which is used by the ‘__wakeup()’ magic method, to re-establish the connection when the ‘unserialize()’ function is implemented to the ‘wakeupMagicMethod’ class object.

PHP Object Injection Samples

As we understand what PHP Object Injection is and how insecure deserialization and magic methods in PHP are the underlying cause, let us look at some vulnerable PHP Object Injection samples to get an understanding of what PHP Object Injection can lead to.

Authentication Bypass via Object Reference

The following example demonstrates the PHP class ‘POI2IDOR’ with an exploitable ‘unserialize()’ method. In line 9 of the code snippet below, we observe that the data from the ‘inputparameter’ is deserialized in an unsecured way, which is then given to an ‘if’ conditional statement on line 12 that is subject to Type Juggling. When a specifically designed serialized object is supplied in this example, an attacker might be able to obtain an object reference for accomplishing an authentication bypass, for example, by accessing the following URL: ‘http://vulnerable.target.com/test.php?inputparameter=a:2:{s:15:”adminsecretcode”;N;s:4:”misc”;R:2;}’

Vulnerable Code Snippet:

Path Traversal

The below-mentioned example demonstrates a PHP class ‘POI2PT’ with an exploitable ‘__destruct()’ magic method spanning from line 5 to line 10. When a specifically constructed serialized object is supplied in this example, an attacker might be able to perform Path Traversal, by browsing the following URL: ‘http://vulnerable.target.com/test.php?inputparameter=O:6:”POI2PT”:1:{s:12:”existingfile”;s:22:”../../../../etcpasswd”;} ‘

Vulnerable Code Snippet:

Authentication Bypass via Type juggling

The following example demonstrates an exploitable unserialize method. When a specifically constructed serialized object is supplied using a POST request, an attacker will be able to perform an authentication bypass with the help of type juggling as the comparison statement on line 5 appears to be loosely comparing the data. The HTTP request for exploiting this misconfiguration will be similar to the one mentioned below:

Vulnerable Code Snippet:

POST Request:

Arbitrary Code Injection

As seen in the following example, the PHP class ‘POI2CI’ includes an exploitable ‘__destruct()’ magic method from line 7 to line 9. When a precisely configured serialized object is supplied in this code snippet, the application will seek references to the ‘receivedinput’ object, and once there are no more references, the ‘__destruct()’ magic method will be called, resulting in the execution of the injected command.

The attacker will be able to obtain command injection, by accessing the following URL: ‘http://vulnerable.target.com/test.php? inputparameter=O:6:”POI2CI”:1:{s:16:”arbitrarycommand”;s:2:”id”;}’

Vulnerable Code Snippet:

PHPGGC: PHP Generic Gadget Chains

PHPGGC is a deserialization payload library that includes a tool for generating them from the command line or programmatically. This may be used to produce Property Oriented Programming (POP) gadgets from libraries that users have already discovered. While facing unserialize on a website for which you do not have the source code, or simply when attempting to develop an attack, this tool allows you to produce the payload without having to go through the time-consuming procedures of locating and assembling gadgets.

CodeIgniter4, Doctrine, Drupal7, Guzzle, Laravel, Magento, Monolog, Phalcon, Podio, Slim, SwiftMailer, Symfony, WordPress, Yii, and ZendFramework are all supported by PHPGGC. Additionally, PHPGGC requires a PHP version greater than or equivalent to 5.6 for proper functioning.

The attributes associated with a gadget chain generated by the PHPGGC library are described in the table below:

Attribute

Description

Name

Name attribute specifies the framework or library that the gadgets are intended for.

Version

Version attribute specifies the framework or library version for which the gadgets are intended.

Type

Type attribute describes the sort of exploitation the gadget chain would result in, such as Remote Code Execution, Arbitrary File Deletion, Server-Side Request Forgery, and so on.

Vector

Vector attribute describes the PHP magic method that will be used to initiate the chain following the unserialize operation on the specified input.

Information

Information attribute describes any extra detail associated with the gadget chain.

At the time of writing, the PHPGGC library has 94 gadget chains associated with various frameworks and libraries that it could exploit. The list of available gadget chains in PHPGGC can be obtained by executing the below-mentioned command:

Depending on the application technology, we can also use the following command to filter the gadget chain available in the PHPGGC that is most suited for testing:

PHPGGC provides a ‘-i’ flag that can be used to retrieve additional information about the specified gadget chain using the command below:

On a high level, PHP Object Injection Exploitation Using PHPGGC includes the following activities:

  1. Detection of the framework or library in use.

  2. Identification of a possible injection point, such as a parameter, cookie, or Header.

  3. Additional attack preparation, such as a reverse shell or a backdoor, which will be uploaded to the application server upon successful exploitation of the vulnerability.

  4. Custom serialized object creation using PHPGGC

Interesting Real World Scenarios

Over time, security experts worldwide have discovered several instances of PHP Object Injection vulnerability, some of which could be exploited to achieve Remote Code Execution, Authentication Bypass, etc. Some of the most significant cases of the PHP Object Injection vulnerability are described below, which will aid in acquiring a better understanding of this vulnerability and knowing some of the finest publicly known exploits.

Data Tampering through PHP Object Injection

WooCommerce is a WordPress e-commerce plugin. It simplifies the process of developing and administering an online store by providing decent levels of flexibility as well as various important features such as inventory and tax administration, secure payments, and shipping integration.

In this case, the security researcher was testing the order feature in the WooCommerce WordPress plugin and discovered that the PHP native unserialize method allows small ‘o’ as an option and treats it as a ‘StdClass’ object.

Vulnerable Code Snippet:

Using the obtained knowledge about the small ‘o’ as an option, the security researcher constructed a bypass that allowed them to tamper with any ‘order’ object. In addition, when paired with capital ‘S’, existing firewall rules failed, causing the firewall to be bypassed.

Proof of Concept Code:

Type Juggling Chained with PHP Object Injection for SQL Injection

ExpressionEngine is a robust and flexible open-source Content Management System. ExpressionEngine has a large community of developers making add-ons that extend system capabilities.

In this scenario, when the security researcher attempted to log in with the username ‘admin,’ the server responded with a cookie containing PHP serialized data. The researcher then downloaded and installed a copy of the application for further analysis. After walking through the code, the researcher discovered that a few checks were done before the cookie was parsed and subsequently unserialized. Further investigation revealed that a cookie integrity validation mechanism was in place, ensuring that the cookie was not tampered with. Since the application was written in PHP, a loosely typed language, using the loose comparison operator resulted in the comparison evaluating as true because ‘0ex’ will always be zero when cast to integers, a process known as Type Juggling.

The researcher then created the following proof of concept, which brute forces the ‘md5($payload.$this->sess_crypt_key)’ until an MD5 hash sum of the updated ‘$payload’ and ‘$this->sess_crypt_key’ that starts with ‘0e’ and ends in all digits was discovered:

Proof of Concept Code:

Output:

When the researcher compared the MD5 hash sum to any ‘$signature’ value, they discovered that the original ‘$payload’ was successfully updated, confirming the existence of Type Juggling and PHP Object Injection.

The researcher discovered a method that appears to be checking the database to see if the given ‘$username’ is locked out pre-authentication. Since the researcher got access to the value of ‘$username’ and he was able to inject a SQL query there, it resulted in SQL injection.

Following an additional inspection of the source code and multiple hit-and-try efforts, the researcher constructed the Proof of concept code shown below to insert the ‘sleep(5)’ command into the database:

Proof of Concept Code:

 

Output:

The researcher then submitted the below-mentioned payload through the ‘exp_flash’ cookie generated by the preceding proof of concept code and observed that the response was shown after 5 seconds, confirming the vulnerability:

Object Injection to Pre-Auth Remote Code Execution in Moodle

Moodle is a learning platform that aims to give educators, administrators, and learners a unified, secure, and integrated system for creating personalized learning environments.

In this scenario, the researcher discovered that Moodle’s Shibboleth authentication module was vulnerable to Remote Code Execution through a PHP Object Injection vulnerability. The vulnerability was discovered in the logout handler in the ‘logout_file_session’ function spanning from line 17 to line 22, since the file handler traverses all session files. Each session file holds a single serialized session object. The handler handles this by reading each file and deserializing its data using the ‘unserializesession’ function. When a matching session ID in a session object is identified, the relevant file is unlinked, resulting in a ‘logged-out’ session, as shown in the below-mentioned code snippet:

The code fails to properly parse the serialized value of a session key if it contains an unexpected Pipe ‘|’ character, introducing the risk of the parser misinterpreting the beginning and end of a serialized value within the session object, leading to the deserialization of potentially user-controlled input.

The researcher sent the payload ‘xxx|O:8:”Evil”:0:{}’ which was saved in the ‘$_SESSION’ object of an unauthenticated guest user, which the session handler then serialized and stored on the filesystem in the form ‘USER|O:8:”stdClass”:…:{…} SESSION|O:8:”stdClass”:…:{… s:…:”filterfirstname”;s:19:”xxx|O:8:”Evil”:0:{}”;…}’, confirming the PHP Object Injection vulnerability which was then exploited for obtaining Remote Code Execution.

Practice Labs

Being a team of Advanced Penetration Testers and Security Researchers, we strongly believe in a hands-on approach to cyber security and therefore we have published a compilation of four PHP Objection labs on our platform Vulnmachines for the readers to learn PHP Object Injection by practicing in labs that mimic real-life circumstances. 

The practice labs relevant to PHP Object Injection are listed below and can be accessed by navigating to Vulnmachines:

  • Demystifying PHP Object Injection (Why So Serialize)

Mitigations and Best Practices

  • Deserializing user input should be avoided unless necessary.

  • When deserializing data from untrusted sources, avoid using the ‘unserialize()’ method with user-supplied input and instead use the ‘json_decode()’ and ‘json_encode()’ methods.

  • Implement a verification mechanism for serialized data before deserializing it from any untrusted source, such as user input.

References

Uber has been HACKED By a Teen

Uber says it’s investigating a “cybersecurity incident” and alerted the law-enforcement authorities. The alleged hacker, who claims to be an 18-year-old, says they have administrator access to company tools including Amazon Web Services and Google Cloud Platform. The New York Times reports that the ride-hailing business has taken multiple internal systems, including Slack, offline while it investigates the breach. The alleged breach had reportedly forced Uber to take several internal communications and engineering systems offline.

The hacker’s screenshots appear to indicate full access to many critical Uber IT systems, including the company’s security software and Windows domain. The hacker also gained access to the company’s Amazon Web Services console, VMware ESXi virtual machines, Google Workspace email admin dashboard, and Slack server, to which the hacker posted messages.

How this attack worked initially (According to news and Twitter):

  • The attack initiated with a social engineering technique that compromised an employee’s VPN credentials.
  • The gained credentials allowed the attacker to scan the intranet and gain VPN access to Uber’s internal network.
  • The internal network held PowerShell scripts with the login information for a Thycotic “admin” user (PAM).With this, the “extraction of secrets” for all services began (DUO, AWS, GSuite,etc.)

Investigation:

Uber has obviously taken notice of this, and they are currently looking into the issue.

https://www.nytimes.com/2022/09/15/technology/uber-hacking-breach.html

How the attacker bypassed the MFA?:

For their employees, Uber appears to use push notification MFA (Duo). How might an attacker circumvent MFA?
Push, touch, and mobile MFA are frequently erroneously thought to protect users against social engineering. MiTM attacks typically continue to be a threat even when MFA can stop an attacker who merely has access to the victim’s credentials.

With the use of tools like Evilginx, an attacker can set up a counterfeit domain that delivers the legitimate Uber login page to the victim (an Uber employee). The question is how the attacker will persuade the victim to visit his phishing website.

It was actually quite simple, the attacker continually pushed and denied the victim’s MFA requests to overwhelm him, and then he pretended to be an “IT” team over WhatsApp to convince the victim to visit his created phishing page and enter credentials on the totally fake Uber login page. The attacker obtains the logs and sends the response to his own local server.

It appears that PowerShell scripts were located on a private network share. Using the admin user’s username and password from one of the Powershell scripts, the user was able to extract the secrets for all the services, including AWS, Gsuite, and others.

Once the attacker compromised an employee, they appear to pivot the internal network using the victim’s already-existing VPN connection.:

In this incident, it appears that the attacker discovered an internal network share that held scripts with privileged access, granting them the authority to control. Hackers allege that they have infiltrated the Duo, OneLogin, AWS, and GSuite infrastructures of Uber.

By tricking the victims into accepting a prompt that allowed the attacker to register their own device for MFA, the attacker claims they were able to secure persistent MFA access to their compromised accounts. Below are the screenshots from the Hacker:


Screenshot of Access to the database of administrator login data amassed by the threat actor behind the Uber attack. It is evident that he gained access to Uber’s internal network through a social engineering scam because those passwords seem to be secure.

The attacker shared several screenshots of Uber’s internal environment, including their Drive VCenter, sales metrics, Slack and even their EDR portal. Right now, the compromised HACKERONE account is the greatest concern for UBER. The attacker has access to all the vulnerabilities that were reported to UBER by different security researchers and given that the average SLA to apply a patch for a vulnerability ranges from one month to even six months, this is a serious concern.





As a preventative measure against these cyberattacks:

  • The Firm should regularly provide the security awareness training to its employees on phishing attacks and campaigns.
  • It is not recommended to utilise a single set of credentials to access all services. Switch to certificate-based authentication.
  • Restricting internal service access to a minimum and only granting the user the necessary access.
  • Shared drives and other internal drives need to be frequently examined for private information (PII) and other sensitive data. The vault should be used to store sensitive data.

Conclusion:

  • In this day and age, all businesses, no matter how big or little, are vulnerable to cyberattacks. As of September 18,2022,Uber Technologies’ net value was $63.02 billion. They were still the target of a cyberattack.
  • Never undervalue the impact that cyberattacks can have on the reputation of your company and brand.

References:

  1. https://mobile.twitter.com/BillDemirkapi/status/1570602097640607744
  2. Uber Says It’s Investigating a Potential Breach of Its Computer Systems (thehackernews.com)
  3. https://www.uber.com/newsroom/security-update/

Exploiting IDORs – A compilation

Hello readers, in this blog, our Senior Consultant Vanshal Gaur, is going to explain access control and vulnerabilities arising from insecure access control such as Insecure Direct Object References (IDOR) with some interesting obscure examples.

So, what is an IDOR?

IDOR is a type of access control vulnerability that arises when an application uses user-supplied input to access objects directly. It usually takes the form of an unique identifier and may appear in a URL.

In order to have a better understanding of IDOR, let us first understand what exactly is “Access control” and what are its types.

Access Control

Access control allows applications (or admins) to define user roles as per capabilities that a user should have. Some users have more privileges than other users. In the context of web applications, access control is dependent on authentication and session management:

  •  Authentication identifies the user and confirms that they are who they say they are.
  •  Session management identifies which subsequent HTTP requests can be made by that same user.
  • Access control determines whether the user is allowed to carry out the action that they are attempting to perform.


Access control can be better explained in the following types:

  1. Vertical access control – Vertical access control aims to control functionalities that should not be available or accessed by low privilege users. For example, a Moderator role will possibly have more access rights to contents in a system than a regular user. On the other hand, the admin role has the highest privilege in a system compared to other roles.
  2. Horizontal access control – Horizontal access control aims to control the restrictions to access resources by users who have the same capability level. For example, in a web application there can be many users having their own private information such as phone number, email and it could be any confidential information that should not be displayed to other users even if they have the same role type.
  3. Context-dependent access control: Context-dependent access control aims to control the restrictions specified for the user itself. For example, a user buys a product from an e-commerce application and after the product is shipped, the user wants to change the shipping address but it shouldn’t be allowed, security implementation should be done properly.

Now that we know “Access Control”, we can shift our focus back on IDOR. In IDOR, attackers can bypass authorization and access resources, for example, database records or files in the system directly. It does so by allowing attackers to directly modify the value of a parameter used to directly point to an object. This is caused by the fact that the application takes user-supplied input and uses it to retrieve an object without performing sufficient authorization checks.

The vulnerability is of such significant concern that for many years it was listed as one of the Open Web Application Security Project’s (OWASP) Top 10 vulnerabilities.

Impacts of IDOR

The impact of an IDOR vulnerability depends on the application’s functionality. Therefore, a clear list can not be generated. It depends on various factors. Generally speaking, an IDOR vulnerability can introduce a risk for CIA (confidentiality, integrity, availability) of data.

The following are some examples of IDOR impact:

  • Alteration of Data.
    • Privilege levels do not distinguish users who can only view data and users permitted to modify data.
  •   Exposure of Confidential Information.
    •  Compromising admin-level accounts often results in access to the user’s confidential data.
  •   Loss of Accountability
    •  Attackers maliciously execute actions as other users.
    •  Attackers maliciously execute higher level actions.
  •   Account Takeover.
  •   Authentication Bypass.

Testing IDOR

In order to test IDOR, the tester first needs to map out all locations in the application where user input is used to reference objects directly. For example, locations where user input is used to access a file, a database row, application pages, etc. Next, the tester should modify the value of the parameter used to reference objects and assess whether it is possible to retrieve objects belonging to other users or otherwise bypass authorization.

Below mentioned are some Burp Suite plugins, which can make your life easier and help you automate the process of finding IDORs and Access Control issues:

  •  Autorize
  •  AuthZ
  •  AuthMatrix


Reference: https://www.youtube.com/watch?v=3K1-a7dnA60 (A great tutorial by @regala_), A must-watch!

An Easy IDOR Example:

Suppose there are two users: UserA and UserB.

UserA can access his bank account details by visiting the below URL:

example.com/bankdetails.aspx?id=UserA


And UserB can access his bank account details by visiting:

example.com/bankdetails.aspx?id=UserB


Essentially, both these users should not be able to access the bank details of any other user.

If you observe the URLs of both the users, the object that allows the bank application to differentiate between both the users is the “id” parameter.

Now if an IDOR vulnerability had to exist in this case, a malicious user (suppose UserA) will be able to modify the insecure object “id”. By changing the “id” to “UserC”, the malicious user (UserA) will be able to access the bank details for UserC.

Logical Thinking For Encoded and Hashed IDs

During the reconnaissance of the application sometimes we may come across some sort of encoded ID, it might be possible to decode the encoded ID using common encoding schemes and change the inside value to exploit IDOR.

If the application is using a randomised/hashed ID, check if the ID value is predictable. Sometimes applications use algorithms/methods that produce insufficient entropy, and as such, the IDs can actually be predicted after a thorough analysis. In this case, try creating multiple accounts to analyse how these IDs are created. You might be able to find a pattern that will allow you to predict IDs belonging to other users.

Further, it might also be possible to leak hashed or random IDs via another API endpoint, on other public pages in the application (profile page of other users, etc), or in a URL.

For example, consider the below API endpoint which allows users to retrieve detailed direct messages through a hashed conversation ID.

GET /api_v1/messages?conversation_id=SOME_RANDOM_ID


This may seem completely okay at first since the conversation_id is a long, random, alphanumeric sequence. But, it was discovered that you could actually find a list of conversations for each user just by using their user ID! Note that user_id was publicly available on each user’s profile page.

GET /api_v1/messages?user_id=ANOTHER_USERS_ID


The above request would return a list of conversation_ids belonging to that given user. Therefore, it’s possible to read any user’s messages by first obtaining their user_id on their profile page, then retrieving a list of conversation_ids belonging to that user, and finally loading the messages via the API endpoint /api_v1/messages!

In case the object reference IDs seem unpredictable, see if there is anything you can do to manipulate the creation or linking process of these object IDs. If no IDs are used in the application-generated requests, try adding it to the request. Try adding parameters like id, user_id, message_id or other object reference parameters and see if it makes a difference to the application’s behaviour.

Let’s take one example here, if the following request displays all your direct messages:

GET /api_v1/messages


Try adding “user_id” and observe whether the application behaves in a different way. Would it display another user’s messages?

GET /api_v1/messages?user_id=ANOTHER_USERS_ID


Let’s advance towards understanding Blind and HTTP Parameter Pollution (HPP) IDORs, and how to look for such vulnerabilities.

Blind IDOR

Blind IDOR attacks are identical to Blind XSS or SQLi attacks. In that, the specific IDOR request is undetectable because the following response does not reveal the vulnerability.

For example, if you change the object’s information in the application, you will receive an email that includes that information, now if you try to change the same information for another user, and you can’t access anything in HTTP response but you can access the same information of object with an email, that would be called a “Blind IDOR”.

HPP IDOR

In some cases, you can test the HTTP Parameter Pollution vulnerability for IDOR by adding the same parameter twice in your request. ie: UserA could make the below URL calls in order to get access to UserB account details.:

example.com/?id=UserB&id=UserA
example.com/?id=UserA&id=UserB
example.com/?id[]=UserA&id[]=UserB

IDOR Prevention

To prevent vulnerabilities arising out of IDOR, applications should implement strict access control on every functionality, and check if a user is authorised to access and/or manipulate the requested object.

Never depend on untrusted data:

  •  Never trust request data for access control decisions.
  •  Never make access control decisions in JavaScript.
  •  Never depend on the order of values sent from the client.
  •  Never make authorization decisions based solely on:
    •  Hidden fields
    •   Cookie values
    •   Form parameters
    •  URL parameters


More information about IDOR prevention can be found in OWASP’s IDOR prevention cheat sheet

Interesting Obscure IDOR Instances

There are many occurrences of access control vulnerabilities where user-controlled parameter values are used to access resources or functions directly.

We have listed some interesting IDOR vulnerabilities, found over time by security researchers all over the world.

1. Stealing Your Private YouTube Videos, One Frame at a Time.

A security researcher found an IDOR vulnerability, where it was possible to access any YouTube channel’s private video by getting one video frame at a time.

David, who originally discovered this vulnerability mentioned that he tried to access other user’s private videos by changing the target video’s ID from YouTube requests but could not be successful, so he started to think differently. He started poking around with Google AdSense (a product that advertisers use to create ads across all Google services, including YouTube). The ads you get before YouTube videos are set up by advertisers on the Google Ads platform.

The researcher created a Google Ads account and created a new advertisement, which would play a video of his as a skippable ad for YouTube users.

While exploring AdSense features, he found a page called “Videos”, where it was possible to see the list of videos used by advertisements.

Clicking on a video opened up an Analytics section for that specific video, which had an interesting feature called “Moments”. It allowed advertisers to “mark” specific moments of the video.

Exploitation:

Whenever we “marked a moment” in the “Moments” section, a POST request to “/GetThumbnails” was sent, as shown below:

POST /aw_video/_/rpc/VideoMomentService/GetThumbnails HTTP/1.1
Host: ads.google.com
User-Agent: Internet-Explorer-6
Cookie: [redacted]

__ar={“1″:”kCTeqs1F4ME“,”2″:”12240“,”3″:”387719230”}


A Base64 encoded image, that is the thumbnail displayed by Ads was returned in the response to the above request. This request contained a “video-id”( in parameter _ar as “1”), by changing this ID to a private video’s ID, it was possible to fetch the thumbnail of that video.

As the post request took time in milliseconds (in parameter _ar as “2”), we could specify the time for which we wanted to fetch the thumbnail.

David wrote a python script to automate this whole process, which would get all the thumbnails of videos frame by frame, and generate a moving video.

Key takeaway: Even though you think you hit the dead-end, exploring the functionalities of the application and thinking deep is the key.

2. IDOR Resulting in Image Deletion in Mozilla Support Page.

Here, the security researcher found IDOR by performing a code review of Kitsune (A Django-based application, created by Mozilla).

Django is a Python-based web framework, free and open-source, that follows the model–template–views architectural pattern.

While going through all the URL endpoints, the researcher found this interesting endpoint:

Going through the “views.reply” function, the researcher discovered that if you provide a “delete_images” Post parameter, it will delete any image with the “id” you provide in the “delete_image” parameter, without any checks, if the user deleting the image is the owner of the image.

Now that we know the vulnerable piece of code, we can exploit the vulnerability as follows:

  1. Have two accounts, suppose User A and User B.
  2. As User A, make a new question, in the question, make a new reply and add an image in the reply.
  3. Take note of the “id” of the uploaded image.
  4. As User B, reply to the question, then intercept the request.
  5. In the body of the request, add: &delete_images=true&delete_image=60680
  6. Replace “60680” with the id of the uploaded image of User A.
  7. You will see that the image will be deleted directly in the Content Delivery Network (CDN).

In this instance, a security researcher exploited the vulnerability by adding a new parameter to the existing request. We can also use this technique to bruteforce the parameter names or guess it according to other application parameters. Such vulnerabilities can also be termed as Mass Assignment vulnerability.

Key Takeaway: Exploiting these types of vulnerabilities is difficult in black-box type of assessments, as guessing the exact parameter is hardly possible. Hence, the code reviews are as important as other methods.

3. 49500$ Bounty From Facebook, Critical Bug in Instagram

Recently, a security researcher named Neeraj Sharma, found a vulnerability in Instagram where the attacker could change the reel thumbnail of any Instagram user by knowing “clips_media_id” (Media ID of reel) of that user.

While understanding the API structure and the request flow of Instagram application, the researcher came to the point where users can edit their reels cover photo (thumbnail). For testing, he changed his reel thumbnail and intercepted all the HTTP requests using Burp and after forwarding some requests he observed the following HTTP request:

POST /api/v1/media/configure_to_clips_cover_image/ HTTP/2
Host: i.instagram.com
X-Ig-App-Locale: en_US

X-Ig-App-Id: 567067343352427
Priority: u=3
User-Agent: Instagram 226.0.0.16.117 Android (24/7.0; 320dpi; 720×1184; unknown/Android; vbox86p; vbox86; en_US; 356747126)
Accept-Language: en-US
Authorization: Bearer IGT:2:<BASE64_Encoded_Token>
X-Mid: YnJa7AABAAFBAWyzna1J4pu-Mf2e
Ig-U-Ig-Direct-Region-Hint: ASH,446xxxxxxx,168xxxxxxx:01f7b979c4246d13c5918e1c108d47035dcd6e26eac03b70a2019c4b49c9361859eb1339

Ig-Intended-User-Id: 446xxxxxxxx
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 100
Accept-Encoding: gzip, deflate
X-Fb-Http-Engine: Liger
X-Fb-Client-Ip: True
X-Fb-Server-Cluster: True

clips_media_id=2763122193610xxxxxx&_uuid=8893c680–7663–48a4–95dc-dd91b9xxxxxx&upload_id=326264xxxxxx


Here the important parameters are “clips_media_id” and “upload_id”.

Clip ID is the ID of a reel video and upload_id is the ID of an image that the user wants as a new reel thumbnail. Due to the IDOR vulnerability, which was present at the vulnerable endpoint, it was possible to change the “clips_media_id” to the victim’s reel ID and change the thumbnail of their video.

Though this vulnerability seems less severe, the impact is high. Within the CIA triad, Integrity was violated and the Accessibility of the victim was totally disregarded by the actions of the attacker. As the malicious actor was able to forge thumbnails in any profile without any authorization or victim interaction, the impact was loud, wide and around heterogeneous masses of Instagram users.

Key Takeaway: It’s always possible that simple bugs like these are lying around the web, it is good to be mindful of the basics of every application, no matter even if the application has been tested 1000s of times.

4. Google Cloud Dialogflow IDOR

Dialogflow is a natural language understanding platform that makes it easy to design and integrate a conversational user interface into your mobile application, web application, device, and more. Using Dialogflow, you can provide new and engaging ways for users to interact with your product.

The security researcher in this case was testing Dialogflow and observed an option to delete the phone gateway, as shown in the below figure:

As mentioned in the above request for “delete phone gateway”, the researcher tried to brute-force the random string (which is an encoded phone number) but it didn’t work.

Moving on to find the other encoded numbers to see if it was possible to delete another user’s phone gateway using the same request, the researcher found another feature called “CX Phone Number”, where it was possible to create new numbers, and inside that was an option to select Area code.

On intercepting the Area code request, some random strings (Phone numbers) were found in response.

Replacing the random strings (Phone Numbers) in the “delete phone gateway” request, the researcher was successfully able to delete other users’ phone numbers.

Key Takeaway: If you’re lacking some sort of information in order to successfully exploit a vulnerability, it’s worth trying to find that information on other features of the application.

5. IDOR with Mass Assignment Vulnerability

The application had an account update functionality where a user could update profile information, such as name and profile picture. There was no functionality to update the other details such as Email Address, Password and Role. Here, an attacker could chain the IDOR with Mass Assignment vulnerability to change other user details and ultimately leverage it to complete the account takeover of the victim.

The researcher intercepted the profile update request and observed the below request/response. By looking at the userID in the URL, we think of an IDOR, but the application was validating the request using the slug parameter.

Request:

PUT /api/users/15 HTTP/1.1
Host: target.com
Cookies: session=xxxxxxxx

{
    “name”:”Test User”,
    “image”:”IMG URL”,
    “slug”:”dXNlcjE1″
}


Response:

HTTP/1.1 200 OK
Set-Cookie: session=xxxxxxxx; Secure; HttpOnly; SameSite=None
Connection: close
Content-Length: 0


{
    “userid”:”15″,
    “name”:”Test User”,
    “Email”:”test@example.com”,
    “Role”: “User”,
    “image”: “https://target.com/media/images/avtar.png”
…DATA…
}


Further, it was observed that the “slug” parameter value was the base64 encoded string of “userID”, i.e., user15, as reflected in the request URL.

So, the researcher added the “email” parameter in the request and replaced the “ID” value with the victim’s userID (user18 – dXNlcjE4) along with the encoded “slug” value. As a result, the researcher was able to perform an account takeover by chaining IDOR with Mass Assignment vulnerability.

Request:

PUT /api/users/18 HTTP/1.1
Host: target.com
Cookies: session=xxxxxxxx

{
    “name”:”Test User”,
    “image”:”https://target.com/media/images/avtar.png”,
    “Email”:”attackercontrolledaddress@example.com”,
    “slug”:”dXNlcjE4″
}


Response:

HTTP/1.1 200 OK
Set-Cookie: session=xxxxxxxx; Secure; HttpOnly; SameSite=None
Connection: close
Content-Length: 0


{
    “userid”:”18″,
    “name”:”Test User”,
    “Email”:”attackercontrolledaddress@example.com”,
    “Role”: “User”
}


With such an issue, it is possible to further take advantage of forgot password functionality after changing the email of the victim and completely take over the account.

Key Takeaway: Eventhough it might seem like the application does not have certain functionality, it’s always worth adding additional parameters in the request and observe the corresponding response.

References:

An Empirical Analysis Of Apache Server

In this blog post, Udit Bhadauria discussed about the latest Apache Server vulnerability. This blog post describes the vulnerability details, minimum requirements, affected versions, vulnerability detection, chaining vulnerability with Remote Code Execution and recommendation. Let’s dive into each sections:

What Is Path Traversal Vulnerability?

Path Traversal is a very common security vulnerability that arises due to improper normalization and improper data validation of pathname. Path Traversal is a low complexity vulnerability that results in unauthenticated access to a restricted directory or a file. Path Traversal vulnerability is also known as:

  1. Directory Traversal vulnerability
  2. Directory Climbing vulnerability
  3. Backtracking vulnerability
  4. Dot-Dot-Slash vulnerability

In this type of attack, the attacker tries to traverse the system files using the sequence of payload “../” in the input. Sometimes, Path Traversal vulnerability can also be chained with other security vulnerabilities for creating more impact including but not limited to Local File Inclusion (LFI) and in certain scenario this can also lead to Remote Code Execution (RCE). 

Due to the presence of Web Application Firewall (WAF), this type of attack needs some sort of encoding for successful execution. The most widely used and preferred encoding for this type of attack is URL encoding. However, different types of encoding schemes can be used depending upon how the application handles the user input and how the firewall is configured.

CVE-2021-41773 And What Led To CVE-2021-42013?

CVE-2021-41773 and CVE-2021-42013 have been identified in the Apache versions 2.4.49 and 2.4.50 respectively in October 2021. These Path Traversal vulnerabilities exist due to improper handling and misconfiguration within the path normalization in Apache 2.4.49 and Apache 2.4.50.

The researcher discovered that Apache 2.4.49 was vulnerable to Path Traversal using the “/.%2e/” bypass, as a result of which the Apache software foundation fixed it and released the new version 2.4.50. However, the fix was incomplete and Apache 2.4.50 was also vulnerable to Path Traversal using the payload “/%%32%65%%32%65/” which was simply a double URL encoding of key characters that were used in the previous payload. This infers that the vulnerability can still be reproduced using this new bypass by providing double URL encoded payload. This misconfiguration results in accessing internal system-critical files without authentication.

The default Apache server settings are not protected by the “require all denied” configuration, therefore, resulting in unauthorized access to all system documents associated with the vulnerable server.

The most commonly used endpoints for testing the misconfigurations are:

If the response code for any of the above endpoints is 403 then the target application can be vulnerable, but it should be kept in mind that 403 does not mean that the application is certainly vulnerable as WAF can also produce a 403 response code.

On the other hand, if the response code for any of the above endpoints is 400 or 5XX then the application will be most likely not vulnerable to this misconfiguration.

Another important thing to be kept in mind while testing for this vulnerability is that the vulnerability might exist even if the application does not have the “/cgi-bin/” in its directory structure as the vulnerability can be reproduced using other available aliases (e.g. /icons/).

Minimum Requirements For The Vulnerability To Exist

The application must fulfil the following requirements for Path Traversal vulnerability:

CVE-2021-41773:

  1. The application must be running on Apache 2.4.49.
  2. The configuration file “apache.conf” should contain “require all granted” instead of “require all denied”. [By default its “require all granted” in Apache 2.4.49].

CVE-2021-42013:

  1. The application must be running on Apache 2.4.50.
  2. The configuration file “apache.conf” should contain “require all granted” instead of “require all denied”. [By default its “require all denied” in Apache 2.4.50].

Who Are All Affected?

Apache has been one of the first choices that many organizations think about for hosting their applications on the internet. According to the Netcraft’s Web Server Survey, nearly 25% of the developers prefer Apache for hosting their work over the internet. This enormous presence of Apache servers over the internet makes Apache one of the prime targets for security researchers and malicious actors.

As discussed in the earlier section, all these instances are not vulnerable as there are some minimum requirements. However, at present, the number of instances running Apache 2.4.49 are enormous and thus are being scanned at a very large scale by security researchers and bug hunters.

According to Censys.io at the time of writing this blog post, there are more than 18,000 active instances of Apache 2.4.49 that are a possible target for CVE-2021-41773 and more than 9,000 active instances of Apache 2.4.50 that can be tested for CVE-2021-42013: 

 

Performing a similar search using the shodan.io vulnerability search engine yields more than 69,000 potential targets for CVE-2021-41773 and 13,500 possible targets for CVE-2021-42013 at the time of writing this post:

Shodan – Apache 2.4.49

Shodan – Apache 2.4.50

Vulnerability Detection And Wide Scope Scanning

There are several ways for detection and exploitation of this vulnerability some of which are as follows:

A Nmap script can be found at GitHub that can be used for detection of this vulnerability using the following Nmap command:

$ nmap –script http-vuln-cve2021-41773 -p  

A specially crafted curl command can also be used for checking whether a single target application is vulnerable to CVE-2021-41773 and CVE-2021-42013:

$ curl –silent –path-as-is –insecure “https://vulnerable.target/cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/etcpasswd”

$ curl –silent –path-as-is –insecure “https://vulnerable.target/cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32% 65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/etcpasswd”

Nuclei vulnerability scanning templates are also available at GitHub Nuclei Template – CVE-2021-41773 and GitHub Nuclei Template – CVE-2021-42013 for identification and exploitation of CVE-2021-41773 and CVE-2021-42013 respectively. The nuclei templates can be used for scanning single target and mass scanning potential targets:

OWASP Nettacker is also effective in the identification of CVE-2021-41773 and CVE-2021-42013. It can be used for scanning the targets from a list, entire subnets, domains along with subdomains and IP ranges by running the following commands mentioned in the below screenshot:

Vulnerability Detection using “nettacker.py” Script

Chaining Path Traversal Vulnerability With Remote Code Execution

Misconfiguration of “apache2.conf” file can also lead to Remote Code Execution. If the configuration file “etcapache2apache2.conf” has the configuration “Require all granted” instead of “Require all denied” and CGI scripts are also enabled for these aliased pathes, it could allow an attacker to exploit Path Traversal vulnerability and perform Remote Code Execution. The code snippets for vulnerable and safe configurations are mentioned below:

Vulnerable Configuration:

Safe Configuration:

This can be achieved using the following command:

$ curl -s –path-as-is -d ‘echo Content-Type: text/plain; echo; id’ “http://[IP]:[Port]/cgi-bin/.%2e/%2e%2e/%2e%2e/bin/sh”

Lab Setup

For setting up the lab and practical demonstration, we will be using a Debian-based container image that is available on GitHub. This image can be used for testing and chaining the vulnerability from Path Traversal to Remote Code Execution.

Execute the following commands using any *.nix based system:

$ git clone https://github.com/blasty/CVE-2021-41773

$ docker-compose build && docker-compose up || docker-compose-up


Setting Up with Docker

Please note down the IP address and use that to perform Path Traversal and Remote Code Execution vulnerabilities.

Performing The Path Traversal Vulnerability:

$ curl -s –path-as-is “http://[IP]:[Port]/icons/.%2e/%2e%2e/%2e%2e/%2e%2e/etcpasswd”

Exploiting File Path Traversal Vulnerability

 

Escalating The Path Traversal Vulnerability To Remote Code Execution:

For escalating the vulnerability to Remote Code execution use the following curl command:

$ curl -s –path-as-is -d ‘echo Content-Type: text/plain; echo; id’ “http://[IP]:[Port]/cgi-bin/.%2e/%2e%2e/%2e%2e/bin/sh”

Exploiting Remote Code Execution Vulnerability

As highlighted in aforementioned screenshot, Remote Code Execution was not allowed on “/icons/” directory, it is required to use “/cgi-bin/”.

Recommendations And Best Practices

At the time of writing, this post one can follow the following techniques for safeguarding oneself from this vulnerability:

  1. Update to the latest Apache version.
  2. Update the configuration file “apache2.conf” from “Require all granted” to “Require all denied” for preventing access to the files outside the expected application base directory.
  3. Since a large group of individuals are using automated scanners, a strong WAF implementation is required as an additional layer of security.

References

  1. Path Traversal Vulnerability – OWASP
  2. Apache 2.4.49 – CVE-2021-41773
  3. Apache 2.4.50 – CVE-2021-42013
  4. Apache HTTP Server 2.4 vulnerabilities
  5. October 2021 Web Server Survey – Netcraft
  6. Censys – Apache 2.4.49
  7. Censys – Apache 2.5.50
  8. Shodan – Apache 2.4.49
  9. Shodan – Apache 2.4.50
  10. GitHub – RootUp – Nmap Script
  11. GitHub – blasty – CVE-2021-41773 Playground
  12. GitHub – OWASP – Nettacker Python Script
  13. GitHub – projectdiscovery – Nuclei Template

Anatomy Of A File Upload Attack

Anatomy Of A File Upload Attack

TL;DR

  1. File upload allows you to upload a ZIP file and extract its contents online.
  2. Upload a ZIP file with a malicious symlink and extract arbitrary files from the server.
  3. Pr0fit.

Recently our team discovered a vulnerability in one of the client’s web applications which allowed us to read local files from the application’s server. Here, Krishna from our technical team had explained the vulnerability:

Overview Of The Application

The target web application provides Virtual Data Room (VDR) service to the businesses. A virtual data room (VDR), also known as a deal room, is a secure online repository for document storage and distribution. It is typically utilized during the due diligence process preceding a merger or acquisition to review, share, and disclose company documentation.

Vulnerability

During the testing, SecOps assessment team discovered that the application allowed us to upload and preview the uploaded document and convert the uploaded document in PDF within the application itself. The assessment team observed that the application also allowed us to upload multiple documents through archive (ZIP) files, in simple words we can compress multiple documents in a ZIP file and upload the compressed ZIP file to the application. Additionally, the application allowed us to extract the uploaded ZIP files.

We exploited a ZIP Symlink vulnerability which allowed us to read local files from the application server.

What Is Symlink?

A Symlink (also called a symbolic link) is a type of file in Linux that points to another file or a folder on your system. Symlinks are similar to shortcuts in Windows.

What Is ZIP Symlink Vulnerability?

An archive can contain a symbolic link. A symbolic link is a special file that links to another file. By uploading a ZIP containing a symbolic link, and after the ZIP is extracted, you can access the symbolic link to gain access to files that should not be accessible otherwise. To do so, you need to get your symbolic link to point to files outside of the web root, for example “/etcpasswd”.

These types of issues are typically found when a developer allows ZIP files in the upload functionality. When a user uploads the malicious ZIP file in the application then it simply takes the ZIP file and extracts it without any further validations.

Exploitation

The assessment team created a Symlink of the “/etcpasswd” file on their system and compressed the file in the ZIP archive using the following command:

sudo ln -s ../../../../../../../../../../etcpasswd name_of_symlink.txt

sudo zip --symlink zip_file.zip  name_of_symlink.txt

The assessment team uploaded the ZIP file containing Symlink in the application:

After uploading the file, the assessment team extracted the Symlink file, as shown in below snapshot: 

The application allowed the assessment team to preview the content of uploaded documents, on previewing the file the assessment team was able to access the content of server’s “passwd” file: