[LINUX] Wie man ein Terminal hackt

Future Advent Calendar 2019 Dies ist der Artikel am 17. Tag.

Ich bin heutzutage süchtig nach Go, aber dieses Mal werde ich es mir anders überlegen. Ich möchte ein Terminal-Sharing-Tool namens ttycopy vorstellen, das ich in meinem vorherigen Projekt gelegentlich verwendet habe.

Es gibt eine Szene wie ~~ Ich möchte hacken ~~ Ich möchte sehen ...! Wenn ein Superingenieur auf dem Server sshing und etwas tut. Überprüfen Sie anschließend den Bildschirm, indem Sie überprüfen, ob der Befehl auf dem Server korrekt eingegeben wurde. Wenn es eine physische Entfernung gibt, ist es schwierig, den Bildschirm auf dem Monitor anzuzeigen. [^ 1]

[^ 1]: Wenn Sie es verwenden, lehnen Sie es natürlich ab, bevor Sie es verwenden.

Eine Möglichkeit besteht darin, den Bildschirm anzuzeigen, aber es wäre klug, wenn Sie mit einem kleinen Werkzeug darauf zugreifen könnten. In Perl gibt es ein Tool namens ttylog. Inspiriert von ttylog habe ich eine Shell-basierte [ttycopy] erstellt (https://github.com/d-tsuji/ttycopy). Es funktioniert in der Shell, sodass Sie die ttycopy-Implementierung kopieren, einfügen und beiläufig ausführen können.

Beispielbetrieb

Es funktioniert wie folgt. Es ist ein bisschen verwirrend, aber ich bin als Root- und Tsuji-Benutzer bei einem Server angemeldet und führe ttycopy als Root-Benutzer aus. Sie können sehen, dass das als Tsuji-Benutzer angemeldete Terminal in der Mitte des Terminals angezeigt wird.

ttycopy

Wie ttylog funktioniert, erfahren Sie auch in Geben Sie den Terminalbildschirm ohne Erlaubnis frei und werfen Sie einen Blick auf die Arbeit anderer. Der grundlegende Verarbeitungsablauf ist wie folgt.

  1. Ermitteln Sie die PID des tty-Anmeldevorgangs
  2. Sehen Sie sich Systemaufrufe mit dem Befehl strace auf der PID an
  3. Formatieren und Anzeigen der von strace ausgegebenen gelesenen Systemaufrufzeichenfolge

In ttycopy habe ich es gemäß dem obigen Verfahren in die Shell implementiert.

Implementierung in Shell (Bash)

1. Ermitteln Sie die PID des tty-Anmeldevorgangs

Die Implementierung in der Shell ist wie folgt.

pid=`ps fauwwx | grep sshd.*${tty} | grep -v grep | sed -e 's/^[a-zA-Z0-9]\+[ \n\r\f\t]\+\([0-9]\+\).*/\1/'`

Es erfasst die PID des Prozessbaums, die von grep abgerufen werden kann, mithilfe eines regulären Ausdrucks. Es ist erfrischend mit regulären Ausdrücken.

[tsuji@localhost ~]$ ps fauwwx | grep sshd.
root      1531  0.0  0.1  82568  6236 ?        Ss   15:29   0:00 /usr/sbin/sshd -D
root      2830  0.0  0.2 149824  8916 ?        Ss   15:29   0:01  \_ sshd: root@pts/0
root     13315  0.0  0.2 158980 10280 ?        Ss   18:58   0:00  \_ sshd: root@notty
root     14956  0.0  0.2 154512  9352 ?        Ss   20:10   0:00  \_ sshd: tsuji [priv]
tsuji    14959  0.0  0.1 154512  4092 ?        S    20:10   0:00      \_ sshd: tsuji@pts/1
tsuji    15012  0.0  0.0 112672  2268 pts/1    S+   20:11   0:00              \_ grep --color=auto sshd.

2. Sehen Sie sich Systemaufrufe mit dem Befehl strace auf der PID an

Die Implementierung in der Shell ist der folgende Teil.

strace -e read -s16384 -q -xx -p ${pid} 2>&1

Wir verwenden strace, um einen Lesesystemaufruf durchzuführen, der von der PID ausgegeben wird, die mit dem zuvor erhaltenen tty verknüpft ist. Bekommen Da verschiedene andere Systemaufrufe als der gelesene Systemaufruf aufgerufen werden, wird nur der gelesene Systemaufruf mit der Option "-e read" von strace extrahiert.

Der gelesene Systemaufruf war der unten definierte Systemaufruf. Die Ergebnisse, die mit strace erhalten werden können, sind auch wie folgt.

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);

