HardenedHackingDump

Hardened Hacking Brain Dump

Removing PT_GNU_STACK Marks

We want to remove PT_GNU_STACK markings for reason of ditching the executable stack[1]. We should submit changes upstream when they've worked in Ubuntu.

Note: Sometimes we scanelf -t to find .text relocations. These involve marking libraries RW; rewriting their addresses; and marking them RX again. In general this is bad; but it doesn't cause an executable stack. We'll use scanelf -t when we fix one on Malone.

Below is a scanelf check on /usr/lib for PT_GNU_STACK executable stacks. scanelf comes from pax-utils, a suite of ELF tools to aid auditing systems. Fixed libs are marked with their bug number. Libs with applied fixes have a Smile :) next to them. We ignored klibc binaries here, who is going to exploit an initrd? (We can fix those some time in the distant future)

bluefox@icebox:/tmp/x/libgcrypt11-1.2.2$ scanelf -qeRt /usr/lib

RWX --- --- /usr/lib/liblzo.so.1.0.0 #49401
RWX --- --- /usr/lib/xorg/modules/drivers/nsc_drv.so
RWX --- --- TEXTREL /usr/lib/games/quake2/ref_soft.so
RWX --- --- TEXTREL /usr/lib/games/quake2/ref_softx.so
RWX --- --- TEXTREL /usr/lib/games/quake2/ref_softsdl.so
RWX --- --- /usr/lib/games/quake2/quake2.real
TEXTREL /usr/lib/libSDL_image-1.2.so.0.1.3
RWX --- --- /usr/lib/libgcj.so.7.0.0
TEXTREL /usr/lib/gstreamer-0.10/libgstffmpeg.so
RWX --- --- TEXTREL /usr/lib/libdv.so.4.0.2 #49402
RWX --- --- /usr/lib/libFLAC.so.7.0.0 #49283
RWX --- --- /usr/lib/openoffice/program/libgcc3_uno.so
RWX --- --- /usr/lib/libqthreads.so.12.3.0
TEXTREL /usr/lib/libieee1284.so.3.2.2
RWX --- --- /usr/lib/libsmpeg-0.4.so.0.1.4 #49196
TEXTREL /usr/lib/libmpeg2convert.so.0.0.0
RWX --- --- TEXTREL /usr/lib/libxvidcore.so.4.1 #49387, #49388 (TEXTREL)
TEXTREL /usr/lib/libmpeg2.so.0.0.0
RWX --- --- TEXTREL /usr/lib/libmp3lame.so.0.0.0 #49288
RWX --- --- /usr/lib/libgcrypt.so.11.2.1 #49192
TEXTREL /usr/lib/vlc/codec/libffmpeg_plugin.so
TEXTREL /usr/lib/vlc/stream_out/libstream_out_switcher_plugin.so
RWX --- --- /usr/lib/libgdk_pixbuf.so.2.0.0 #49250
RWX --- --- /usr/lib/libgdk_pixbuf_xlib.so.2.0.0 #49250
RWX --- --- /usr/lib/xmms/Visualization/libbscope.so

And one of /bin:

bluefox@icebox:/tmp/x/libgcrypt11-1.2.2$ scanelf -qeR /bin/

RWX --- --- /bin/gzip #49067
RWX --- --- /bin/gunzip #49067
RWX --- --- /bin/zcat #49067
RWX --- --- /bin/uncompress #49067

And /usr/bin:

bluefox@icebox:/tmp/x/libgcrypt11-1.2.2$ scanelf -qeR /usr/bin/

RWX --- --- /usr/bin/gpgv #49323
RWX --- --- /usr/bin/gpg #49323
RWX --- --- /usr/bin/zip
RWX --- --- /usr/bin/vlc
RWX --- --- /usr/bin/mlgui
RWX --- --- /usr/bin/mlguistarter
RWX --- --- /usr/bin/mlnet
RWX --- --- /usr/bin/mldonkey_options
RWX --- --- /usr/bin/mldonkey_server
RWX --- --- /usr/bin/mldonkey_users
RWX --- --- /usr/bin/mldonkey_files
RWX --- --- /usr/bin/mldonkey_command
RWX --- --- /usr/bin/mldonkey_submit

Example

Fixing GPG, an example.

bluefox@icebox:/tmp/x$ scanelf -qe /usr/bin/gpgv
RWX --- ---   /usr/bin/gpgv
bluefox@icebox:/tmp/x$ dpkg-query -S /usr/bin/gpgv
gnupg: /usr/bin/gpgv

First get the source and build.

bluefox@icebox:/tmp/x$ apt-get source gnupg
...
bluefox@icebox:/tmp/x$ sudo apt-get build-dep gnupg
...
bluefox@icebox:/tmp/x$ cd gnupg-1.4.2.2
...
bluefox@icebox:/tmp/x/gnupg-1.4.2.2$ dpkg-buildpackage -uc -us -rfakeroot

