Hướng dẫn phar php exploit

Deserialization vulnerabilities have been a topic of interest for the research community for more than a decade now. Every year, new attack chains rise, exploiting these vulns in programming languages like Java, C# [via the .NET framework].

At Blackhat US-18, Sam Thomas introduced a new way to exploit these vulnerabilities in PHP.

This new type of attack abuses the fact that using the phar:// stream wrapper to perform read/write operations on PHAR files determines their metadata to be automatically deserialized.

From here, it opens the gate to POP [Property Oriented Programming] attacks, where an attacker modifies the properties of objects to hijack the logic flow of the application, which eventually leads to code execution on the hosting server.

1. Understanding PHAR deserialization vulns to build safer web apps

The scope of this article is to help PHP developers gain a stronger grasp of the most common root causes and implications of this class of attacks, delivered using PHAR [PHP Archive] files. By the end of this walkthrough, you – as a PHP developer – will be able to create more secure web applications.

Explore our view on how PHAR deserialization works and learn:

  • What stream wrappers in PHP are, with focus on the phar://wrapper

  • What the components of a PHAR archive are

  • How the attack is conducted

  • How to exploit a dummy application so you can gain a practical understanding of these theoretical concepts

  • The key mitigation to avoid a PHAR deserialization vulnerability

2. Core concepts to understand PHAR Deserialization

phar:// Stream Wrapper

In PHP, all file operations are handled using streams.

A stream is a resource object which exhibits streamable behavior. That is, it can be read from or written to in a linear way.

PHP developers use wrappers when their application requests specific resources, such as an image or a document.

Examples of stream wrappers include: //, ftp://, file://, php://, phar://.

To better understand stream wrappers, consider these lines:

filegetcontents["//example.com/image.jpeg"]

filegetcontents["file://../images/image.jpeg"]

filegetcontents["phar://./archives/app.phar"]

Using wrappers, you can call the same function [filegetcontents] to fetch an image either from a remote location or from a folder stored on the local disk.

In particular, the phar:// wrapper is used to interact with PHAR files. It allows various read/write operations to be carried out on an archive and it can only work on local files.

If you want to dig deeper, here’s a full list of the phar:// wrapper options.

PHAR archives

Similarly to Java Archive files [JAR], in PHP you can share a library or an entire application as a single file using a PHAR [PHP Archive] file.

A valid PHAR includes four elements:

  1. Stub

  2. Manifest

  3. File Contents

  4. Signature

PHP provides the PHAR class to build these archives.

Here’s how you can build a specific element of the archive using a class method. [Make sure to stick around for a Proof-of-Concept code that creates completely valid PHAR files!]

3. Elements of a PHAR archive

1. The stub is the first part of the archive. It’s a simple PHP program and it can contain any code you want. The only requirement is that the last command issued within the stub is _HALTCOMPILER[]:

    

The method for setting the stub is:

   PHAR: : setStub [string $stub]

2. The manifest is where the metadata resides. It includes information about the archive and each file within it. More importantly, the metadata is stored in a serialized format.

Remember that the key factor in this attack is that, whenever a file operation occurs on a PHAR using the phar:// wrapper, this metadata is automatically deserialized.

For example, filegetcontents ['phar://./archives/app.phar'] will deserialize the metadata of the app.phar archive.

To add metadata to the archive, use:

    PHAR: : setMetadata [mixed $metadata]

3. The file contents are the actual files included in the archive, and they can be of any kind. To add files to the archive, use:

    //adds the file specified by $path to the archive as $name

PHAR: : addFile [string $path$name]

    //adds $contents to the archive as $name

  PHAR: : addFromString [string $namestring $contents]

4. The signature is a hash of the archive’s content. You must have a valid signature if you want to access the archive from PHP. The signature is automatically added when creating a PHAR programmatically.

4. How POP attacks work

If the PHAR archive is attacker-controlled, that constitutes a basis for a POP attack.

Let’s take a look at the basics of this attack technique. [For an in-depth walkthrough, take a look at  Stefan Esser’s original paper.]

An attacker can add an object from any class to the PHAR’s metadata, having any values set for its properties. When the file operation is triggered inside the target application, the deserialization of the PHAR occurs.

If the object defined in the metadata belongs to a class defined in the scope of the current program, that object will be loaded in that program’s context.

In PHP, there’s a class of methods called magic methods that are automatically called if a certain event happens. For the current example, only two magic methods are of interest: __wakeup[] and __destruct[] which are called when an object needs to be unserialized or destroyed.

Let’s focus on the  __destruct[] method, as it’s more likely to be defined in some class of the target application.

So by now you have an object you control, loaded in the scope of the application, and a method you know will be called – either when the object is no longer in scope or when the script ends.

There are cases where the program logic of the destructor is based on the values of some of the object’s properties. Given that you control these properties, you can hijack the logic flow.

Here’s a flow example to help you visualize how an attack looks:

5. Proof of Concept for a PHAR Deserialization vulnerability exploit

Let’s have a look at a basic code example that illustrates the behavior described so far.

Our dummy application will be a web-based text editor.

Any user is allowed to add multiple documents and they have media storage where they add media they can later embed in any document. The documents can be exported in PDF format.

Suppose the class that generates the PDFs is called PDFGenerator.php and it has the following destructor:

This class is later included in the main Editor.php file.

Running a test with a file that doesn’t exist, notice that the behavior is what we expected it to be:

Now let’s build a PHAR archive using the methods we went through. Its metadata will be an object of the PDFGenerator class.

Create a new file called phar_gen.php with the following code:

Chủ Đề