The Elusive SSH: Hunt For The Origin IP
Leveraging LFI to reveal IP address behind a CDN, for possible SSH ownage.
You found the private key to a server, but it’s behind a CDN platform. Now what?! It’s not easy SSH-ing into a server behind a CDN proxy but if you have an LFI, there is still some hope.
Markdown Menace: LFI
While experimenting with the “Bulk Markdown Import” feature of HashNode, my mate Aditya noticed that if the markdown file had a reference to an image file, the markdown parser would look for the file internally and throw an error (as it failed to locate the file). So, if we had the following markdown content:
---
title: "Why I use Hashnode"
date: "2020-02-20T22:37:25.509Z"
slug: "why-i-use-hashnode"
image: "Insert Image URL Here"
---
This is a test MD file.
![blog.jpg](/images/blog.jpg)
The parser will throw the following error: Markdown parser started looking for “blog.jpg” wherever it stored the markdown file, and upon failing (obviously) threw this verbose error. Does this mean if markdown contained a reference to an internal file, it will be successfully fetched? You bet it did!
Exploiting LFI
A classic ../../../../etc/passwd
payload was enough to trick the markdown parser into
looking for a local file and upload it to HashNode's CDN, as intended. Our malicious
markdown looked like this:
---
title: "Why I use Hashnode"
date: "2020-02-20T22:37:25.509Z"
slug: "why-i-use-hashnode"
image: "Insert Image URL Here"
---
This is a test MD file.
![blog.jpg](../../../../etc/passwd)
This file was parsed without any hiccups. In response, we get a URL where the fetched file
is uploaded (as the server assumed it was a legit image file):
Now it was as simple as visiting the URL and downloading the internal file which can later
be viewed (As an example, in our case it will be the /etc/passwd
file).
The next logical step was to attempt retrieving the private SSH key of the user with a
/home
folder and a shell. And that's exactly what we did. Luckily, the private key was at the
default location i.e /home/user/.ssh/id_rsa
. But we hit a roadblock at this point. HashNode
uses a CDN, which meant we were not able to SSH to the server using the private key
as the origin IP is hidden behind the CDN's proxy. But we did not give up.
Finding The Origin IP
This was not an overly complex task, but something about which we had no idea
beforehand. Zach (he runs an awesome
infosec Discord server) suggested taking a look at the
/proc/net/tcp
file which might reveal some information regarding the IP addresses
associated with the server and that's where we struck gold.
The Mysterious /proc/net/tcp
So what is this file? /proc/net/tcp
contains information regarding all the network
connections and corresponding interfaces in hexadecimal form. Below is what the contents in
this file look like:
Understanding what each entry meant was its own hell. Thanks to this kernel.org
document, it was clear what we were looking at. Below is a screencap from the URL:
We focused on the local addresses as they were IPs assigned to the server. Each local
address entry was hex value of the decimal value of IP but in reverse. So if the entry is
AABBCCDD and corresponding IP is a.b.c.d then AA=d , BB=c and so on.
From the /proc/net/tcp we retrieved three IPs. One was 127.0.0.1, which was expected. Another one was 10.x.x.x which we figured was the internal IP address. Lastly, one translated into 192.x.x.x and this one piqued our interest, as it was owned by a cloud service provide. We tried establishing an SSH connection through netcat and voila: We were able to establish an SSH connection. We did not proceed further and reported our findings to the HashNode team.
End Of The Line
Here are our concluding thoughts:
- It's fair to say a large number of verbose error messages are still out there spitting information that bad actors leverage to move ahead. Developers need to be keen on what they leave for everyone to see.
- Local file inclusion in markdown importing and parsing might be something that's exploitable in numerous applications out there and ready to be pwned, it's just a matter of time.
- Linux files are a treasure trove of crucial information that can help you further increase the impact of your initial findings. As we saw how /proc/net/tcp gave us the public IP of the origin server, other files might also prove helpful.
Links for reference:
Aditya Dixit's Twitter: twitter.com/zombie007o
Zach's Discord Server: discord.gg/cbt2RBD
Kernel.org Documentation on /proc/net/tcp:kernel.org/doc/Documentation/networking/pro..