Angenommen, Sie geben den folgenden Befehl im Terminal aus, auf das verwiesen wird.

[tsuji@localhost gomi]$ hoge
bash: hoge:Befehl nicht gefunden...
[tsuji@localhost gomi]$

Wenn Sie zu diesem Zeitpunkt mit strace -p $ {PID} -e read auf den Aufruf des Lesesystems verweisen, wird die folgende Ausgabe ausgegeben.

[root@localhost ttycopy]# strace -p 14959 -e read
strace: Process 14959 attached
read(3, "\0\0\0\20\356\202\375C&&\357q\276\210pZ)\300\26M\357T\313\303k\6p\232\351\263\32\224"..., 16384) = 36
read(11, "h", 16384)                    = 1
read(3, "\0\0\0\20\235\230\204Ud\36)\370\266\233\362\305\2219\253g\335M\23\212\374h\250i@\235/\216"..., 16384) = 36
read(11, "o", 16384)                    = 1
read(3, "\0\0\0\20\324\357\304\vn\357BbW\241m\220yS\236\362\301\337\337\237c\203\245\223\221\253;,"..., 16384) = 36
read(11, "g", 16384)                    = 1
read(3, "\0\0\0\20\344\215\235\300\226\236\0\323\376\r\217,\257\322\326w\323R\264\3}\266\7q\315\215\344\346"..., 16384) = 36
read(11, "e", 16384)                    = 1
read(3, "\0\0\0\20^``\333\263h\372Z\336\335Y2\250\203\335\221\372faj\177\260f\302Sb\35\354"..., 16384) = 36
read(11, "\r\n", 16384)                 = 2
read(11, "bash: hoge: \343\202\263\343\203\236\343\203\263\343\203\211\343\201\214\350\246\213\343\201"..., 16384) = 62
read(11, "\33]0;tsuji@localhost:~/gomi\7[tsuj"..., 16384) = 51
^Cstrace: Process 14959 detached

Im obigen Beispiel werden die Zeichenfolgen "strace: Prozess 14959 angehängt" und "strace: Prozess 14959 getrennt" angezeigt, aber die strace-Option "-q" wird verwendet, um diese Ausgabe zu unterdrücken. Wir verwenden auch die Option -x, um die Zeichenfolge zur einfacheren Anzeige in hexadezimal zu konvertieren.

3. Formatieren und Anzeigen der von strace ausgegebenen gelesenen Systemaufrufzeichenfolge

Ziel ist es, den Inhalt des zweiten Arguments des in Schritt 2 erhaltenen Lesesystemaufrufs anzuzeigen. Die Implementierung in der Shell ist wie folgt.

sed -une "s/^read([0-9]\+, \"\(.*\)\".*/echo -n \$'\1'/p" | bash

