[OpenWrt-Devel] MIPS stack security and other problems

Dave Taht dave at taht.net
Mon Dec 17 18:40:19 EST 2018


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;
}


>
>     John
>
>
>
>
>
> _______________________________________________
> 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


More information about the openwrt-devel mailing list