Author Topic: Linux Memory Hardening  (Read 1728 times)

0 Members and 1 Guest are viewing this topic.

Offline madf0x

  • Knight
  • **
  • Posts: 172
  • Cookies: 50
    • View Profile
Linux Memory Hardening
« on: December 14, 2014, 09:49:02 pm »
Hey there, this is an article I wrote back in 2011 for securityoverride about memory protection mechanisms in linux. Some points may be outdated, like the bit about firefox 0days since UAF bugs have become more popular since and naturally bypass a lot of these protections, but I feel theres still some good points here for those learning about exploit development on linux, or simply want to harden their own system more. So if you see something wrong and/or outdated, please leave a comment pointing it out! Especially if you have references for further reading explaining why in more depth :D

//intro

 Hallo people, first a quick intro about this article. This is going to be all about hardening against memory corruption attacks. You may commonly know these as 0days, stack overflows, heap corruptions, format strings, ect. Sure code fixing is the main defense but its reactive defense. It only works after the fact. That fact may be very well that you got 0wned. Aint that the sh*t? Originally I meant this to be about hardening the core OS but after I thought about it, it left out a few compiler based defenses I felt are important. The truth is that if a single a oh-day ruins your day than you FAILED. You have NOT done your job. Thats because nothing but the most top-notch exploit can bypass the modern day mitigations on a linux box, and even then it is highly situational. Also remember that most "hackers" these days are all teeth and no shell. If you got a better shell then you are already ahead. Who knows, maybe you'll learn a thing or two about what it takes to make a real modern exploit.
 
 *disclaimer* this is not about local kernel 0day protection. My opinion is if youve let them get that far, well f*ck you, you havnt done your job.
 
 //paxtest + checksec.sh
 
 Paxtest and checksec.sh should be your first go-to tools when it comes to evaluating how exploitable* a system is. If you've ever been serious about targeting a box the 'old school way' you know that you try to mirror the target as much as possible. Same kernel, distro, services, ect to play with instead of doing the equivilent of screaming at their network and hoping no one hears you. Thats when you bust out paxtest and checksec.sh, and they are also the first tools you should be using to judge exactly what you need to fix on your box.
 
 Paxtest can be found with a quick google and on my Ubuntu box at least it comes via a nice aptitude install paxtest :P Checksec.sh last I've seen can be found at http://www.trapkit.de/tools/checksec.html
 
 First a quick use of paxtest. Paxtest creates and runs several test runs to check what kernel support for memory protections are in place. Run it with sudo paxtest blackhat ((the other option is --kiddie and they return the same result but I suppose back in the day kiddie made 'safer' checks that werent as accurate)) My 'out of the box' Ubuntu returns this for instance:
 