Die erste Hälfte ist "sed -une" s / ^ read ([0-9] \ +, "\ (. * )". * / Echo -n \ $ '\ 1' / p "". Der Ausdruck erfasst das zweite Argument des Aufrufs des Lesesystems und gibt ihm die Zeichenfolgen "echo -n" und "$", sodass Sie eine Zeichenfolge wie die folgende erhalten können:

[tsuji@localhost gomi]$ cat hoge
hoge
[tsuji@localhost gomi]$

--Terminale Zeichenkettenausgabe nach Verarbeitung durch Strace

echo -n $'\x00\x00\x00\x10\xc6\x1e\x56\xc6\x1f\x11\x7e\x57\x11\xaf\xdb\x2a\x91\x32\x84\x8e\x6e\x5b\x12\xc1\x72\x94\x36\x17\x12\xbb\x7c\xab\x4b\xdd\x19\x33'
echo -n $'c'
echo -n $'\x00\x00\x00\x10\x5d\x68\x72\x7c\x74\xca\x3c\xd1\x57\xfc\x14\x7d\x55\x34\x66\x15\x03\xcb\x26\x7c\x17\xbc\x7f\x7a\xf5\x25\x40\xed\xa8\x21\x39\xb3'
echo -n $'a'
echo -n $'\x00\x00\x00\x10\x05\x3d\x4a\xc2\x76\x1c\xd4\x23\x2a\x17\xc6\xa1\x1c\xf2\xdb\x14\x75\x1c\x7d\xb7\x21\xfb\xfc\xcd\x2d\x5c\xef\x06\x6c\x97\x01\x28'
echo -n $'t'
echo -n $'\x00\x00\x00\x10\x66\xb0\x8c\x40\x10\xa6\xf3\x9b\x36\x75\xd5\xc1\x65\x63\x94\x4f\x77\xd9\x10\x6d\xcf\xbb\x48\xed\x8b\x43\x58\x20\x54\x08\xde\x9b'
echo -n $' '
echo -n $'\x00\x00\x00\x10\x60\x6e\xb6\x06\x43\x16\xf5\x75\x89\x90\xb6\x42\x2c\xfe\x8b\x97\xae\xad\x47\x26\xf9\x39\xfc\xd2\x84\x37\xde\x0d\xe5\x32\xbc\x80'
echo -n $'h'
echo -n $'\x00\x00\x00\x10\x00\xe4\x3d\xb7\xd9\x79\x2e\x46\x80\xd5\xa5\xc2\xa7\x9a\xc7\x0c\xe1\x58\x7b\xd5\x97\xff\x00\xab\x72\x51\xa4\xbb\xab\x7d\xd1\xaf'
echo -n $'o'
echo -n $'\x00\x00\x00\x10\xf8\x1d\xce\xe6\x7f\x1a\x43\x94\xa2\xde\x3d\x3c\xb5\xe9\xb9\x94\x39\x43\x63\xfd\xa9\x1f\x45\x83\x64\x5c\x3a\xdf\xa8\x1a\xa4\x86'
echo -n $'g'
echo -n $'\x00\x00\x00\x10\x90\x69\x42\xa9\x48\x99\x0c\x52\xe9\x49\xbd\x4e\xa5\x17\x01\xff\xac\xec\x29\x75\x2c\xc0\x2b\x7c\x07\x85\xf2\x2f\xce\x71\x8f\x46'
echo -n $'e'
echo -n $'\x00\x00\x00\x10\xd9\x91\x38\x08\x0b\x95\x78\xd4\x80\x51\xa2\xe8\xef\x20\x06\x45\xa9\x3c\xf0\xa3\x10\x7d\x06\x32\x2d\x31\x53\x57\x40\x77\x1b\x29'
echo -n $'\r\n'
echo -n $'\x68\x6f\x67\x65\x0d\x0a\x1b\x5d\x30\x3b\x74\x73\x75\x6a\x69\x40\x6c\x6f\x63\x61\x6c\x68\x6f\x73\x74\x3a\x7e\x2f\x67\x6f\x6d\x69\x07'
echo -n $'[tsuji@localhost gomi]$ '

Die -n Option von echo -n dient dazu, Unterbrechungen beim Dolmetschen zu vermeiden. Das Bash-Format "$" hat folgende Auswirkungen: Auszug aus der Manpage. [^ 2]

Wörter der Form $ 'string' werden speziell behandelt. Dieses Wort wird zu Zeichenfolge erweitert und dann durch das Zeichen ersetzt, das mit einem Backslash versehen ist, wie im ANSI C-Standard angegeben. Die Backslash-Escape-Sequenz wird (falls vorhanden) wie folgt dekodiert:

Auf diese Weise ist es möglich, die Bedeutung der Zeichenfolge zu erweitern.

Danach können Sie die Zeichenfolge anzeigen, indem Sie die Shell die Zeichenfolge von "echo" mit "| bash" interpretieren lassen.

Zusammenfassung

Ich konnte das Terminal beiläufig freigeben, indem ich die Zeichenfolge des Arguments des Aufrufs des Lesesystems mit strace abrief und in Echtzeit wiederherstellte. Ich denke, es ist ein Lehrmittel, weil Sie die Arbeit anderer Menschen in Echtzeit sehen können. Wenn Sie das Terminal hacken möchten, verwenden Sie es bitte.

Wenn Sie möchten, können Sie sich motivieren lassen, indem Sie ttycopy einen Stern hinzufügen: v:

Recommended Posts

Wie man ein Terminal hackt
So rufen Sie eine Funktion auf
Wie man einen lockeren Bot macht
So erstellen Sie ein Conda-Paket
Wie erstelle ich einen Crawler?
So erstellen Sie eine rekursive Funktion
So erstellen Sie eine virtuelle Brücke
Wie erstelle ich eine Docker-Datei?
[Blender] So erstellen Sie ein Blender-Plug-In
So löschen Sie einen Docker-Container
Wie erstelle ich einen Crawler?
So erstellen Sie eine Konfigurationsdatei
So erstellen Sie einen Klon aus Github
So teilen und speichern Sie einen DataFrame
So erstellen Sie eine Sphinx-Übersetzungsumgebung
So erstellen Sie einen Git-Klonordner
Qiita (1) Wie schreibe ich einen Codenamen?
So fügen Sie ein Paket mit PyCharm hinzu
[Python] Wie man eine Klasse iterierbar macht
So zeichnen Sie ein Diagramm mit Matplotlib
[Python] So konvertieren Sie eine zweidimensionale Liste in eine eindimensionale Liste
[Colab] So kopieren Sie einen riesigen Datensatz
[Python] So invertieren Sie eine Zeichenfolge
So installieren Sie ein Paket mithilfe eines Repositorys
Wie bekomme ich Stacktrace in Python?
So erstellen Sie ein Repository aus Medien
So erstellen Sie einen benutzerdefinierten Backtrader-Indikator
So wählen Sie eine Seaborn-Farbpalette aus
So testen Sie auf einer von Django authentifizierten Seite
Wie erstelle ich eine Pelican Site Map?
So führen Sie Maya Python-Skripte aus
Wie man ein Dialogsystem für Anfänger erstellt
So berechnen Sie die Volatilität einer Marke
Lesen einer CSV-Datei mit Python 2/3
Freigeben einer virtuellen Umgebung [Informationen zu den Anforderungen.txt]
So senden Sie eine Nachricht mit Curl an LINE
So codieren Sie eine Drohne mithilfe der Bilderkennung
So öffnen Sie einen Webbrowser über Python
So löschen Sie einen Taple in einer Liste (Python)
Wie man einen Wettbewerb bei Coda Lab abhält
So zeichnen Sie ein 2-Achsen-Diagramm mit Pyplot
Einbetten von Variablen in Python-Strings
So erstellen Sie ein Funktionsobjekt aus einer Zeichenfolge
So zeichnen Sie vor der Optimierung ein 3D-Diagramm
So erstellen Sie eine JSON-Datei in Python
So erstellen Sie ein Wörterbuch mit einer hierarchischen Struktur.
So generieren Sie ein Python-Objekt aus JSON
So stellen Sie eine Streamlit-Anwendung für GCP (GAE) bereit
So implementieren Sie eine Verlaufsauswahl in Houdini
So fügen Sie einen Suchpfad für Python-Module hinzu
So erstellen Sie ein QGIS-Plug-In (Paketerzeugung)
So extrahieren Sie den Koeffizienten aus der Minutenformel
So schreiben Sie einen ShellScript Bash für Anweisung
Wie man sich erinnert, wenn man ein Wort vergisst
So messen Sie die Leitungsgeschwindigkeit vom Terminal aus
So benachrichtigen Sie Discord-Kanäle in Python