Schreiben Sie in einen Socket, der von einem anderen Prozess unter Linux geöffnet wurde

9

Ist es unter Linux möglich, dass ein Prozess in einen Socket schreibt, der von einem anderen geöffnet wurde?

Angenommen, ich öffne mit netcat eine Verbindung zu google.com:

myuser@linux:~$ nc google.com 80

Jetzt kann ich nach der Prozess-PID suchen und ihren Dateideskriptor-Ordner öffnen:

myuser@linux:~$ ls -la /proc/24105/fd
totale 0
dr-x------ 2 myuser myuser  0 2012-03-10 19:01 .
dr-xr-xr-x 7 myuser myuser  0 2012-03-10 19:01 ..
lrwx------ 1 myuser myuser 64 2012-03-10 19:02 0 -> /dev/pts/12
lrwx------ 1 myuser myuser 64 2012-03-10 19:02 1 -> /dev/pts/12
lrwx------ 1 myuser myuser 64 2012-03-10 19:01 2 -> /dev/pts/12
lrwx------ 1 myuser myuser 64 2012-03-10 19:02 3 -> socket:[3947162]

Jetzt möchte ich die HTTP-Anfrage mit einem Echo in diesem Socket stellen:

myuser@linux:~$ echo "GET / HTTP/1.1" >> /proc/24285/fd/3
bash: /proc/24285/fd/3: no such device or address

Wenn Sie es als root tun, ändert sich das Ergebnis nicht.

Ich kann nicht in den Socket schreiben, aber ich kann in den Standard schreiben:

myuser@linux:~$ echo "GET / HTTP/1.1" >> /proc/24285/fd/0
myuser@linux:~$

Aber es ist nicht das, was ich tun möchte.

Ich dachte: Ein Linux-Socket sollte wie eine Datei behandelt werden, nicht wahr? Ein oder mehrere Prozesse können denselben Socket verwenden. Warum kann ich das nicht tun?

otaku22
quelle
Es sieht nicht so aus, als wäre es möglich. Erstens ist dies ein Socket, kein Fifo, so dass Sie nicht einfach wie eine normale Datei darauf zurückgreifen können. nckann dies tun, aber wenn Sie dies versuchen, wird "Transportendpunkt ist nicht verbunden" angezeigt. Beispiel Befehlnc -v --send-only -U /proc/123/fd/3 <<< 'GET /'$'\n\n'
Patrick
Was? Warum sollte ich die Option -U (Unix-Socket) verwenden? Übrigens kann ich nicht verstehen, wie es nützlich sein kann
otaku22
1
Ich habe mit gdb eine schlechte Problemumgehung gefunden: gdb -p 24285und dann kann ich mit in den Dateideskriptor schreiben call write(3, "test",4). Es funktioniert, aber ich möchte das Gleiche aus dem Prozess heraus tun, da die Verwendung von gdb das Stoppen des Prozesses erfordert (
wodurch

Antworten:

5

Dies ist nicht möglich, da es schwierig zu implementieren und selten nützlich wäre. Muffen sind viel komplexer als Rohre:

  • Steckdosen sind bidirektional.
  • Es gibt verschiedene Arten von Steckdosen. Einige Sockets sind keine Byte-Streams (z. B. UDP-Sockets sind Datagramm-Sockets, die Pakete und keine Bytes senden).
  • Sockets führen Multiplexing durch (und es gibt eine gewisse Überlastung zwischen Sockets, die von Servern verwendet werden, die auf Verbindungen warten, und Sockets, die von tatsächlich geöffneten Verbindungen verwendet werden).

Da Sockets bidirektional sind, werden sie häufig zur Kommunikation unter bidirektionalen Protokollen verwendet. Wenn Sie Daten in die Konversation einfügen, sendet die andere Seite möglicherweise eine Antwort auf Ihre Daten, und es gibt keine Möglichkeit, die Antwort an den richtigen Anforderer zu senden. Dies verringert die Nützlichkeit der Ermöglichung der Dateninjektion in Sockets erheblich.

Wenn Sie versuchen, denselben Server wie einen vorhandenen Client zu kontaktieren und keine vorhandene Konversation zu bearbeiten, gibt es bereits eine Möglichkeit, dies zu tun: Wenden Sie sich auf dieselbe Weise an den Server (öffnen Sie einen Socket im Dateisystem oder einen TCP oder UDP-Port). Wenn der Socket zwischen zwei Prozessen namenlos ist, ist dies ein guter Hinweis darauf, dass Sie nicht teilnehmen sollten, sodass das Betriebssystem es nicht einfach macht.

Mit einem Datagramm-Socket (hier nicht der Fall) konnten Sie keine Daten direkt einfügen, da die Shell nur Byteströme versteht und nicht weiß, ob sie aufruft, sendanstatt writeein Paket zu senden.

Wenn Sie mit einem Endpunkt zusammenarbeiten, können Sie festlegen, dass der Dateideskriptor 1 2 3 übergeben soll .

Andernfalls können Sie den Prozess, bei dem der Socket geöffnet ist, veranlassen, die Daten selbst mit zu senden ptrace(dies gdbwird unter der Haube verwendet). Dadurch wird der Prozess von Natur aus unterbrochen, sodass Ihre schmutzigen Tricks den Prozess nicht zu sehr verwirren. Selbst wenn der Prozess angehalten wird, besteht ein großes Risiko, dass die Datenstrukturen des Prozesses nicht mit der Realität der von Ihnen injizierten Daten- oder Umgebungsänderungen übereinstimmen. (Beachten Sie, dass selbst wenn das System das Einspeisen von Daten über einen Socket zulässt, ein ähnliches, wenn auch geringeres Risiko besteht, den Prozess mit diesen Inkonsistenzen zu verwechseln.)

Gilles 'SO - hör auf böse zu sein'
quelle
Klingt interessant: lxr.linux.no/linux+v3.2.11/net/socket.c#L146
otaku22
@ otaku22 Führend zu Theoretisch kann man diese Inode nicht öffnen, aber / proc bietet eine Hintertür. Denken Sie daran, es geschlossen zu halten, sonst lassen Sie die gruseligen Krabbeltiere herein. Meine Antwort zielt darauf ab zu zeigen, was diese gruseligen Krabbeltiere sind. Ich weiß nicht, ob es anderswo eine offiziellere oder vollständigere Präsentation gibt.
Gilles 'SO - hör auf böse zu sein'
1

Ich würde sagen, es ist möglich, aber beide Prozesse müssen zusammenarbeiten, um dies zu tun. Sie können von einem Prozess einen Dateideskriptor über eine Socket-Verbindung an einen anderen Prozess senden lassen. Ich habe dieses Beispiel gefunden, das auf einem aktuellen Arch Linux-Computer zu funktionieren scheint.

Bruce Ediger
quelle