SSH: Tunneln erlauben, Kommandos ausführen verbieten

Alle weiteren Dienste, die nicht in die drei oberen Foren gehören.
Antworten
Benutzeravatar
XCooperation
Beiträge: 78
Registriert: 01.06.2005 15:05:37
Wohnort: Schrobenhausen
Kontaktdaten:

SSH: Tunneln erlauben, Kommandos ausführen verbieten

Beitrag von XCooperation » 13.07.2007 17:54:09

Hallo,
ich hab das gleiche Problem wie hier:
http://www.debianforum.de/forum/viewtop ... el&start=0

Ich möchte bestimmten Usern erlauben, einen Tunnel über SSH zu benützen, allerdings möchte ich nicht, dass sie irgendwelche Befehle ausführen können.
Die User sollten PuTTY unter Windows benützen können, plink will ich nicht einsetzen.
/bin/false als Shell funktioniert ja leider nicht.

Kann ich stattdessen einfach ein Programm schreiben, das ungefähr so aussieht:

Code: Alles auswählen

void main()
{
  cout << "You are not allowed to execute any commands!" <<endl;
  while(true) { cin.get(); }
}
Und dann einfach dieses Programm als Shell für die User angeben.
Geht das und ist das sicher?
Never trust a running system!
http://www.xenesis.net

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Beitrag von cosmac » 13.07.2007 18:19:36

hi,

bei Etch ist sowas schon fertig dabei: /usr/sbin/nologin.
Das wird in /etc/passwd statt der shell eingetragen und gut ist.
'man 8 nologin' hat geschrieben:nologin - politely refuse a login
:)
Beware of programmers who carry screwdrivers.

Benutzeravatar
XCooperation
Beiträge: 78
Registriert: 01.06.2005 15:05:37
Wohnort: Schrobenhausen
Kontaktdaten:

Beitrag von XCooperation » 13.07.2007 18:36:24

Nein, das funktioniert nicht.

Der unterschied zum obigen ist folgender: nologin wird sofort nach der Meldung beendet und loggt damit den user wieder aus => Tunneling ist nicht möglich
Never trust a running system!
http://www.xenesis.net

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Beitrag von cosmac » 13.07.2007 21:42:02

o.k., nächster Versuch: wenn man keine Anmeldung per Passwort braucht,
kann man in das AuthorizedKeysFile auf dem Server die Option "no-pty"
und/oder command="command" reinschreiben. Die Zeile mit dem Public
Key beginnt dann z.B. so:

Code: Alles auswählen

no-pty ssh-dss AAAAB3NzaC1kc...
Beware of programmers who carry screwdrivers.

Benutzeravatar
XCooperation
Beiträge: 78
Registriert: 01.06.2005 15:05:37
Wohnort: Schrobenhausen
Kontaktdaten:

Beitrag von XCooperation » 14.07.2007 11:34:04

Ja, das wäre auch eine Lösung. Allerdings muss ich dafür dann einen SSH Key für den User erstellen. Sich ohne den Key anzumelden ginge ja dann nicht mehr, oder?
Ich möchte gerne eine Anmeldung nur mit Usernamen und Passwort.

Wie auch immer, meine Idee mit dem obigen Code scheint zufunktionieren, ich weiß nur nicht ob das jetzt wirklich sicher ist ;).
Never trust a running system!
http://www.xenesis.net

Benutzeravatar
Tintom
Moderator
Beiträge: 3069
Registriert: 14.04.2006 20:55:15
Wohnort: Göttingen

Beitrag von Tintom » 14.07.2007 12:45:39

Wie wäre es denn, wenn man $PATH in der jeweiligen .bashrc gegen /dev/null linkt ?
Ich hab das gerade getestet und kann mich per ssh einloggen aber nichts ausführen.

Gruß

Tino

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Beitrag von cosmac » 14.07.2007 14:52:59

moin, moin,

die Idee mit PATH=/dev/null ist ja spassig, hat aber meinem Angriff nichtmal
1 Minute standgehalten. Die internen Befehle der bash funktionieren ja noch:

Code: Alles auswählen

export PATH=/usr/bin:/bin
bringt mich schon ein ganzes Stück weiter ;)

Zum Vergleich: die Endlos-Schleife als Login-Shell aus dem OP ist nach einer
Stunde immernoch nicht geknackt. Was aber überhaupt nicht heißt, daß es
sicher ist
, ich bin ja nur Hobby-Cracker im 1. Lehrjahr ;)