Next, run a scanelf -qeR . in the source tree.

bluefox@icebox:/tmp/x/gnupg-1.4.2.2$ scanelf -qeR .
RWX --- ---  ./build-udeb/tools/mpicalc
RWX --- ---  ./build-udeb/g10/gpgv
RWX --- ---  ./build-udeb/g10/gpg
!WX --- ---  ./build-udeb/mpi/mpih-rshift.o
!WX --- ---  ./build-udeb/mpi/mpih-lshift.o
!WX --- ---  ./build-udeb/mpi/mpih-sub1.o
!WX --- ---  ./build-udeb/mpi/mpih-add1.o
!WX --- ---  ./build-udeb/mpi/mpih-mul3.o
!WX --- ---  ./build-udeb/mpi/mpih-mul2.o
!WX --- ---  ./build-udeb/mpi/mpih-mul1.o
RWX --- ---  ./build-deb/tools/mpicalc
RWX --- ---  ./build-deb/g10/gpgv
RWX --- ---  ./build-deb/g10/gpg
!WX --- ---  ./build-deb/mpi/mpih-rshift.o
!WX --- ---  ./build-deb/mpi/mpih-lshift.o
!WX --- ---  ./build-deb/mpi/mpih-sub1.o
!WX --- ---  ./build-deb/mpi/mpih-add1.o
!WX --- ---  ./build-deb/mpi/mpih-mul3.o
!WX --- ---  ./build-deb/mpi/mpih-mul2.o
!WX --- ---  ./build-deb/mpi/mpih-mul1.o
RWX --- ---  ./debian/gpgv-udeb/usr/bin/gpgv
RWX --- ---  ./debian/tmp/usr/bin/gpg
RWX --- ---  ./debian/tmp/usr/bin/gpgv

OK we know we have to fix something mpi some asm files... delete the source tree and recreate.

bluefox@icebox:/tmp/x/gnupg-1.4.2.2$ cd ..
bluefox@icebox:/tmp/x$ rm -rf gnupg*
bluefox@icebox:/tmp/x$ apt-get source gnupg
...
bluefox@icebox:/tmp/x$ cd gnupg-1.4.2.2

Find any asm:

bluefox@icebox:/tmp/x/gnupg-1.4.2.2$ grep -Hnr "asm" .
...
./mpi/i586/mpih-mul3.S:35:#include "asm-syntax.h"
./mpi/i586/mpih-add1.S:27:#include "asm-syntax.h"
...
bluefox@icebox:/tmp/x/gnupg-1.4.2.2$ find . -name \*.S
./mpi/m68k/mc68020/mpih-mul3.S
./mpi/m68k/mc68020/mpih-mul2.S
./mpi/m68k/mc68020/mpih-mul1.S
./mpi/m68k/mpih-add1.S
./mpi/m68k/mpih-lshift.S
./mpi/m68k/mpih-rshift.S
./mpi/m68k/mpih-sub1.S
./mpi/hppa/udiv-qrnnd.S
./mpi/hppa/mpih-add1.S
./mpi/hppa/mpih-lshift.S
./mpi/hppa/mpih-rshift.S
./mpi/hppa/mpih-sub1.S
./mpi/sparc32v8/mpih-mul3.S
./mpi/sparc32v8/mpih-mul2.S
./mpi/sparc32v8/mpih-mul1.S
./mpi/sparc32/mpih-add1.S
./mpi/sparc32/mpih-lshift.S
./mpi/sparc32/mpih-rshift.S
./mpi/sparc32/udiv.S
./mpi/i586/mpih-mul3.S
./mpi/i586/mpih-add1.S
./mpi/i586/mpih-mul2.S
./mpi/i586/mpih-mul1.S
./mpi/i586/mpih-lshift.S
./mpi/i586/mpih-rshift.S
./mpi/i586/mpih-sub1.S
./mpi/i386/mpih-mul3.S
./mpi/i386/mpih-add1.S
./mpi/i386/mpih-mul2.S
./mpi/i386/mpih-mul1.S
./mpi/i386/mpih-lshift.S
./mpi/i386/mpih-rshift.S
./mpi/i386/mpih-sub1.S
./mpi/supersparc/udiv.S
./mpi/powerpc32/mpih-mul3.S
./mpi/powerpc32/mpih-add1.S
./mpi/powerpc32/mpih-mul2.S
./mpi/powerpc32/mpih-mul1.S
./mpi/powerpc32/mpih-lshift.S
./mpi/powerpc32/mpih-rshift.S
./mpi/powerpc32/mpih-sub1.S
./mpi/hppa1.1/mpih-mul3.S
./mpi/hppa1.1/udiv-qrnnd.S
./mpi/hppa1.1/mpih-mul2.S
./mpi/hppa1.1/mpih-mul1.S
./mpi/alpha/mpih-mul3.S
./mpi/alpha/udiv-qrnnd.S
./mpi/alpha/mpih-add1.S
./mpi/alpha/mpih-mul2.S
./mpi/alpha/mpih-mul1.S
./mpi/alpha/mpih-lshift.S
./mpi/alpha/mpih-rshift.S
./mpi/alpha/mpih-sub1.S
./mpi/pa7100/mpih-lshift.S
./mpi/pa7100/mpih-rshift.S
./mpi/mips3/mpih-mul3.S
./mpi/mips3/mpih-add1.S
./mpi/mips3/mpih-mul2.S
./mpi/mips3/mpih-mul1.S
./mpi/mips3/mpih-lshift.S
./mpi/mips3/mpih-rshift.S
./mpi/mips3/mpih-sub1.S
./mpi/power/mpih-mul3.S
./mpi/power/mpih-add1.S
./mpi/power/mpih-mul2.S
./mpi/power/mpih-mul1.S
./mpi/power/mpih-lshift.S
./mpi/power/mpih-rshift.S
./mpi/power/mpih-sub1.S

