[OpenWrt-Devel] MIPS stack security and other problems

Rosen Penev rosenp at gmail.com
Tue Dec 18 11:48:44 EST 2018


On Tue, Dec 18, 2018 at 6:41 AM Hauke Mehrtens <hauke at hauke-m.de> wrote:
>
> On 12/18/18 11:02 AM, Andre Heider wrote:
> > On 18/12/2018 01:44, Rosen Penev wrote:
> >> On Mon, Dec 17, 2018 at 4:34 PM Rosen Penev <rosenp at gmail.com> wrote:
> >>>
> >>> On Mon, Dec 17, 2018 at 3:40 PM Dave Taht <dave at taht.net> wrote:
> >>>>
> >>>> John Crispin <john at phrozen.org> writes:
> >>>>
> >>>>> On 17/12/2018 23:18, Dave Taht wrote:
> >>>>>> Rosen Penev <rosenp at gmail.com> writes:
> >>>>>>
> >>>>>>> On Sun, Dec 16, 2018 at 4:54 PM Dave Taht <dave at taht.net> wrote:
> >>>>>>>>
> >>>>>>>> A pretty deep look at home MIPS and arm routers, and a surprising
> >>>>>>>> bug in Linux/MIPS - by mudge and co:
> >>>>>>>>
> >>>>>>>> https://cyber-itl.org/2018/12/07/a-look-at-home-routers-and-linux-mips.html
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> I have no idea if current openwrt, or what prior releases... are
> >>>>>>>> subject to
> >>>>>>>> the problems they outline.
> >>>>>>> As of kernel 4.14.88, I see the same problems.
> >>>>>> Well, I see that the stack, at least, on kernel 4.4.92 on mips and
> >>>>>> 4.14 on openwrt 18.06...
> >>>>>>
> >>>>>> is mapped rw only, with no execute bit.
> >>>>>>
> >>>>>> That doesn't mean the other other flaws discussed in the paper don't
> >>>>>> exist, but at least current openwrt HEAD is using the right gcc
> >>>>>> version
> >>>>>> to turn the right linkage on. Someone here with waaaay more
> >>>>>> expertise in
> >>>>>> the compiler, here, should take a hard look at this and the paper.
> >>>>>>
> >>>>>>
> >>>>>> root at lupin-jeff:~# cat /proc/self/maps
> >>>>>> 00400000-0044b000 r-xp 00000000 1f:04 879        /bin/busybox
> >>>>>> 0045b000-0045c000 rw-p 0004b000 1f:04 879        /bin/busybox
> >>>>>> 77182000-771a4000 r-xp 00000000 1f:04 611        /lib/libgcc_s.so.1
> >>>>>> 771a4000-771a5000 rw-p 00012000 1f:04 611        /lib/libgcc_s.so.1
> >>>>>> 771a6000-77238000 r-xp 00000000 1f:04 653        /lib/libc.so
> >>>>>> 77245000-77246000 r--p 00000000 00:00 0          [vvar]
> >>>>>> 77246000-77247000 r-xp 00000000 00:00 0          [vdso]
> >>>>>> 77247000-77249000 rw-p 00091000 1f:04 653        /lib/libc.so
> >>>>>> 77249000-7724b000 rwxp 00000000 00:00 0 # is this the heap?
> >>>>>> 7fe06000-7fe27000 rw-p 00000000 00:00 0          [stack]
> >>>>>>
> >>>>>>
> >>>>>>>> _______________________________________________
> >>>>>>>> openwrt-devel mailing list
> >>>>>>>> openwrt-devel at lists.openwrt.org
> >>>>>>>> https://lists.openwrt.org/mailman/listinfo/openwrt-devel
> >>>>>> _______________________________________________
> >>>>>> openwrt-devel mailing list
> >>>>>> openwrt-devel at lists.openwrt.org
> >>>>>> https://lists.openwrt.org/mailman/listinfo/openwrt-devel
> >>>>>
> >>>>> Dave,
> >>>>>
> >>>>> too lazy to read thd pdf, in a nutshell whats the issue and what do we
> >>>>> need to do do to mitigate it ?
> >>>>
> >>>>  From the paper: (It's the second comment regarding ALSR bypass via a
> >>>> deterministic segment that concerns me most). They are claiming that
> >>>> the
> >>>> emulation segment at
> >>>>
> >>>> 7ffff000-80000000 rwxp 00000000 00:00 0
> >>>>
> >>>> is a bad idea, in the paper. Which openwrt has.
> >>>>
> >>>>
> >>>> "Timeline Key:
> >>>> (A)
> >>>> 2001: Linux introduces FPU emulation in kernel 2.4.3.4. This puts
> >>>> code on the stack and
> >>>> executes it there requiring the stack be marked as readable,
> >>>> writable, and executable.
> >>>> (B)
> >>>> 2016 July:  a new page was introduced to execute branch delay slot
> >>>> instructions. This
> >>>> was introduced to remove the code being inserted and executed on the
> >>>> program stack.
> >>>> However, this fix introduced a new fixed location segment that can
> >>>> be used to bypass
> >>>> ASLR defenses.
> >>>> 3
> >>>> (C)
> >>>> 2016 August:  a patch to make the stack and heap non-execute was
> >>>> introduced, if a
> >>>> PT_GNU_STACK was present. However, as noted in the patch none of the
> >>>> toolchains
> >>>> used to build executables created a PT_GNU_STACK and the stack would
> >>>> remain
> >>>> executable until this was addressed in compiler toolchains.
> >>>> 4
> >>>> In summary, Linux MIPS binaries have been easier to exploit by way
> >>>> of classic stack overflow
> >>>> attacks for over a decade, and continue to be so according to our
> >>>> examination of toolchain
> >>>> patches. Additionally, the fix that moved FPU emulation off the
> >>>> stack created a separate DEP
> >>>> and
> >>>>
> >>>> ASLR exposure.  Even if patches were introduced today for both the
> >>>> kernel and the
> >>>> toolchains, the lag in adoption implies it could be years before
> >>>> Linux MIPS devices can be
> >>>> expected to have basic DEP and ASLR.
> >>>> "
> >>>>
> >>>> Their proof of concept for exploiting this on mipsel is:
> >>>>
> >>>> include <stdio.h>
> >>>> #include <stdlib.h>
> >>>> #include <string.h>
> >>>> #include <unistd.h>
> >>>>
> >>>> int main(void) {
> >>>>      // set a pointer to the vfpu emulation page address
> >>>>      void* p = (void *)0x7ffff000;
> >>>>      printf("%p\n", (void*)p);
> >>>>      // construct a function pointer from p
> >>>>      void (*func_ptr)(void) = p;
> >>>>      // 'jr $ra' mips32el instruction bytes
> >>>>      char code[] = {0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00};
> >>>>      // copy the instruction to the vfpu page
> >>>>      memcpy(p, code, 8);
> >>>>      // call the function pointer, this should then directly return
> >>>> back
> >>>>      (*func_ptr)();
> >>>>      // print out the current maps of the process
> >>>>      char cmd[200];
> >>>>      sprintf(cmd, "cat /proc/%d/maps", getpid());
> >>>>      system(cmd);
> >>>>      return 0;
> >>>> }
> >>> I tested this. Output on current master:
> >>>
> >>> root at OpenWrt:/tmp# ./a.out
> >>> 0x7ffff000[ 1213.393861] do_page_fault(): sending SIGSEGV to a.out for
> >>> invalid write access to 7ffff003
> >>>
> >>> [ 1213.402945] epc = 555757ac in a.out[55575000+1000]
> >>> [ 1213.407816] ra  = 55575774 in a.out[55575000+1000]
> >>> Segmentation fault
> >> Ah I see. OpenWrt has 304-mips_disable_fpu.patch which makes this
> >> fail. Although from the looks of it, lantiq enables this.
> >
> > On lantiq it indeed looks differently:
> >
> > $ cat /etc/openwrt_release
> > DISTRIB_ID='OpenWrt'
> > DISTRIB_RELEASE='SNAPSHOT'
> > DISTRIB_REVISION='r8714+2-a969e96e47'
> > DISTRIB_TARGET='lantiq/xrx200'
> > DISTRIB_ARCH='mips_24kc'
> > DISTRIB_DESCRIPTION='OpenWrt SNAPSHOT r8714+2-a969e96e47'
> > DISTRIB_TAINTS='no-all'
> >
> > $ cat /proc/self/maps
> > 00400000-0044b000 r-xp 00000000 1f:03 736        /bin/busybox
> > 0045a000-0045b000 r-xp 0004a000 1f:03 736        /bin/busybox
> > 0045b000-0045c000 rwxp 0004b000 1f:03 736        /bin/busybox
> > 77efa000-77f1d000 r-xp 00000000 1f:03 995        /lib/libgcc_s.so.1
> > 77f1d000-77f1e000 rwxp 00013000 1f:03 995        /lib/libgcc_s.so.1
> > 77f1e000-77fb6000 r-xp 00000000 1f:03 993        /lib/libc.so
> > 77fc5000-77fc7000 rwxp 00097000 1f:03 993        /lib/libc.so
> > 77fc7000-77fc9000 rwxp 00000000 00:00 0
> > 7f834000-7f855000 rw-p 00000000 00:00 0          [stack]
> > 7fefb000-7fefc000 rwxp 00000000 00:00 0
> > 7fffc000-7fffd000 r--p 00000000 00:00 0          [vvar]
> > 7fffd000-7fffe000 r-xp 00000000 00:00 0          [vdso]
> >
> > Regards,
> > Andre
>
> Hi,
>
> On my lantiq xrx200 system with kernel 4.14 it looks similar to Andre's
> memory map. The mapping at 7fefb000 also exists on my device and is rwx,
> so I assume that this is the same as the mapping at 0x7ffff000 they
> talked in the paper about.
>
> I am also wondering why the 3. mapping of busybox is also rwx, procd has
> the same, see her:
> ---------------------------------------------------------------------
> root at LEDE:~# cat /proc/1/maps
> 00400000-0040a000 r-xp 00000000 fe:00 201        /sbin/procd
> 00419000-0041a000 r-xp 00009000 fe:00 201        /sbin/procd
> 0041a000-0041b000 rwxp 0000a000 fe:00 201        /sbin/procd
> 0041b000-0041d000 rwxp 00000000 00:00 0
> ....
> ---------------------------------------------------------------------
>
> readelf shows no section with rwx, but the two LOAD sections with
> deferent permissions are very close to each other.
>
> ---------------------------------------------------------------------
> hauke at hauke-desktop:~/openwrt/lede$ readelf -W -l
> build_dir/target-mips_24kc_musl/procd-2018-11-23-d6673547/ipkg-install/usr/sbin/procd
>
>
> ......
>
> Program Headers:
>   Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
>   PHDR           0x000034 0x00400034 0x00400034 0x00140 0x00140 R   0x4
>   INTERP         0x000174 0x00400174 0x00400174 0x0001a 0x0001a R   0x1
>       [Requesting program interpreter: /lib/ld-musl-mips-sf.so.1]
>   ABIFLAGS       0x000190 0x00400190 0x00400190 0x00018 0x00018 R   0x8
>   REGINFO        0x0001a8 0x004001a8 0x004001a8 0x00018 0x00018 R   0x4
>   LOAD           0x000000 0x00400000 0x00400000 0x09b70 0x09b70 R E 0x10000
>   LOAD           0x009d2c 0x00419d2c 0x00419d2c 0x00834 0x02a64 RW  0x10000
>   DYNAMIC        0x0001c0 0x004001c0 0x004001c0 0x00168 0x00168 R   0x4
>   GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
>   GNU_RELRO      0x009d2c 0x00419d2c 0x00419d2c 0x002d4 0x002d4 R   0x1
>   NULL           0x000000 0x00000000 0x00000000 0x00000 0x00000     0x4
> ......
> ---------------------------------------------------------------------
>
> Do the common MIPS CPUs support non executable stacks at all?
> cpu_has_rixi is set to 0 for the ath79 SoCs for example, for lantiq some
> automatic detection is done, but I haven't checked the result.
ramips has RIXI enabled by default. This is the result for procd:

root at OpenWrt:/# cat /proc/1/maps
55616000-55624000 r-xp 00000000 1f:05 1902       /sbin/procd
55633000-55634000 r-xp 0000d000 1f:05 1902       /sbin/procd
55634000-55635000 rwxp 0000e000 1f:05 1902       /sbin/procd
55635000-55637000 rwxp 00000000 00:00 0
55bdb000-55c03000 rwxp 00000000 00:00 0          [heap]
77e9e000-77ec1000 r-xp 00000000 1f:05 1700       /lib/libgcc_s.so.1
77ec1000-77ec2000 rwxp 00013000 1f:05 1700       /lib/libgcc_s.so.1
77ec2000-77ed4000 r-xp 00000000 1f:05 1715       /lib/libjson_script.so
77ed4000-77ed5000 r-xp 00002000 1f:05 1715       /lib/libjson_script.so
77ed5000-77ed6000 rwxp 00003000 1f:05 1715       /lib/libjson_script.so
77ed6000-77ee7000 r-xp 00000000 1f:05 1706       /lib/libblobmsg_json.so
77ee7000-77ee8000 r-xp 00001000 1f:05 1706       /lib/libblobmsg_json.so
77ee8000-77ee9000 rwxp 00002000 1f:05 1706       /lib/libblobmsg_json.so
77ee9000-77eff000 r-xp 00000000 1f:05 915        /usr/lib/libjson-c.so.2.0.2
77eff000-77f00000 r-xp 00006000 1f:05 915        /usr/lib/libjson-c.so.2.0.2
77f00000-77f01000 rwxp 00007000 1f:05 915        /usr/lib/libjson-c.so.2.0.2
77f01000-77f15000 r-xp 00000000 1f:05 1705       /lib/libubus.so
77f15000-77f16000 r-xp 00004000 1f:05 1705       /lib/libubus.so
77f16000-77f17000 rwxp 00005000 1f:05 1705       /lib/libubus.so
77f17000-77f2e000 r-xp 00000000 1f:05 1703       /lib/libubox.so
77f2e000-77f2f000 r-xp 00007000 1f:05 1703       /lib/libubox.so
77f2f000-77f30000 rwxp 00008000 1f:05 1703       /lib/libubox.so
77f30000-77fc8000 r-xp 00000000 1f:05 1702       /lib/libc.so
77fd7000-77fd9000 rwxp 00097000 1f:05 1702       /lib/libc.so
77fd9000-77fdb000 rwxp 00000000 00:00 0
7f9ff000-7fa20000 rw-p 00000000 00:00 0          [stack]
7fefc000-7fefd000 rwxp 00000000 00:00 0
7ff8b000-7ff8d000 r--p 00000000 00:00 0          [vvar]
7ff8d000-7ff8e000 r-xp 00000000 00:00 0          [vdso
>
> @Dave: From which device did you get the map and which kernel is used there?
>
> Hauke
>

_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list