John Crispin <[email protected]> writes:

> On 17/12/2018 23:18, Dave Taht wrote:
>> Rosen Penev <[email protected]> writes:
>>
>>> On Sun, Dec 16, 2018 at 4:54 PM Dave Taht <[email protected]> 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@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
>>>> [email protected]
>>>> https://lists.openwrt.org/mailman/listinfo/openwrt-devel
>> _______________________________________________
>> openwrt-devel mailing list
>> [email protected]
>> 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
> [email protected]
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel

_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to