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
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.
Links
[1] Hardened Gentoo Guide to PT_GNU_STACK [2] Hardened Gentoo Guide to pax-utils
HardenedHackingDump (last edited 2008-08-06 16:38:34 by localhost)