3

I know it's possible to embed phar archives into jpeg images but is it also possible to do so with PNG images? I am testing a php application that securely checks if an image is a valid PNG image however it calls vulnerable filesystem functions like file_exists on said file, so I am curious if this is a potential attack vector - and if this is a potential attacker vector how could I embed the phar archive into the image? Is it strikingly similar to embedding phar archives into jpeg images? Or is there a different technique for doing this?

Gilles 'SO- stop being evil'
  • 50,912
  • 13
  • 120
  • 179
t40_yx
  • 45
  • 3
  • It's not embedding a PHAR in a JPEG that's the problem, it's having a file that's both a valid JPEG and a valid PHAR. It looks doable with PNG too with a bit of effort. – Gilles 'SO- stop being evil' May 23 '21 at 16:41
  • Yea I've been searching for documentation on the subject/method to no avail seems if no one else has any sources detailing how I'll just have to rely on good old trial and error. – t40_yx May 23 '21 at 16:46

1 Answers1

1

You can hide a PHAR inside an image (PNG, JPEG)

You can hide a PHAR file within a PNG image (or a JPEG image) by using a custom data block. You could even declare you own chunk called "phAR" or "phAr", and put a PHAR file into it. I believe this can be readily done with ExifTool. You now have a valid PNG, which actually is a valid PHAR in "custom format" as far as the phar:// stream is involved.

Does this possibility create additional insecurity?

No. The main insecurity must already be there and is neither increased nor decreased by the possibility of supplying a masked PHAR rather than a plain (e.g. ZIP-format) PHAR.

Let us consider these files:

phar.png       - a valid PNG containing a PHAR
phar.phar.png  - the first PHAR, with a PNG extension (so, not a PNG)

The trick that allows the file to be executed is not being "a PHAR inside a PNG". Rather, it is "the caller using the phar:// stream" (or, equivalently, "the caller allowing the attacker to specify any stream at all, including the phar stream".

But if the attacker can specify a file like "phar://phar.png", chances are, overwhelmingly, that he could just use "phar://phar.phar.png", or even "phar://phar.phar", without using the PNG at all.

On the other hand, if the attacker cannot include the magic "phar://" sequence, then they will be unable to exploit the phar vulnerability - be it in PNG, JPEG, PHAR, or MP3 for that matter.

The one use case where "PHAR masking" could be needed is if the vulnerable application checks that the supplied URL or filename ends in PNG, but does not check that it begins with "http(s)://" or is an actual local path. Not only do I feel that this scenario is unlikely, but I submit that it could be more easily exploited by simply renaming any old PHAR so that it has a ".png" extension. This is because the activation of the PHAR stream is not driven by the file or is structure, but by its URL or path.

This is a bit like how the physicist Richard P. Feynman was taught how to mix white and red paint into yellow: you add a bit of white, you add a bit of red, and if necessary add a hefty dollop of bright yellow.

Here, the PNG masking is somewhat like the red paint, and the "phar://" stream is the yellow paint. Yes, you can add white and red -- but you won't get yellow until you mix in the yellow paint. And if you have yellow, you need neither white nor red.

LSerni
  • 22,521
  • 4
  • 51
  • 60
  • I can achieve code execution by embedding phar bytes into a `jpeg` file check: https://pentest-tools.com/blog/exploit-phar-deserialization-vulnerability/ – t40_yx May 23 '21 at 21:10
  • This is not at all the same thing: the file in that page is a PHAR file and is being read as such by an insecure application that believes it is reading a remote JPEG file, when it is not; thus triggering a PHAR-linked code execution. For the exploit you linked to work, you do not need to alter a JPEG file (and the page, indeed, doesn't) - you do not even need a JPEG file to exist at all. Your question, as it stands, is asking something completely different. – LSerni May 23 '21 at 21:43
  • Read this: https://www.nc-lp.com/blog/disguise-phar-packages-as-images – t40_yx May 24 '21 at 09:40
  • You can use a valid `JPEG` header and the execution will work. So my question was essentially can I do the same with `PNG` files? Will `php` deserialize the injected `png` file? because I can replicate the process in `php` using `jpeg`. – t40_yx May 24 '21 at 09:41
  • The literal answer you seem to seek is, "Yes". You can use `exiftool` to have a PNG that is also a PHAR file. That way, you will have obtained both the white and the red paint in Feynman's story ;-) – LSerni May 24 '21 at 12:23
  • 1
    You've answered the question in the title, but not the question that was actually asked. Embedding a PHAR inside an image isn't the problem, the problem is an image-PHAR polyglot. – Gilles 'SO- stop being evil' May 24 '21 at 12:40
  • A PNG with a PHAR chunk *is*, indeed, a PHAR polyglot (sort of): it will be correctly seen as a PNG, and will "answer" to a PHAR stream in the exact same conditions of the links that were asked. This does not extend to exploiting a simple local file access or `file_exists`, but as far as I can see, neither did the other cited exploits. – LSerni May 24 '21 at 12:59
  • LSemi I've managed to pull it off it is possible, I've managed to craft a `PNG` file that will deserialize data. I'll post the POC soon. – t40_yx May 24 '21 at 13:11
  • 1
    And yes when `file_exists` or any file system function is called, like `jpeg` you can do exactly the same by just prepending `PNG` header magic bytes to the file that's literally it. So your answer is wrong `PNG` files are not secure and it is indeed possible. – t40_yx May 24 '21 at 13:12
  • @t40_yx ...and you did it *without* using the `phar://` stream specifier, so that the PoC would *not* work if one fed it a plain renamed PHAR, but required "masking" as a valid PNG? Because *that* is what would amaze me. Please downvote my answer if you believe it is wrong; I shall not only upvote yours, but actually award it a bounty if the PoC works. – LSerni May 24 '21 at 13:21
  • My question was pertaining to exploiting filesystem functions using a phar-image polygot using the same technique one would use to exploit phar-jpeg polygots, except with a phar-png polygot this would indeed require control of the filename string argument being passed to the filesystem functions for the attacker to exploit it of course. Your original answer did not contain enough information and stated it was impossible. Thanks for clarifying. – t40_yx May 24 '21 at 21:00