Block > Shellshock

 5 min (925 Wörter, 5582 Zeichen)

Inhaltsverzeichnis

Dank Shellshock haben wir nun auf dem Server die FastCGI -Skripte, die ich fuer Rezepte, Urlaube und die Tagcloud genutzt habe, entfernt.
Der Grund dafuer sollte klar sein, FastCGI nutzt z.B. die bash und sollte damit nun eher nicht mehr verwendet werden.
Auch der Wechsel zu sh bringt da nicht viel, ist z.B. die sh unter Arch Linux nur ein Symlink zu /bin/bash

Update (2014-10-12)

Meillo hat mich fuer die obigen Zeilen kritisiert - und das zu Recht. Daher fange ich mal neu an:

Grund fuer die Abschaltung sind die bekannt gewordenen Luecken in Bash , auch bekannt als Shellshock. Da die FastCGI-Skripte Bash-Skripte waren, waren die damit auch eine Sicherheitsluecke.
Da ich ehrlich gesagt zu faul war, die Skripte abzusichern haben wir uns der Einfachheit entschlossen, (Fast-)CGI nicht mehr zu benutzen.
Und eigentlich wars das auch schon.
Ueber den Einsatz von CGI kann gestritten werden: es ist zwar einfach, aber eben auch fehleranfaellig, gerade weil der komplette Request vom Client teils ohne Ueberpruefung an den Interpreter bzw. Kernel weitergegeben wird (wenn ich das richtig verstanden habe).
Und ein “Wechsel” zur /bin/sh ist laut Meillo auch nicht so sinnvoll, da es ja nur ein Vorgaenger von bash ist. Sinnvoller waere ein Wechsel zu einer ash -Variante, z.B. dash

D.h. von nun an ist alles statisch , selbst die Tagcloud
Aenderungen gibt es lediglich bei der URL , aber es gibt ja Redirects 😉

Shellshock #

Fuer alle, die keinen Server besitzen, ist Shellshock nicht soo dramatisch, allerdings schadet es auch auf privaten Rechnern nicht, dagegen immun zu sein.

Ob der eigene Rechner anfaellig fuer Shellshock ist, kann z.B. ueber dieses Skript herausgefunden werden.

  bashcheck

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/bin/bash

warn() {
	if [ "$scary" == "1" ]; then
		echo -e "\033[91mVulnerable to $1\033[39m"
	else
		echo -e "\033[93mFound non-exploitable $1\033[39m"
	fi
}

good() {
	echo -e "\033[92mNot vulnerable to $1\033[39m"
}

tmpdir=`mktemp -d -t tmp.XXXXXXXX`

[ -n "$1" ] && bash=$(which $1) || bash=$(which bash)
echo -e "\033[95mTesting $bash ..."
$bash -c 'echo "Bash version $BASH_VERSION"'
echo -e "\033[39m"

#r=`a="() { echo x;}" $bash -c a 2>/dev/null`
if [ -n "$(env 'a'="() { echo x;}" $bash -c a 2>/dev/null)" ]; then
	echo -e "\033[91mVariable function parser active, maybe vulnerable to unknown parser bugs\033[39m"
	scary=1
elif [ -n "$(env 'BASH_FUNC_a%%'="() { echo x;}" $bash -c a 2>/dev/null)" ]; then
	echo -e "\033[92mVariable function parser pre/suffixed [%%, upstream], bugs not exploitable\033[39m"
	scary=0
elif [ -n "$(env 'BASH_FUNC_a()'="() { echo x;}" $bash -c a 2>/dev/null)" ]; then
	echo -e "\033[92mVariable function parser pre/suffixed [(), redhat], bugs not exploitable\033[39m"
	scary=0
elif [ -n "$(env '__BASH_FUNC<a>()'="() { echo x;}" $bash -c a 2>/dev/null)" ]; then
	echo -e "\033[92mVariable function parser pre/suffixed [__BASH_FUNC<..>(), apple], bugs not exploitable\033[39m"
	scary=0