Immerhin reicht es schon für einen DOS-Angriff: Wenn man versucht, einen
Befehl auf dem Server ausführen zu lassen kann man mit CTRL-C die Verbindung
beenden, das Programm läuft aber weiter und verbraucht alle übrige CPU-Zeit.
Wenn man das 42 Mal macht, bremst das den Server doch etwas.
Beware of programmers who carry screwdrivers.

Benutzeravatar
Tintom
Moderator
Beiträge: 3069
Registriert: 14.04.2006 20:55:15
Wohnort: Göttingen

Beitrag von Tintom » 14.07.2007 15:06:23

cosmac hat geschrieben:moin, moin,

die Idee mit PATH=/dev/null ist ja spassig, hat aber meinem Angriff nichtmal
1 Minute standgehalten. Die internen Befehle der bash funktionieren ja noch:

Code: Alles auswählen

export PATH=/usr/bin:/bin
bringt mich schon ein ganzes Stück weiter ;)
Zugegeben, ich hab an das Gute im Anwender geglaubt als ich das geschrieben habe. :wink:

Benutzeravatar
XCooperation
Beiträge: 78
Registriert: 01.06.2005 15:05:37
Wohnort: Schrobenhausen
Kontaktdaten:

Beitrag von XCooperation » 14.07.2007 15:29:28

Immerhin reicht es schon für einen DOS-Angriff: Wenn man versucht, einen
Befehl auf dem Server ausführen zu lassen kann man mit CTRL-C die Verbindung
beenden, das Programm läuft aber weiter und verbraucht alle übrige CPU-Zeit.
Wenn man das 42 Mal macht, bremst das den Server doch etwas.
Hm, ich denke das funktioniert nicht. Wenn du CTRL-C drückst wird das Programm doch beendet, oder?
Außerdem gibt es ja in meinem obigen Programm keine Endlosschleife:
Das Programm wartet ja mit

Code: Alles auswählen

cin.get();
auf irgendeine Eingabe vom User. Damit wird das Programm in einen Wartezustand versetzt und verbraucht keine Ressourcen.
So hab ich mir das zumindestens gedacht ;)
Never trust a running system!
http://www.xenesis.net

Benutzeravatar
XCooperation
Beiträge: 78
Registriert: 01.06.2005 15:05:37
Wohnort: Schrobenhausen
Kontaktdaten:

Beitrag von XCooperation » 14.07.2007 15:42:02

Ok, also ich hab folgenden Code genommen:

Code: Alles auswählen

/* nocommands.cpp */

#include <string>
#include <iostream>

using namespace std;

int main()
{
	cout << "Sorry, you are not allowed to execute any commands!" <<endl;
	cout << "Enter \"exit\" to logout." <<endl;
	
	string command;
	while(true)
	{
		cin >> command;
		if(command == "exit")
		{
			cout << "Goodbye!" <<endl;
			exit(0);
		}
	}
}
Und überprüft:
Via PuTTY hab ich mich als "proxyuser" angemeldet. Meine Shell kam wie erwartet.
Dann hab ich als erstes als root an meiner Linuxmaschine "users" eingegeben:

Code: Alles auswählen

proxyuser root
Und dann "ps -A | gep nocommands": Ergebnis: Prozess existiert.

Dann hab ich in PuTTY CTRL-C gedrückt: Ergebnis: Session beendet (also anscheinend Logout)
Wieder die gleiche Prozedur wie oben an der Linux Maschine:
Ergebnis: Einziger eingeloggter User ist root und nocommands wurde beendet.
Ein DoS dürfte also nicht möglich sein
Never trust a running system!
http://www.xenesis.net

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Beitrag von cosmac » 14.07.2007 16:08:44

o.k., normal wird nocammnds mit CTRL-C beendet und alles ist gut, aber...

Ich hab hier gerade kein Windows mit Putty, aber das dürfte genauso
funktionieren. Ich hab's auf Etch so provoziert:

Code: Alles auswählen

ssh proxyuser@localhost /bin/unfug
also dem sshd gesagt, es soll auf dem Server "/bin/unfug" ausgeführt werden.
Das gibt's natürlich nicht, aber das ist auch egal. Nach dem CTRL-C bleibt ein
Prozess "nocommands -c /bin/unfug" übrig.

"Endlosschleife" hab ich wohl zu zweideutig benutzt...

Code: Alles auswählen

while (true) { warte_auf_irgendwas(); }
also wenn das keine Endlosschleife ist ;)
natürlich braucht die keine CPU-Zeit.

