On 18/12/2018 01:44, Rosen Penev wrote:
On Mon, Dec 17, 2018 at 4:34 PM Rosen Penev <[email protected]> wrote:
On Mon, Dec 17, 2018 at 3:40 PM Dave Taht <[email protected]> wrote:
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;
}
I tested this. Output on current master:
root@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
_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/mailman/listinfo/openwrt-devel