I always believe that finding vulnerabilities in bug-bounty program is always easy but the main trick is in the reconnaissance/mapping phase. The purpose of the following write-up is not only to show the vulnerabilities and how to find them, but it shows how to do a good reconnaissance in a pentest/bughunting process. Many people don’t share their methodologies in bug hunting which I can understand why. I am also not going to share all my techniques but I am sharing some of the fundamentals in this write-up.
Before we delve into the write-up, let’s brefiely introduce Deutsche Telekom
Deutsche Telekom AG (English: German Telecom) is a German telecommunications company headquartered in Bonn. Deutsche Telekom was formed in 1996. In 2012 Deutsche Telekom started their bug bounty program. They has a very interesting bug bounty program which I have been participating in for almost 3 years (since it started). What I really love about their bb program is that they only accept Remote Code Execution (RCE), SQL injection (SQLi) and other critical vulnerabilities (some people will get judgemental here ^^). They don’t accept Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF) and other client-side attacks. This makes it very challenging program (for me).
Everything started off with the following subdomain “https://raz.telekom.de“. When I searched for that subdomain in all search engines (thanks to sublist3r), I couldn’t find it. I also use subbrute with all possible combinations of the alphabets of length (3) because it is a relatively small space to bruteforce.
When visiting “https://raz.telekom.de” I got a 403 response.
I run dirbuster with a customised dictionary and I managed to find some pages. The following screenshot shows how the main.php looked like.
From the previous page, you can see that I am logged in with some guest user and there are some functionalities I can do. (Probably due to messed up session management)
Before starting with my vulnerability research, I usually try to understand what is the purpose of the web application and how it works. This is actually an essential part of reconnaissance which is not done by any tools. I looked at the application and tried different functionalities. From its name, it is a license management application. I can import licences, check licenses for different devices, update licenses and view the licenses information. For me, it looked a very interesting application with many tempting functionalities to test. I always love to start with the “meaty” functionality. As a result, I decided to start with the upload functionality in “import license”. I tried to upload different files with different extensions, but every time I got the following error message.
From the error message, we can understand that my uploaded file doesn’t match a specific format that is defined in a configuration file (test date) from the error message.
My hypothesis at that point was the following: I need to find the configuration file and then upload a correct file that matches what is in the configuration and then I can either find RCE from injecting php code or SQLi if the file is used in a SQL statement.
Let’s start with finding the configuration file. Looking at the request that was sent when uploading my license, we see the following
I added a single quote in the “conf” variable which seems the configuration file parameter. We can see that in the error message there is “file doesnt seems to exist or is not readable”. I decided to try some file traversal and see if I can read the file or just know its location and then fetch it from the web directly.
I tried to access the same file name but with “./” in the beginning. It worked and the code managed to parse the configuration file.
I tried to access “test date” directly from the web in the root folder but I got 404 (https://raz.telekom.de/test%20date). Probably the configuration file is inside a folder. When I added a single quote to the “man” parameter I also got the error of being unable to parse the file. I assumed that the “man” parameter is the parent folder of the configuration file. I tried the following
That went very well, the “test date” file was fetched and parsed correctly. As expected the man parameter is the folder for the configuration file (probably an abbreviation for manufacturer!). I continued with my hypothesis and tried to fetch the configuration file from the web directly. I tried to access “https://raz.telekom.de/Funkwerk/test date”, but I got a 404. Obviously, I am missing other things. I tried to access “https://raz.telekom.de/Funkwerk” but I got 404 which means either the configuration folder is not hosted on the web or there is a parent directory. Dirbuster was running to enumerate all possible directories (recon never ends!). I wrote a quick python script to take the results of dirbuster and make them as parent directories for the “Funkwerk” directory. If I got anything other than 404 then that is a success. The script showed me that the parent folder was “config“. Very interesting! I am getting closer
When I try to access “https://raz.telekom.de/config/Funkwerk” I get a 403 (forbidden) response.
Now, I probably should figure out the correct extension in order to download the configuration file. But before reconning to the extension, I decided to choose another configuration file because that one was named “test date” which probably a test configuration file and won’t contain anything interesting. I went for the following (that was a stupid move actually ^^)
I also tried the path traversal as following
To get the extension of the configuration file (recon again!), I decided to quickly write a python function that tests “https://raz.telekom.de/config/OneBridge/obmg.[4letters]”
I tried all combination of 3 and 4 letters extensions hoping it to be one of them.
I executed the function and that was the result
The extension is “ini” I fetched obmg.ini and as we see in the following screenshot.
LAME! That one should have been named test 😀 😀
I went back to the “test date” file and that was the content… much better ^^
We should have uploaded a CSV file with delimiter “;”. Everything was going perfectly well with my hypothesis.
By that time, I needed to test two things “SQLi” in the CSV file and to inject php code and see if the file will be saved as php. Given the fact that I can upload any files with any extensions as long as they match the configuration, I uploaded a CSV file with the following <?phpinfo();?> in different fields. From Dirbuster, I have found a directory called “uploads”. Every time I uploaded a file, I had tried to access it in the uploads directory but I always got a 404 response. Looks like that isn’t working (for now at least).
Let’s go for the SQLi!
I tried to add a single quote in every filed of the CSV file and that was the result.
Clearly a SQL injection vulnerability. I was very very happy at that point.
I decided to exploit it in error-based method (I love error-based) and that was my PoC
But wait! I want to PWN this application. For some reason, I wanted to get RCE on that server and completely own it. I decided to keep checking for other bugs in the application.
Before continuing my pentest, I need to feedback my recon deamons (recon never ends!). I managed to know that the configuration extension is “ini” so I should try to find all interesting configuration files and see if there is something interesting. I added the “ini” to my recon deamons and they start “raping” the subdomain “raz.telekom.de”
While the recon was working, I checked another page that you gave it HW serial number and it checks the details of that license in the database. I tested for SQLi and it was positive as you can see it below (Karma for the hardwork ! ^^)
Back to my recon, I managed to find that there is PHPMyAdmin hosted on that server. I checked if I was root using my SQLi’s which would have probably enabled me to login to that PHPMyAdmin to escalate my privileges. Unfortunately I wasn’t a root user.
going over my recon results I found this interesting configuration file “lms.ini” I fetched the file and ….
Those were the credentials to the DB which means I can login to phpmyadmin. Indeed, I logged into phpmyadmin and the main reason behind that was they used an old phpmyadmin that was vulnerable to XML eXternal Entity injection (XXE). We, at secforce, managed to write metasploit module to exploit that vulnerability.
As you can see in the following screenshot I managed to login into phpmyadmin and the vulnerable version is highlighted.
I exploited the XXE to have it as my PoC
Again from the lms.ini file, I managed to find that there is a web service running on that server and it was vulnerable to SQL injection.
SQL injection III
I fed the lms.ini file into my recon process because it has so much rich information such as “.cfg” configuration files.
I kept going for my goal to get RCE vulnerability. I checked the upload feature thoroughly but it uploaded my files into “[timestamp].csv” I tried different ways to change the extension but it wasn’t possible. I checked if there was anyway I can include the “.csv” file into another file and run the php code inside but that wasn’t possible. I wasn’t able to get RCE 🙁
However, I was really satisfied with what I found and I decided to report everything.
By this, we reach to the end of this write-up. All I want to say through that write-up is that reconnaissance is the main key to find good vulnerabilities.
Reconnaissance never ends!