They're all .S files so we looked and they're all in mpi. This makes things easier.

Now look for any strange jmps or jnzs or anything with %esp as a target.

bluefox@icebox:/tmp/x/gnupg-1.4.2.2$ grep -Hnr "esp" mpi/
mpi/ChangeLog:93:       remove whitespace before the '#'.  This is not required by C89,
mpi/ChangeLog:118:      * longlong.h: Some whitespace changes in HPPA to fix assembler
mpi/i586/mpih-mul3.S:61:        INSN2(mov,l     ,R(res_ptr),MEM_DISP(esp,20))
mpi/i586/mpih-mul3.S:62:        INSN2(mov,l     ,R(s1_ptr),MEM_DISP(esp,24))
mpi/i586/mpih-mul3.S:63:        INSN2(mov,l     ,R(size),MEM_DISP(esp,28))
mpi/i586/mpih-mul3.S:64:        INSN2(mov,l     ,R(s2_limb),MEM_DISP(esp,32))
mpi/i586/mpih-add1.S:47:        movl    20(%esp),%edi           /* res_ptr */
mpi/i586/mpih-add1.S:48:        movl    24(%esp),%esi           /* s1_ptr */
mpi/i586/mpih-add1.S:49:        movl    28(%esp),%ebp           /* s2_ptr */
mpi/i586/mpih-add1.S:50:        movl    32(%esp),%ecx           /* size */
mpi/i586/mpih-mul2.S:61:        INSN2(mov,l     ,R(res_ptr),MEM_DISP(esp,20))
mpi/i586/mpih-mul2.S:62:        INSN2(mov,l     ,R(s1_ptr),MEM_DISP(esp,24))
mpi/i586/mpih-mul2.S:63:        INSN2(mov,l     ,R(size),MEM_DISP(esp,28))
mpi/i586/mpih-mul2.S:64:        INSN2(mov,l     ,R(s2_limb),MEM_DISP(esp,32))
mpi/i586/mpih-mul1.S:61:        INSN2(mov,l     ,R(res_ptr),MEM_DISP(esp,20))
mpi/i586/mpih-mul1.S:62:        INSN2(mov,l     ,R(s1_ptr),MEM_DISP(esp,24))
mpi/i586/mpih-mul1.S:63:        INSN2(mov,l     ,R(size),MEM_DISP(esp,28))
mpi/i586/mpih-mul1.S:64:        INSN2(mov,l     ,R(s2_limb),MEM_DISP(esp,32))
mpi/i586/mpih-lshift.S:55:      movl    20(%esp),%edi           /* res_ptr */
mpi/i586/mpih-lshift.S:56:      movl    24(%esp),%esi           /* s_ptr */
mpi/i586/mpih-lshift.S:57:      movl    28(%esp),%ebp           /* size */
mpi/i586/mpih-lshift.S:58:      movl    32(%esp),%ecx           /* cnt */
mpi/i586/mpih-rshift.S:55:      movl    20(%esp),%edi           /* res_ptr */
mpi/i586/mpih-rshift.S:56:      movl    24(%esp),%esi           /* s_ptr */
mpi/i586/mpih-rshift.S:57:      movl    28(%esp),%ebp           /* size */
mpi/i586/mpih-rshift.S:58:      movl    32(%esp),%ecx           /* cnt */
mpi/i586/mpih-sub1.S:57:        movl    20(%esp),%edi           /* res_ptr */
mpi/i586/mpih-sub1.S:58:        movl    24(%esp),%esi           /* s1_ptr */
mpi/i586/mpih-sub1.S:59:        movl    28(%esp),%ebp           /* s2_ptr */
mpi/i586/mpih-sub1.S:60:        movl    32(%esp),%ecx           /* size */
mpi/i386/mpih-mul3.S:61:        INSN2(mov,l     ,R(res_ptr),MEM_DISP(esp,20))
mpi/i386/mpih-mul3.S:62:        INSN2(mov,l     ,R(s1_ptr),MEM_DISP(esp,24))
mpi/i386/mpih-mul3.S:63:        INSN2(mov,l     ,R(size),MEM_DISP(esp,28))
mpi/i386/mpih-mul3.S:64:        INSN2(mov,l     ,R(s2_limb),MEM_DISP(esp,32))
mpi/i386/mpih-add1.S:53:        movl 12(%esp),%edi              /* res_ptr */
mpi/i386/mpih-add1.S:54:        movl 16(%esp),%esi              /* s1_ptr */
mpi/i386/mpih-add1.S:55:        movl 20(%esp),%edx              /* s2_ptr */
mpi/i386/mpih-add1.S:56:        movl 24(%esp),%ecx              /* size */
mpi/i386/mpih-add1.S:74:        addl    (%esp),%eax
mpi/i386/mpih-add1.S:76:        addl    $4,%esp
mpi/i386/mpih-mul2.S:61:        INSN2(mov,l     ,R(res_ptr),MEM_DISP(esp,20))
mpi/i386/mpih-mul2.S:62:        INSN2(mov,l     ,R(s1_ptr),MEM_DISP(esp,24))
mpi/i386/mpih-mul2.S:63:        INSN2(mov,l     ,R(size),MEM_DISP(esp,28))
mpi/i386/mpih-mul2.S:64:        INSN2(mov,l     ,R(s2_limb),MEM_DISP(esp,32))
mpi/i386/mpih-mul1.S:60:        INSN2(mov,l     ,R(res_ptr),MEM_DISP(esp,20))
mpi/i386/mpih-mul1.S:61:        INSN2(mov,l     ,R(s1_ptr),MEM_DISP(esp,24))
mpi/i386/mpih-mul1.S:62:        INSN2(mov,l     ,R(size),MEM_DISP(esp,28))
mpi/i386/mpih-mul1.S:63:        INSN2(mov,l     ,R(s2_limb),MEM_DISP(esp,32))
mpi/i386/mpih-lshift.S:52:      movl    16(%esp),%edi           /* res_ptr */
mpi/i386/mpih-lshift.S:53:      movl    20(%esp),%esi           /* s_ptr */
mpi/i386/mpih-lshift.S:54:      movl    24(%esp),%edx           /* size */
mpi/i386/mpih-lshift.S:55:      movl    28(%esp),%ecx           /* cnt */
mpi/i386/mpih-rshift.S:53:      movl    16(%esp),%edi           /* wp */
mpi/i386/mpih-rshift.S:54:      movl    20(%esp),%esi           /* up */
mpi/i386/mpih-rshift.S:55:      movl    24(%esp),%edx           /* usize */
mpi/i386/mpih-rshift.S:56:      movl    28(%esp),%ecx           /* cnt */
mpi/i386/mpih-sub1.S:54:        movl 12(%esp),%edi              /* res_ptr */
mpi/i386/mpih-sub1.S:55:        movl 16(%esp),%esi              /* s1_ptr */
mpi/i386/mpih-sub1.S:56:        movl 20(%esp),%edx              /* s2_ptr */
mpi/i386/mpih-sub1.S:57:        movl 24(%esp),%ecx              /* size */
mpi/i386/mpih-sub1.S:75:        addl    (%esp),%eax
mpi/i386/mpih-sub1.S:77:        addl    $4,%esp
mpi/hppa1.1/mpih-mul1.S:51: * PA7100, respectively.  We don't do that since it does not seem worth the
mpi/longlong.h:79:   respectively.  The result is placed in HIGH_SUM and LOW_SUM.  Overflow
mpi/longlong.h:85:   LOW_SUBTRAHEND_2 respectively.  The result is placed in HIGH_DIFFERENCE

Looks fine to me. Let's hack in the .note.GNU-stack in the laziest way possible:

e="/* Add these three lines to get us a PT_GNU_STACK header */
#ifdef __ELF__
.section .note.GNU-stack,\"\",%progbits
#endif"
for i in `find . -name \*.S`; do echo "$e" >> "$i"; done

Build it.

bluefox@icebox:/tmp/x/gnupg-1.4.2.2$ dpkg-buildpackage -uc -us -rfakeroot

scanelf it.

bluefox@icebox:/tmp/x/gnupg-1.4.2.2$ scanelf -qeR .

Nothing. We're good. File a bug.

[1] Hardened Gentoo Guide to PT_GNU_STACK [2] Hardened Gentoo Guide to pax-utils


CategoryBrainDump

HardenedHackingDump (last edited 2008-08-06 16:38:34 by localhost)