else
	echo -e "\033[92mVariable function parser inactive, bugs not exploitable\033[39m"
	scary=0
fi


r=`env x="() { :; }; echo x" $bash -c "" 2>/dev/null`
if [ -n "$r" ]; then
	warn "CVE-2014-6271 (original shellshock)"
else
	good "CVE-2014-6271 (original shellshock)"
fi

pushd $tmpdir > /dev/null
env x='() { function a a>\' $bash -c echo 2>/dev/null > /dev/null
if [ -e echo ]; then
	warn "CVE-2014-7169 (taviso bug)"
else
	good "CVE-2014-7169 (taviso bug)"
fi
popd > /dev/null

$($bash -c "true $(printf '<<EOF %.0s' {1..80})" 2>$tmpdir/bashcheck.tmp)
ret=$?
grep AddressSanitizer $tmpdir/bashcheck.tmp > /dev/null
if [ $? == 0 ] || [ $ret == 139 ]; then
	warn "CVE-2014-7186 (redir_stack bug)"
else
	good "CVE-2014-7186 (redir_stack bug)"
fi


$bash -c "`for i in {1..200}; do echo -n "for x$i in; do :;"; done; for i in {1..200}; do echo -n "done;";done`" 2>/dev/null
if [ $? != 0 ]; then
	warn "CVE-2014-7187 (nested loops off by one)"
else
	echo -e "\033[96mTest for CVE-2014-7187 not reliable without address sanitizer\033[39m"
fi

$($bash -c "f(){ x(){ _;};x(){ _;}<<a;}" 2>/dev/null)
if [ $? != 0 ]; then
	warn "CVE-2014-6277 (lcamtuf bug #1)"
else
	good "CVE-2014-6277 (lcamtuf bug #1)"
fi

if [ -n "$(env x='() { _;}>_[$($())] { echo x;}' $bash -c : 2>/dev/null)" ]; then
	warn "CVE-2014-6278 (lcamtuf bug #2)"
elif [ -n "$(env BASH_FUNC_x%%='() { _;}>_[$($())] { echo x;}' $bash -c : 2>/dev/null)" ]; then
	warn "CVE-2014-6278 (lcamtuf bug #2)"
elif [ -n "$(env 'BASH_FUNC_x()'='() { _;}>_[$($())] { echo x;}' $bash -c : 2>/dev/null)" ]; then
	warn "CVE-2014-6278 (lcamtuf bug #2)"
else
	good "CVE-2014-6278 (lcamtuf bug #2)"
fi

rm -rf $tmpdir

Oder schneller/einfacher (Skript vorher lesen/verstehen!):

wget -O bashcheck https://raw.githubusercontent.com/hannob/bashcheck/master/bashcheck && chmod +x ./bashcheck && ./bashcheck

Achtung (2014-10-12)

Meillo merkte ebenfalls an, dass der obige Befehl natuerlich super unsicher ist, wenn nicht vorher das Skript gelesen/verstanden wurde.
Ich habe es benutzt, weil es mehr testet, als der Einzeiler , der die eigentliche Luecke identifiziert:

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

Redirects mit Lighttpd #

Speziell in meinem Fall wollte ich alle .fcgi-Dateien zu den nun statischen Seiten weiterleiten, und auch insbesondere alles hinter dem Parameter q.
Also z.B.:

//yhaupenthal.org/tagcloud.fcgi?q=vegan => //yhaupenthal.org/tagcloud_vegan.htm

Letztendlich reichen dafuer folgende drei Zeilen (mit HTTP Status Code 302 ) (Quelle ):

url.redirect = ( "^/(tagcloud|holidays|recipes).fcgi$" => "/$1.htm",
         "^/(tagcloud|holidays|recipes).fcgi\?q=(.*)$" => "/$1_$2.htm" )
url.redirect-code = 302

 Liebes Internet,
Haikus 

Beitraginfos

 2014-10-04, 15:09:30
 2023-09-30, 18:22:59
  lighttpd, neu, shellshock
 Permalink

Ähnliche Beiträge