[OpenWrt-Devel] MIPS stack security and other problems

Hauke Mehrtens hauke at hauke-m.de
Tue Dec 18 09:41:20 EST 2018


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.

@Dave: From which device did you get the map and which kernel is used there?

Hauke

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/openwrt-devel/attachments/20181218/31d46c2d/attachment.sig>
-------------- next part --------------
_______________________________________________
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