Die zweite ist die eigentlich üble, und ich weiß nicht wieso:
"nocommands -c /bin/unfug".

Die erste Version von nocommands hat mit übrigens besser gefallen,
je weniger Programm, umso weniger Angriffsfläche.
Beware of programmers who carry screwdrivers.

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Beitrag von cosmac » 14.07.2007 16:30:59

Meloneneis regelt! 2 Kugeln später:

nocommands erwischt das EndOfFile auf stdin, cin() wartet dann nicht mehr,
wird aber immer wieder aufgerufen. Da fehlt ein "while (!feof (stdin))".
Beware of programmers who carry screwdrivers.

Benutzeravatar
XCooperation
Beiträge: 78
Registriert: 01.06.2005 15:05:37
Wohnort: Schrobenhausen
Kontaktdaten:

Beitrag von XCooperation » 15.07.2007 12:25:55

Ok, hier dann nochmal die überarbeitete Version:

Code: Alles auswählen

#include <string>
#include <iostream>

using namespace std;

int main()
{
	cout << "Sorry, you are not allowed to execute any commands!" <<endl;
	cout << "Enter \"exit\" to logout." <<endl;
	
	string command;
	while(! (cin.eof() || cin.fail()) )
	{
		cin >> command;
		if(command == "exit")
		{
			cout << "Goodbye!" <<endl;
			exit(0);
		}
	}

	cout << "Unfriendly exit!" <<endl;
	exit(0);
}
Hm, ob jetzt

Code: Alles auswählen

cin >> command;
eine Sicherheitslücke ist?
Naja, theoretisch könnte ich ja mal sagen wir so 1GB an Daten in ssh eingeben und dann Enter drücken. Dadurch wird dann 1GB an Daten in command eingelesen und es dürfte PENG machen. Auch wieder ein DoS. In der Beziehung ist cin wohl doch nicht die ideale Lösung.
Never trust a running system!
http://www.xenesis.net

Benutzeravatar
XCooperation
Beiträge: 78
Registriert: 01.06.2005 15:05:37
Wohnort: Schrobenhausen
Kontaktdaten:

Beitrag von XCooperation » 15.07.2007 12:36:18

So, mit dem hier dürfte es dann wirklich sicher sein:

Code: Alles auswählen

#include <iostream>

using namespace std;

int main()
{
	cout << "Sorry, you are not allowed to execute any commands!" <<endl;
	cout << "Press CTRL+D to log out" <<endl;
	
	char buffer[512];
	
	while(! (cin.eof() || cin.fail()) )
	{
		cin.read(buffer,512); //just wait
	}

	cout << "Goodbye!" <<endl;
	exit(0);
}
Als erstes habe ich wie vorgeschlagen das Beenden mit exit entfernt und durch ein drücken von STRG+D ersetzt. Das erzeugt nämlich ein EOF Zeichen und sollte die Schleife beenden.
Dann liest cin nicht mehr die ganze Zeile, sondern nur noch 512 Bytes. Damit sollte ein DoS nicht mehr möglich sein. (Naja, mit ner endlos schnellen Verbindung kann man nocommands natürlich auch noch in den wahnsinn treiben, aber da könnte man ja die Größe des Puffers nochmal anpassen)
Never trust a running system!
http://www.xenesis.net

adducy
Beiträge: 1
Registriert: 14.08.2007 14:24:52

Beitrag von adducy » 14.08.2007 14:26:57

Du kannst per authorized_keys auch sagen welches kommando bei einem login ausgeführt werden soll. ssh führt dann das kommando aus und schliesst die verbindung wieder. es ist nicht moeglich andere befehle einzugeben

http://blog.trouper.de/blog.cgi?id=24

Benutzeravatar
AK-Palme
Beiträge: 411
Registriert: 25.05.2004 15:38:30
Kontaktdaten:

Beitrag von AK-Palme » 14.08.2007 15:32:31

viellecht funktioniert scponly ja auch.. Wär ein Versuch wert

nil
Beiträge: 989
Registriert: 08.06.2005 13:28:36

Beitrag von nil » 14.08.2007 15:42:09

Ich habe es mal probiert. SSH-Port-Forwarding funktioniert bei "scponly" und einer entsprechenden chroot-Umgebung.

Benutzeravatar
HZB
Beiträge: 490
Registriert: 22.10.2003 11:52:15
Wohnort: Wien

Beitrag von HZB » 14.08.2007 16:34:49

Sorry wenn es vielleicht OT ist, aber wozu benötigst Du einen Deinen SSH Tunnel ?

Antworten