Code: [Select]
--snip short useless stuff--
 Mode: blackhat
 Linux Rigshaw 2.6.32-31-generic #61-Ubuntu SMP Fri Apr 8 18:24:35 UTC 2011 i686 GNU/Linux
 
 Executable anonymous mapping             : Killed
 Executable bss                           : Killed
 Executable data                          : Killed
 Executable heap                          : Killed
 Executable stack                         : Killed
 Executable anonymous mapping (mprotect)  : Vulnerable
 Executable bss (mprotect)                : Vulnerable
 Executable data (mprotect)               : Vulnerable
 Executable heap (mprotect)               : Vulnerable
 Executable shared library bss (mprotect) : Vulnerable
 Executable shared library data (mprotect): Vulnerable
 Executable stack (mprotect)              : Vulnerable
 Anonymous mapping randomisation test     : 12 bits (guessed)
 Heap randomisation test (ET_EXEC)        : 14 bits (guessed)
 Heap randomisation test (ET_DYN)         : 14 bits (guessed)
 Main executable randomisation (ET_EXEC)  : 12 bits (guessed)
 Main executable randomisation (ET_DYN)   : 12 bits (guessed)
 Shared library randomisation test        : 12 bits (guessed)
 Stack randomisation test (SEGMEXEC)      : 20 bits (guessed)
 Stack randomisation test (PAGEEXEC)      : 19 bits (guessed)
 Return to function (strcpy)              : Vulnerable
 Return to function (strcpy, RANDEXEC)    : Vulnerable
 Return to function (memcpy)              : Vulnerable
 Return to function (memcpy, RANDEXEC)    : Vulnerable
 Executable shared library bss            : Vulnerable
 Executable shared library data           : Killed
 Writable text segments                   : Vulnerable
 

 
 As you can see the kernel protections are pretty sh*t :D But wait, Its got NX(linux's dep) and aslr!!! But holy sh*t look at all that other stuff that's vulnerable that can be used to aid in exploitation! And the aslr is crappy as hell! :P I bet a vast majority of you are having an exlamation mark above the head going on. Don't worry, it's STILL better then a CentOS or Debian box...
 
 Next is checksec.sh This checks for binary protections of a given file, or optionally some running processes(all if root). Its a very nice complement to paxtest in judging the exploitability of a program assuming that there is a flaw. It can also check kernel defenses with --kernel(but that and fixing it will be an exercise for the reader). Typically you should run it with sudo checksec.sh --proc-all > checksec.log and sit back, it may or may not have a lot of output depending on how many processes you got going on, so it's best to save it somewhere. Again, heres my output for a 'out of the box' Ubuntu:
 
Code: [Select]

 * System-wide ASLR (kernel.randomize_va_space): On (Setting: 2)
 
   Description - Make the addresses of mmap base, heap, stack and VDSO page randomized.
   This, among other things, implies that shared libraries will be loaded to random
   addresses. Also for PIE-linked binaries, the location of code start is randomized.
 
   See the kernel file 'Documentation/sysctl/kernel.txt' for more details.
 
 * Does the CPU support NX: Yes
 
          COMMAND    PID RELRO             STACK CANARY           NX/PaX        PIE
             init      1 Full RELRO        Canary found           NX enabled    PIE enabled             
             smbd   1031 Full RELRO        Canary found           NX enabled    PIE enabled             
            getty   1102 Partial RELRO     Canary found           NX enabled    No PIE                 
            getty   1106 Partial RELRO     Canary found           NX enabled    No PIE                 
            getty   1116 Partial RELRO     Canary found           NX enabled    No PIE                 
            getty   1117 Partial RELRO     Canary found           NX enabled    No PIE                 
            getty   1121 Partial RELRO     Canary found           NX enabled    No PIE                 
            acpid   1132 Partial RELRO     Canary found           NX enabled    No PIE                 
       irqbalance   1134 Partial RELRO     Canary found           NX enabled    No PIE                 
             cron   1154 Partial RELRO     Canary found           NX enabled    No PIE                 
              atd   1155 Partial RELRO     Canary found           NX enabled    No PIE                 
   nessus-service   1159 Partial RELRO     Canary found           NX enabled    No PIE                 
          nessusd   1160 Partial RELRO     Canary found           NX enabled    No PIE                 
           mysqld   1176 Full RELRO        Canary found           NX enabled    PIE enabled             
   wpa_supplicant   1193 Partial RELRO     Canary found           NX enabled    No PIE                 
          privoxy   1292 Partial RELRO     Canary found           NX enabled    No PIE                 
       gdm-binary   1296 Partial RELRO     Canary found           NX enabled    No PIE                 
  console-kit-dae   1309 Partial RELRO     Canary found           NX enabled    No PIE                 
  gdm-simple-slav   1374 Partial RELRO     Canary found           NX enabled    No PIE                 
             Xorg   1386 Partial RELRO     Canary found           NX enabled    No PIE                 
              tor   1486 Partial RELRO     Canary found           NX enabled    No PIE                 
         winbindd   1527 Full RELRO        Canary found           NX enabled    PIE enabled             
         winbindd   1552 Full RELRO        Canary found           NX enabled    PIE enabled             
      dbus-launch   1572 Partial RELRO     Canary found           NX enabled    No PIE                 
  gdm-session-wor   1593 Partial RELRO     Canary found           NX enabled    No PIE                 
          upowerd   1595 Partial RELRO     Canary found           NX enabled    No PIE                 
             hald   1598 Partial RELRO     Canary found           NX enabled    No PIE                 
      hald-runner   1599 Partial RELRO     No canary found        NX enabled    No PIE                 
  hald-addon-inpu   1624 Partial RELRO     Canary found           NX enabled    No PIE                 
  hald-addon-rfki   1628 Partial RELRO     Canary found           NX enabled    No PIE                 
  hald-addon-leds   1629 Partial RELRO     Canary found           NX enabled    No PIE                 
  hald-addon-gene   1637 Partial RELRO     Canary found           NX enabled    No PIE                 
  hald-addon-stor   1643 Partial RELRO     Canary found           NX enabled    No PIE                 
  hald-addon-cpuf   1645 Partial RELRO     Canary found           NX enabled    No PIE                 
  hald-addon-acpi   1646 Partial RELRO     Canary found           NX enabled    No PIE                 
          polkitd   1657 Partial RELRO     No canary found        NX enabled    No PIE                 
            cupsd   1721 Full RELRO        Canary found           NX enabled    PIE enabled             
            getty   1800 Partial RELRO     Canary found           NX enabled    No PIE                 
         winbindd   1804 Full RELRO        Canary found           NX enabled    PIE enabled             
  gnome-keyring-d   1830 Partial RELRO     Canary found           NX enabled    No PIE                 
    gnome-session   1848 Partial RELRO     Canary found           NX enabled    No PIE                 
        ssh-agent   1961 Full RELRO        Canary found           NX enabled    PIE enabled             
      dbus-launch   1964 Partial RELRO     Canary found           NX enabled    No PIE                 
      dbus-daemon   1965 Partial RELRO     Canary found           NX enabled    PIE enabled             
         gconfd-2   1968 Partial RELRO     Canary found           NX enabled    No PIE                 
  gnome-settings-   1975 Partial RELRO     No canary found        NX enabled    No PIE                 
            gvfsd   1977 Partial RELRO     Canary found           NX enabled    No PIE                 
  gvfs-fuse-daemo   1982 Partial RELRO     No canary found        NX enabled    No PIE                 
         metacity   1987 Partial RELRO     Canary found           NX enabled    No PIE                 
       pulseaudio   1989 Full RELRO        Canary found           NX enabled    No PIE                 
     rtkit-daemon   1991 Partial RELRO     Canary found           NX enabled    No PIE                 
               sh   1994 Partial RELRO     Canary found           NX enabled    No PIE                 
  netbook-launche   1996 Partial RELRO     Canary found           NX enabled    No PIE                 
  gnome-power-man   1999 Partial RELRO     Canary found           NX enabled    No PIE                 
  polkit-gnome-au   2001 Partial RELRO     No canary found        NX enabled    No PIE                 
      gnome-panel   2004 Partial RELRO     Canary found           NX enabled    No PIE                 
        rhythmbox   2007 Partial RELRO     No canary found        NX enabled    No PIE                 
   gnome-terminal   2008 Partial RELRO     Canary found           NX enabled    No PIE                 
           evince   2009 Full RELRO        Canary found           NX enabled    PIE enabled             
        nm-applet   2011 Partial RELRO     Canary found           NX enabled    No PIE                 
         nautilus   2012 Partial RELRO     Canary found           NX enabled    No PIE                 
          yakuake   2013 Partial RELRO     No canary found        NX enabled    No PIE                 
     gconf-helper   2020 Partial RELRO     Canary found           NX enabled    No PIE                 
  gvfs-gdu-volume   2022 Partial RELRO     Canary found           NX enabled    No PIE                 
    udisks-daemon   2026 Partial RELRO     Canary found           NX enabled    No PIE                 
    udisks-daemon   2027 Partial RELRO     Canary found           NX enabled    No PIE                 
  gvfs-gphoto2-vo   2029 Partial RELRO     Canary found           NX enabled    No PIE                 
  gvfs-afc-volume   2031 Partial RELRO     No canary found        NX enabled    No PIE                 
          evinced   2034 Full RELRO        No canary found        NX enabled    PIE enabled             
  gnome-pty-helpe   2040 Partial RELRO     Canary found           NX enabled    No PIE                 
             bash   2041 Partial RELRO     Canary found           NX enabled    No PIE                 
  bonobo-activati   2044 Partial RELRO     Canary found           NX enabled    No PIE                 
  gnome-screensav   2046 Partial RELRO     Canary found           NX enabled    No PIE                 
   go-home-applet   2054 Partial RELRO     No canary found        NX enabled    No PIE                 
  indicator-apple   2056 Partial RELRO     No canary found        NX enabled    No PIE                 
     clock-applet   2058 Partial RELRO     Canary found           NX enabled    No PIE                 
  indicator-apple   2060 Partial RELRO     No canary found        NX enabled    No PIE                 
  notification-ar   2063 Partial RELRO     Canary found           NX enabled    No PIE                 
  window-picker-a   2064 Partial RELRO     No canary found        NX enabled    No PIE                 
      gvfsd-trash   2085 Partial RELRO     Canary found           NX enabled    No PIE                 
  gdu-notificatio   2090 Partial RELRO     No canary found        NX enabled    No PIE                 
        syndaemon   2095 Partial RELRO     Canary found           NX enabled    No PIE                 
   gvfsd-metadata   2133 Partial RELRO     Canary found           NX enabled    No PIE                 
  indicator-me-se   2136 Partial RELRO     No canary found        NX enabled    No PIE                 
  indicator-sessi   2139 Partial RELRO     No canary found        NX enabled    No PIE                 
  indicator-appli   2144 Partial RELRO     No canary found        NX enabled    No PIE                 
  indicator-sound   2146 Partial RELRO     No canary found        NX enabled    No PIE                 
  indicator-messa   2148 Partial RELRO     No canary found        NX enabled    No PIE                 
       gvfsd-burn   2151 Partial RELRO     Canary found           NX enabled    No PIE                 
       notify-osd   2217 Partial RELRO     Canary found           NX enabled    No PIE                 
           python   2250 Partial RELRO     Canary found           NX enabled    No PIE                 
         kdeinit4   2260 Partial RELRO     Canary found           NX enabled    No PIE                 
        klauncher   2263 Partial RELRO     Canary found           NX enabled    No PIE                 
            kded4   2265 Partial RELRO     Canary found           NX enabled    No PIE                 
     kglobalaccel   2270 Partial RELRO     Canary found           NX enabled    No PIE                 
             bash   2271 Partial RELRO     Canary found           NX enabled    No PIE                 
       gvfsd-http   2329 Partial RELRO     Canary found           NX enabled    No PIE                 
  update-notifier   2364 Partial RELRO     Canary found           NX enabled    No PIE                 
         knotify4   2424 Partial RELRO     No canary found        NX enabled    No PIE                 
               su   2672 Partial RELRO     Canary found           NX enabled    No PIE                 
             bash   2680 Partial RELRO     Canary found           NX enabled    No PIE                 
             nmbd   2814 Full RELRO        Canary found           NX enabled    PIE enabled             
            udevd   3092 Full RELRO        Canary found           NX enabled    PIE enabled             
            udevd   3117 Full RELRO        Canary found           NX enabled    PIE enabled             
         dhclient   3127 Full RELRO        Canary found           NX enabled    PIE enabled             
      firefox-bin   4752 Full RELRO        Canary found           NX enabled    PIE enabled             
  plugin-containe   4780 Full RELRO        No canary found        NX enabled    PIE enabled             
  GoogleTalkPlugi   4813 No RELRO          No canary found        NX disabled   No PIE                 
            xchat   4961 Partial RELRO     Canary found           NX enabled    No PIE                 
            gedit   4972 Partial RELRO     Canary found           NX enabled    No PIE                 
             bash   4973 Partial RELRO     Canary found           NX enabled    No PIE                 
             gksu   5242 Partial RELRO     No canary found        NX enabled    No PIE                 
         synaptic   5243 Partial RELRO     Canary found           NX enabled    No PIE                 
  upstart-udev-br    531 Full RELRO        No canary found        NX enabled    PIE enabled             
            udevd    534 Full RELRO        Canary found           NX enabled    PIE enabled             
             smbd    965 Full RELRO        Canary found           NX enabled    PIE enabled             
             sshd    973 Full RELRO        Canary found           NX enabled    PIE enabled             
         rsyslogd    978 Partial RELRO     Canary found           NX enabled    No PIE                 
      dbus-daemon    986 Partial RELRO     Canary found           NX enabled    PIE enabled             
     avahi-daemon    994 Partial RELRO     Canary found           NX enabled    No PIE                 
   NetworkManager    995 Partial RELRO     Canary found           NX enabled    No PIE                 
     avahi-daemon    996 Partial RELRO     Canary found           NX enabled    No PIE                 
    modem-manager    998 Partial RELRO     Canary found           NX enabled    No PIE

 Ill explain the different columns as we face them. A quick visual scan and a bit of intuition tell us the the google talk plugin would be pretty easy to exploit if we found a flaw in it. Well, assuming it would even be worthwile to investigate as a target in the first place :) another place, another place. Now on to the fun stuff!
 
 //NX
 
 First of all, if your cpu doesnt support hardware NX ((top of checksec.sh output)) Chuck it out and get one that does? There, fixed :)
 
 //grsecurity
 
 As you may remember from paxtest that my aslr only involves a handful of bits that is really pathetic against a real exploit(if it even bothers beating aslr head on :) ), and my heap protection and a bunch of other stuff is pretty shitty. This is where grsecurity comes in. You can get a full list of features at http://grsecurity.net/features.php that can do better justice explaining why it is important better than I ever could. It pretty much fixes almost everything. Why it's patches aren't part of the linux dev tree already is beyond me. You can get it from the same site's download section or if you are using aptitude you can get the package at http://kernelsec.cr0.org/
 
 *disclaimer* read the F*cking page before you complain about stuff not working. Also this DOES install a new kernel. If need be, hunt down how to apply the patch to your own kernel source if you have a custom compiled one or it suddenly breaks on you.
 
 Follow the simple instructions at the bottom of the page(if you can't, get a new f*cking hobby :D ). Its recommend you install paxctl while you are at it in case you ever need to change the configuration(why thats in the repos by default and not grsecurity that it controls is another mystery in life).
 
 The only issue is that sometimes it conflicts with some firmware deal and will abort the isntall(did with mine). This means youll have to go the old school way of compiling it from the source. Check out grsecurity's wiki about that. I dont feel like writing an entire book.
 
 //Canaries
 
 Typically this is a protection you SHOULDNT have to worry about. But....looking back at checksec.sh We do a few times out of the box. Stack canaries are a specific set of bytes placed at the end of a stack buffer. The kernel keeps checking for this value whenever a program is running. Since the canary is before eip, you gotta trample the canary to get to eip during an exploit. The kernel is not too found of this idea and will slay the process quicker than you can say shell. Yeah, dont even get to 'shellc'(ode). There are some bypasses but frankly it out of anything makes stack overflows practically obsolete. If you find a process DOESN'T have it, you have to sigh and get it enabled youreself. That means recompiling :/ do a ./configure and then grep the makefile for a -fno-stack-protector and get rid of that retarded line(my lil bro is autistic and I tend to find that workd offensive, that shows how maddening it is to see 'production code' that uses that option. Assuming gcc is up to date, all shall be well. If the proggy breaks thanks to your changes...find an alternative >.>
 
 //Relro
 
 Ahh now to the stuff that seems like only exploit writers(or those serious about learning it, and I mean serious) seem to be aware of. Relro comes in two fassions, partial and full. As you may have guessed full is better than partial. Partial relro is implemented with the gcc compiler options -Wl,z,relro what this does is reorganize a few internel elf data sections to make it more difficult to mess with(not really). And the non-PLT GOT sections is read-only. That last bit is pretty meaningless since it is barely used in exploitation anyways. Nowadays overwriting GOT in general is cool. Full one ups partial by making the ENTIRE got section read-only. With old-school protections that means practically all of your modern 0days are poof! Out the window and out of site :P In fact im still trying to dig up papers about crushing full relro but it's been no-dice so far. Too new and badass I suppose and likely any 'generic' technique would be relatively unknown and a quick ticket to fame or infamy. Anyways you get it running with gcc -Wl,-z,relro,-z,now And yeah, this likely means a LOT of re-compiling if youre paranoid.
 
 //PIE
 
 Ahh the older sister of relro. PIE'd executables are likewise badass. PIE stands for position-independent-executable. Heres the part that makes exploitation scary when youre back up looking at checksec.sh. See how all but the most vital daemons ARENT PIE? Not so good. So whats the big secret about PIE? To qoute wikipedia:
 
 "PIE binaries are used in some security-focused Linux distributions to allow PaX or Exec Shield to use address space layout randomization to prevent attackers from knowing where existing executable code is during a security attack using exploits that rely on knowing the offset of the executable code in the binary, such as return-to-libc attacks."
 
 Yep, this is your fancy, modern aslr. Ya know, the one that is even marginally effective? Technicalities and 'test-programs' aside, you can consider aslr to be good as disabled on any non-PIE program. Back to recomp time with a snazy -fPIE slapped onto gcc ;) doesnt work with --static Ive heard and prob shouldn't be used while compiling .so libs(but the final executable...definately). So far guess what the only real public bypass of PIE is? got overwriting. Remember what full relro was SOOOO good at? ;DDD Back up at checksec.sh, ever wondered why firefox 0days for linux are never bothered with? Ill let you draw youre own (obvious) conclusions.
 
 (speaking of...)
 //Conclusion
 
 Ok, maybe this wasn't a 1-2-3 guide like some of ya may have hoped, but I hope those of you who have read it and havnt looked into modern exploitation have learned a thing or two about defending from 0days, and perhaps a catalog of what you gotta crush in the modern world to write those very same 0days.
 
 References: Too many to count, google a good keyword and I've probably read the results and commited its contribution to memory ;P props to all the underrated exploit writers who don't get the credit they deserve and the guys like the PaX team that have the balls to say, "F*ck your zero days! Bring it!"
 
 Note: If anyone has any information on screwing over RELRO or exploiting PIE, I'd love if ya sent me links/article names/blogs/etc that may be of interest ;)

Offline proxx

  • Avatarception
  • Global Moderator
  • Titan
  • *
  • Posts: 2803
  • Cookies: 256
  • ФФФ
    • View Profile
Re: Linux Memory Hardening
« Reply #1 on: December 16, 2014, 07:19:08 am »
Excellent post sir, take this cookie.
Wtf where you thinking with that signature? - Phage.
This was another little experiment *evillaughter - Proxx.
Evilception... - Phage