OpenBSD Journal

anti-ROP mechanism in libc

Contributed by phessler on from the dont cry over spilled registers dept.

Theo (deraadt@) writes in to the tech@ mailing list, with a clever idea that we would like to try.

This change randomizes the order of symbols in libc.so at boot time.

This is done by saving all the independent .so sub-files into an ar archive, and then relinking them into a new libc.so in random order, at each boot. The cost is less than a second on the systems I am using.

For now, this is only done for libc, because it is generally the most gadget heavy library; spilled registers are more likely to point within the libc segment; and also the gadgets are close to system call stubs. As a result of the change, gadgets are no longer found at fixed offsets from spilled registers.

More details are available on tech@. Please check the thread for any replies or updates.

(Comments are closed)


Comments
  1. By foo (151.67.38.133) on

    Has this been implemented anywhere else before?

  2. By Federico Bento (88.214.187.163) up201407890@alunos.dcc.fc.up.pt on

    Seems like a weaker implementation of fine-grained ASLR to me, which accomplishes nothing on local attacks and is vulnerable to all attacks against fine-grained ASLR, eg:
    http://www.ieee-security.org/TC/SP2013/papers/4977a574.pdf

    Comments
    1. By Can Acar (70.95.81.189) canacar@ on

      To put it another way, OpenBSD is about to become the first OS experimenting with fine-grained ASLR in its default install.

      Is it a silver bullet? No.

      Does it raise the bar? Yes, especially against non-local attackers.

      Many powerful gadgets including code that invokes kernel syscalls, executes a command shell, and changes memory permissions mmap()/mprotect() live in libc, so gaining access to these gadgets is the ultimate goal of many ROP-based exploits. Making these entry points harder to find makes ROP chains more complex, or requires attacker to extract binaries from the system or have an arbitrary read primitive (which is even more general than the heartbleed bug) to find system-specific gadgets.

      Is it expensive? No. Adding a few seconds to boot time (unless you are building a mobile-phone OS) is perfectly fine. There is basically zero additional runtime cost.

      Given that the purpose of ASLR and other countermeasures is to increase the difficulty of attacks and make them less reliable, this is a promising one.

      Comments
      1. By PaXTeam (77.234.78.182) pageexec@freemail.hu on pax.grsecurity.net

        > Does it raise the bar? Yes, especially against non-local attackers.
        
        it's similar to KASLR which is also a pointless exercise.
        
        > Given that the purpose of ASLR and other countermeasures is to increase the difficulty of attacks
        > and make them less reliable, this is a promising one.
        
        how will this stop BROP?

        Comments
        1. By Can Acar (70.95.81.189) canacar@ on

          > it's similar to KASLR which is also a pointless exercise.

          In what sense is it similar to KASLR?

          Because it does protect against local attacks?

          Ignoring all other problems with KASLR, most attacks against the kernel (KASLR) are from usermode, so it is hard to claim KASLR is for network attacks only. This is not true for fine-grained randomization where usermode programs are more likely be attacked from the network.

          Because it is half-baked? -- applying a concept incorrectly/out of context?

          This is an experiment to see how far we can go with something like this. libc contains most of the "cool" functionality. There are most likely wrappers in the application or other libraries for, say, mprotect() so perhaps only randomizing libc is pointless. But we need to start somewhere.

          Perhaps we will have to scramble all system libraries at boot. Perhaps packages will scramble libraries at install time. Perhaps we will rip all of it back out, when we have something better based on the lessons learned, like it is happening to systrace after pledge.

          By the way, OpenBSD does not have KASLR. It was not a priority mostly because of cost of implementing does not justify the (very limited) benefits. This one, however, is extremely easy to implement and it has basically zero runtime cost so is worth playing with.


          > how will this stop BROP?

          Where did anyone claim that this is a silver bullet? Also, BROP-like brute-forcing attacks have a very distinct signature. Perhaps we should not let our servers keep faulting hundreds of times before we do something about it.


          Comments
          1. By PaXTeam (77.234.78.182) pageexec@freemail.hu on pax.grsecurity.net

            > > it's similar to KASLR which is also a pointless exercise.
            >
            > In what sense is it similar to KASLR?

            to quote the blog, "this moving target only moves once and is pretty easy to spot".

            > Because it does protect against local attacks?

            it being...? 'cos neither this libc relinking nor KASLR protect against local attacks.

            > Ignoring all other problems with KASLR, most attacks against the kernel (KASLR) are from usermode,

            no, KASLR doesn't in general protect against local attacks except in very specific cases (i think the motivating example was ChromeOS and its very locked down app model or something like that).

            > so it is hard to claim KASLR is for network attacks only. This is not true for fine-grained randomization
            > where usermode programs are more likely be attacked from the network.

            why more likely? do you have usage stats on OpenBSD deployments? on linux there's a huge amount of local exposure due to containers/virtualization/webhosting/android/etc.

            > > how will this stop BROP?
            >
            > Where did anyone claim that this is a silver bullet?

            BROP means that this defense is DOA (the paper specifically calls out gentoo among others where there's already 'natural' diversity among not only libc binaries but everything else as well yet that didn't prevent exploitation).

            > Also, BROP-like brute-forcing attacks have a very distinct signature. Perhaps we should not
            > let our servers keep faulting hundreds of times before we do something about it.

            like we've been doing it in grsec for well over a decade? :) perhaps you should be paying more attention to actual security research instead of reinventing useless defenses. the brute force prevention part of ASLR is mandatory as i explained it so many years ago.

            Comments
            1. By Renaud Allard (renaud) on


              > like we've been doing it in grsec for well over a decade? :) perhaps you should be paying more attention to actual security research instead of reinventing useless defenses. the brute force prevention part of ASLR is mandatory as i explained it so many years ago.

              Take into account that this is ought to be a default (unfortunately unlike grsec) measure against automated network attacks and which costs strictly nothing in runtime. In other words, it's better than nothing and does not really cost more than nothing.

            2. By Can Acar (70.95.81.189) canacar@ on

              > > Because it does protect against local attacks?
              >
              > it being...? 'cos neither this libc relinking nor KASLR protect against local attacks.

              I meant "it does NOT protect against local attacks". Sorry for the confusion.

              Yes, this raises the bar slightly, and mainly against remote attacks. But it is dirt cheap, so it is worth experimenting with.


              > BROP means that this defense is D OA (the paper specifically calls out gentoo among others where there's already 'natural' diversity among not only libc binaries but everything else as well yet that didn't prevent exploitation).

              No. It means there are other defenses against BROP-like bruteforcing attacks as you also point out.

              > like we've been doing it in grsec for well over a decade? :)

              Yes, this would be good to have.

              Comments
              1. By kraileth (95.118.140.31) on eerielinux.wordpress.com

                > > like we've been doing it in grsec for well over a decade? :)
                >
                > Yes, this would be good to have.
                >

                Ah, that's the attitude! A sober response aiming only on the technical side despite the text it refers to being something like "we've been doing it for over a decade (we totally rule) and you should really pay more attention to serious research (besides you suck)".

                Thanks for that answer which once again reminds me of one good reason why I kind of left Linux for *BSD.

                Comments
                1. By Anonymous Coward (89.101.149.149) on

                  > > > like we've been doing it in grsec for well over a decade? :)
                  > >
                  > > Yes, this would be good to have.
                  > >
                  >
                  > Ah, that's the attitude! A sober response aiming only on the technical side despite the text it refers to being something like "we've been doing it for over a decade (we totally rule) and you should really pay more attention to serious research (besides you suck)".
                  >
                  > Thanks for that answer which once again reminds me of one good reason why I kind of left Linux for *BSD.

                  I guess grsec gets "punchy" because some people found out some security flaws recently.

              2. By PaXTeam (188.143.77.136) pageexec@freemail.hu on pax.grsecurity.net

                > No. It means there are other defenses against BROP-like bruteforcing attacks as you also point out.

                well, the logic is quite simple i think: if you have brute force prevention then normal ASLR is already enough, library relinking doesn't add anything meaningful because the bound on an attack's success rate is dominated by the number of attempts and not the entropy in addresses. if you don't have brute force prevention then library relinking is useless due attacks like BROP. IOW, if you just implemented brute force prevention you'd be as good as it can get.

                Comments
                1. By foo (151.67.43.30) on

                  > well, the logic is quite simple i think: if you have brute force prevention then normal ASLR is already enough, library relinking doesn't add anything meaningful because the bound on an attack's success rate is dominated by the number of attempts and not the entropy in addresses. if you don't have brute force prevention then library relinking is useless due attacks like BROP. IOW, if you just implemented brute force prevention you'd be as good as it can get.


                  It is like you didn't want OpenBSD to include this simple trick.

                2. By Anonymous Coward (79.247.132.99) on

                  > > No. It means there are other defenses against BROP-like bruteforcing attacks as you also point out.
                  >
                  > well, the logic is quite simple i think: if you have brute force prevention then normal ASLR is already enough, library relinking doesn't add anything meaningful because the bound on an attack's success rate is dominated by the number of attempts and not the entropy in addresses. if you don't have brute force prevention then library relinking is useless due attacks like BROP. IOW, if you just implemented brute force prevention you'd be as good as it can get.

                  > > No. It means there are other defenses against BROP-like bruteforcing attacks as you also point out.
                  >
                  > well, the logic is quite simple i think: if you have brute force prevention then normal ASLR is already enough, library relinking doesn't add anything meaningful because the bound on an attack's success rate is dominated by the number of attempts and not the entropy in addresses. if you don't have brute force prevention then library relinking is useless due attacks like BROP. IOW, if you just implemented brute force prevention you'd be as good as it can get.

                  You don't understand the fundamental basics of this concept nor what it prevents. I recomment you to read more about malware programming (which will teach you a lot about explpiting and mitigations.. like metamorphic programming..).

                  I don't belief "YOU" wrote "in the name of the project" nor that you're affilated.

            3. By Joachim Schipper (2001:980:2f71:1:e072:464b:e34e:2b6e) joachim@joachimschipper.nl on http://www.joachimschipper.nl

              > > > how will this stop BROP?
              > >
              > > Where did anyone claim that this is a silver bullet?
              >
              > BROP means that this defense is DOA (the paper specifically calls out gentoo among others where there's already 'natural' diversity among not only libc binaries but everything else as well yet that didn't prevent exploitation).

              To be fair, BROP is a bit too cutting-edge at the moment; e.g. https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2015/june/blind-return-oriented-programming/ concludes "From my experience, [BROP] works much better in theory than in practice."

              That said, relinking libc only works against attackers who don't have a very powerful infoleak. E.g. https://twitter.com/halvarflake/status/724899492391190528, which you have no doubt seen, mostly agrees with you.

              (Full disclosure: the company I work for was acquired by NCC and is now only semi-independent; I don't know the author of the linked report.)

        2. By Anonymous Coward (79.247.132.99) on

          >
          > Does it raise the bar? Yes, especially against non-local attackers.
          >
          > it's similar to KASLR which is also a
          >
          > Given that the purpose of ASLR and other countermeasures is to increase the difficulty of attacks
          > and make them less reliable, this is a promising one.
          >
          > how will this stop BROP?

          No it is not.

          You do lack fundamental knowledge of security exploitation and mitration technics. Yes you might can code an Exploit and use ROB's all day long... impressive...

    2. By Anonymous Coward (148.87.19.194) on

      > Seems like a weaker implementation of fine-grained ASLR to me, which accomplishes nothing on local attacks and is vulnerable to all attacks against fine-grained ASLR, eg:
      > http://www.ieee-security.org/TC/SP2013/papers/4977a574.pdf

      It really doesn't seem particularly beneficial for at least a few reasons:

      * randomization is done once, at boot, and never after, which means
      that any infoleak in any binary will reveal the information the
      attacker needs

      * no affect locally (I can launch my own binary and dump the library
      image)

      * remotely, if I have an infoleak in demon A and a bug in demon B, I
      can use the infoleak in A to exploit B

      * seems like preventing the return in the first place would be more
      effective than attempting to "hide" the information

      Comments
      1. By Anonymous Coward (79.247.132.99) on

        > > Seems like a weaker implementation of fine-grained ASLR to me, which accomplishes nothing on local attacks and is vulnerable to all attacks against fine-grained ASLR, eg:
        > > http://www.ieee-security.org/TC/SP2013/papers/4977a574.pdf
        >
        > It really doesn't seem particularly beneficial for at least a few reasons:
        >
        > * randomization is done once, at boot, and never after, which means
        > that any infoleak in any binary will reveal the information the
        > attacker needs

        10 Servers, 10 different Values, 10 times an Informationleak required

        >
        > * no affect locally (I can launch my own binary and dump the library
        > image)



        > * remotely, if I have an infoleak in demon A and a bug in demon B, I
        > can use the infoleak in A to exploit B

        That is correct (in Theory). But if you now Attack B and you fail and the server crashes you can try it again. To build a successfull Exploit you might need to "rebuild" your libc (localy) to match the remote Version to test your Exploit. It should be kind of impossible to exploit Applications like Pidgin or Browsers effectively if the libc is randomized. And if I'm correct: Most Malware and/or security breaches ain't done during cracking Servers and Services directly.

        Is it a silver Bullet to resolve every Issue in any case? No..

        > * seems like preventing the return in the first place would be more
        > effective than attempting to "hide" the information

        So what is your Solution and how is it implemented?

      2. By Anonymous Coward (192.35.17.17) on

        > * randomization is done once, at boot, and never after, which means
        > that any infoleak in any binary will reveal the information the
        > attacker needs
        So every machine has a different libc, after every restart. Instead of every OpenBSD 6.0 install has the same one. Remote attackers can not simply test remote exploits on their machine.

        > * no affect locally (I can launch my own binary and dump the library
        > image)
        Not targeted at local attacks.

        > * remotely, if I have an infoleak in demon A and a bug in demon B, I
        > can use the infoleak in A to exploit B
        Good luck with that.

        > * seems like preventing the return in the first place would be more
        > effective than attempting to "hide" the information
        this is just the next step after pledge, W^X, stack protector, ASLR, PIE, static-PIE, random stack gap, arc4random, and many more...

        Randomize all the things!!!

  3. By foo (151.67.17.214) on

    It is a great idea to protect software such as browsers and email clients! :)

    For network daemons it would be cool if OpenBSD could add an incremental timer for respawning...

    Like the login prompt when you get to wait an incremental time (1, 2, 4, 8, ... seconds) every time you fail the login. So the service is slowed but also the exploiting is slowed, and hopefully a message to root@ is delivered, so he could use PF to redirect the attacking IP(s) to a honeypot or simply drop the traffic.

    Comments
    1. By Anonymous Coward (79.247.132.99) on

      > It is a great idea to protect software such as browsers and email clients! :)
      >
      > For network daemons it would be cool if OpenBSD could add an incremental timer for respawning...
      >
      > Like the login prompt when you get to wait an incremental time (1, 2, 4, 8, ... seconds) every time you fail the login. So the service is slowed but also the exploiting is slowed, and hopefully a message to root@ is delivered, so he could use PF to redirect the attacking IP(s) to a honeypot or simply drop the traffic.
      >

      How shouzld this get realized with Daemons where nobody uses a login?
      smtpd? ntpd? dhcpd? :-/

      Comments
      1. By foo (151.67.104.97) on

        > > Like the login prompt when you get to wait an incremental time (1, 2, 4, 8, ... seconds) every time you fail the login. So the service is slowed but also the exploiting is slowed, and hopefully a message to root@ is delivered, so he could use PF to redirect the attacking IP(s) to a honeypot or simply drop the traffic.
        > >
        >
        > How shouzld this get realized with Daemons where nobody uses a login?
        > smtpd? ntpd? dhcpd? :-/


        The code that respawns daemons simply keeps a counter of how many times the daemon has been restarted then it is just a matter of waiting 2^x seconds ;-)

      2. By Anonymous Coward (90.105.212.102) on

        > > It is a great idea to protect software such as browsers and email clients! :)
        > >
        > > For network daemons it would be cool if OpenBSD could add an incremental timer for respawning...
        > >
        > > Like the login prompt when you get to wait an incremental time (1, 2, 4, 8, ... seconds) every time you fail the login. So the service is slowed but also the exploiting is slowed, and hopefully a message to root@ is delivered, so he could use PF to redirect the attacking IP(s) to a honeypot or simply drop the traffic.
        > >
        >
        > How shouzld this get realized with Daemons where nobody uses a login?
        > smtpd? ntpd? dhcpd? :-/

        fwiw, smtpd is not getting a "respawn" feature anytime soon ;-)

    2. By phessler (phessler) on http://www.openbsdfoundation.org/donations.html

      > It is a great idea to protect software such as browsers and email clients! :)
      >
      > For network daemons it would be cool if OpenBSD could add an incremental timer for respawning...
      >
      > Like the login prompt when you get to wait an incremental time (1, 2, 4, 8, ... seconds) every time you fail the login. So the service is slowed but also the exploiting is slowed, and hopefully a message to root@ is delivered, so he could use PF to redirect the attacking IP(s) to a honeypot or simply drop the traffic.
      >

      The network daemons don't respawn. They suicide REALLY HARD.

  4. By Anonymous Coward (2a06:3000::120:4) on

    So now there's a whole compiler (and a rubbish GNU one for that matter!) in the base set, just for linking some files together, which *might* improve the security of a single library. Isn't this marvelous.

    Comments
    1. By Billy Larlad (69.178.115.77) on http://www.openbsd.org

      > So now there's a whole compiler (and a rubbish GNU one for that matter!) in the base set, just for linking some files together, which *might* improve the security of a single library. Isn't this marvelous.

      It looks like ar, cc, and ld were the only binaries moved into base for this. They amount to about two megabytes...

      http://freshbsd.org/commit/openbsd/35f67871fe17aac92f8afc865c9666cbeacd410e

Credits

Copyright © - Daniel Hartmeier. All rights reserved. Articles and comments are copyright their respective authors, submission implies license to publish on this web site. Contents of the archive prior to as well as images and HTML templates were copied from the fabulous original deadly.org with Jose's and Jim's kind permission. This journal runs as CGI with httpd(8) on OpenBSD, the source code is BSD licensed. undeadly \Un*dead"ly\, a. Not subject to death; immortal. [Obs.]