Kann ein Benutzer ohne Rootberechtigung unter Ubuntu einen Chroot-Prozess ausführen?
Kann ein Benutzer ohne Rootberechtigung unter Ubuntu einen Chroot-Prozess ausführen?
Antworten:
Unter Linux kann der Systemaufruf chroot (2) nur von einem privilegierten Prozess ausgeführt werden. Die Fähigkeit, die der Prozess benötigt, ist CAP_SYS_CHROOT.
Der Grund, warum Sie als Benutzer nicht chroot können, ist ziemlich einfach. Angenommen, Sie haben ein Setuid-Programm wie sudo, das prüft, ob Sie etwas tun dürfen. Legen Sie es jetzt in eine Chroot-Chroot mit Ihren eigenen / etc / sudoers. Plötzlich haben Sie eine sofortige Privilegieneskalation.
Es ist möglich, ein Programm so zu entwerfen, dass es sich selbst in der Chroot-Umgebung befindet und als Setuid-Prozess ausgeführt wird. Dies wird jedoch im Allgemeinen als schlechtes Design angesehen. Die zusätzliche Sicherheit der Chroot motiviert die Sicherheitsprobleme mit der Setuid nicht.
chroot
dann auszuführen .
@ imz - IvanZakharyaschev kommentiert die Antwort von pehrs, dass es mit der Einführung von Namespaces möglich sein könnte, aber dies wurde nicht getestet und als Antwort veröffentlicht. Ja, das ermöglicht es in der Tat einem Nicht-Root-Benutzer, chroot zu verwenden.
Bei einer statisch verknüpften dash
und einer statisch verknüpften busybox
und einer ausgeführten bash
Shell, die als Nicht-Root ausgeführt wird:
$ mkdir root
$ cp /path/to/dash root
$ cp /path/to/busybox root
$ unshare -r bash -c 'chroot root /dash -c "/busybox ls -al /"'
total 2700
drwxr-xr-x 2 0 0 4096 Dec 2 19:16 .
drwxr-xr-x 2 0 0 4096 Dec 2 19:16 ..
drwxr-xr-x 1 0 0 1905240 Dec 2 19:15 busybox
drwxr-xr-x 1 0 0 847704 Dec 2 19:15 dash
Die Root - Benutzer - ID in diesem Namespace wird auf die Nicht-Root - Benutzer - ID außerhalb dieses Namensraumes abgebildet, und umgekehrt, weshalb die System zeigt Dateien , die von dem aktuellen Benutzer gehören , wie durch Benutzer - ID 0. Ein regelmäßigen Besitz ls -al root
, ohne unshare
, tun Zeigen Sie sie als Eigentum des aktuellen Benutzers an.
Hinweis: Es ist bekannt, dass Prozesse, die in der Lage sind, zu verwenden chroot
, in der Lage sind, aus a auszubrechen chroot
. Da einem normalen Benutzer Berechtigungen erteilt unshare -r
würden chroot
, wäre dies ein Sicherheitsrisiko, wenn dies in einer chroot
Umgebung zulässig wäre . In der Tat ist es nicht erlaubt und scheitert mit:
Freigabe aufheben: Freigabe fehlgeschlagen: Vorgang nicht zulässig
welche mit der Dokumentation von unshare (2) übereinstimmt :
EPERM (seit Linux 3.9)
CLONE_NEWUSER wurde in Flags angegeben und der Aufrufer befindet sich in einer Chroot-Umgebung (dh das Stammverzeichnis des Aufrufers stimmt nicht mit dem Stammverzeichnis des Mount-Namespaces überein, in dem er sich befindet).
In diesen Tagen möchten Sie sich mit LXC (Linux Containers) anstatt mit chroot / BSD befassen. Es liegt irgendwo zwischen einer Chroot und einer virtuellen Maschine und bietet Ihnen viel Sicherheitskontrolle und allgemeine Konfigurierbarkeit. Ich glaube, Sie müssen nur Mitglied der Gruppe sein, die die erforderlichen Dateien / Geräte besitzt. Möglicherweise sind jedoch auch Funktionen / Systemberechtigungen erforderlich. Auf jeden Fall sollte es sehr machbar sein, da LXC ziemlich neu ist, lange nachdem SELinux etc. zum Linux-Kernel hinzugefügt wurde.
Denken Sie auch daran, dass Sie Skripte nur als root schreiben können, den Benutzern jedoch die sichere Berechtigung erteilen, diese Skripte mit sudo auszuführen (wenn Sie möchten, müssen Sie jedoch sicherstellen, dass das Skript sicher ist).
Die Kombination von fakeroot / fakechroot ergibt eine Chroot-Simulation für einfache Anforderungen wie das Erstellen von Tar-Archiven, bei denen Dateien anscheinend Eigentum von root zu sein scheinen. Fakechroot-Manpage ist http://linux.die.net/man/1/fakechroot .
Sie erhalten zwar keine neue Berechtigung, aber wenn Sie ein Verzeichnis besitzen (z. B. Fake-Distribution), bevor Sie es aufrufen
fakechroot fakeroot chroot ~/fake-distro some-command
Es sieht jetzt so aus, als ob Sie root sind und alles in der gefälschten Distribution besitzen.
~/fake-distro
benutzt busybox, welche symlinks ls
, mv
und andere gängige Dienstprogramme dazu /bin/busybox
. Wenn ich explizit anrufe /bin/busybox mv ...
, funktionieren die Dinge, aber wenn ich anrufe, /bin/mv ...
bekomme ich sh: /bin/mv: not found
. Die Einstellung export FAKECHROOT_EXCLUDE_PATH=/
vor dem Ausführen von fakechroot behebt dieses Symptom, bricht dann jedoch bei anderen Symlinks (z /usr/bin/vim -> /usr/bin/vim.vim
. B. ) ab.
Es scheint, dass es mit Benutzernamensräumen tatsächlich möglich ist, ohne root zu chrooten. Hier ist ein Beispielprogramm, das zeigt, dass es möglich ist. Ich habe erst begonnen zu untersuchen, wie Linux-Namespaces funktionieren, und bin mir daher nicht ganz sicher, ob dieser Code die beste Vorgehensweise ist oder nicht.
Speichern unter user_chroot.cc
. Kompilieren mit g++ -o user_chroot user_chroot.cc
. Verwendung ist ./user_chroot /path/to/new_rootfs
.
// references:
// [1]: http://man7.org/linux/man-pages/man7/user_namespaces.7.html
// [2]: http://man7.org/linux/man-pages/man2/unshare.2.html
#include <sched.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cerrno>
#include <cstdio>
#include <cstring>
int main(int argc, char** argv) {
if(argc < 2) {
printf("Usage: %s <rootfs>\n", argv[0]);
}
int uid = getuid();
int gid = getgid();
printf("Before unshare, uid=%d, gid=%d\n", uid, gid);
// First, unshare the user namespace and assume admin capability in the
// new namespace
int err = unshare(CLONE_NEWUSER);
if(err) {
printf("Failed to unshare user namespace\n");
return 1;
}
// write a uid/gid map
char file_path_buf[100];
int pid = getpid();
printf("My pid: %d\n", pid);
sprintf(file_path_buf, "/proc/%d/uid_map", pid);
int fd = open(file_path_buf, O_WRONLY);
if(fd == -1) {
printf("Failed to open %s for write [%d] %s\n", file_path_buf, errno,
strerror(errno));
} else {
printf("Writing : %s (fd=%d)\n", file_path_buf, fd);
err = dprintf(fd, "%d %d 1\n", uid, uid);
if(err == -1) {
printf("Failed to write contents [%d]: %s\n", errno,
strerror(errno));
}
close(fd);
}
sprintf(file_path_buf, "/proc/%d/setgroups", pid);
fd = open(file_path_buf, O_WRONLY);
if(fd == -1) {
printf("Failed to open %s for write [%d] %s\n", file_path_buf, errno,
strerror(errno));
} else {
dprintf(fd, "deny\n");
close(fd);
}
sprintf(file_path_buf, "/proc/%d/gid_map", pid);
fd = open(file_path_buf, O_WRONLY);
if(fd == -1) {
printf("Failed to open %s for write [%d] %s\n", file_path_buf, errno,
strerror(errno));
} else {
printf("Writing : %s (fd=%d)\n", file_path_buf, fd);
err = dprintf(fd, "%d %d 1\n", gid, gid);
if(err == -1) {
printf("Failed to write contents [%d]: %s\n", errno,
strerror(errno));
}
close(fd);
}
// Now chroot into the desired directory
err = chroot(argv[1]);
if(err) {
printf("Failed to chroot\n");
return 1;
}
// Now drop admin in our namespace
err = setresuid(uid, uid, uid);
if(err) {
printf("Failed to set uid\n");
}
err = setresgid(gid, gid, gid);
if(err) {
printf("Failed to set gid\n");
}
// and start a shell
char argv0[] = "bash";
char* new_argv[] = {
argv0,
NULL
};
err = execvp("/bin/bash", new_argv);
if(err) {
perror("Failed to start shell");
return -1;
}
}
Ich habe dies auf einem minimalen rootfs getestet, das mit multistrap erzeugt wurde (ausgeführt als Nicht-root). Einige Systemdateien mögen /etc/passwd
und /etc/groups
wurden von den Host-Rootfs in die Gast-Rootfs kopiert.
Failed to unshare user namespace
mir unter Linux 4.12.10 (Arch Linux).
unshare
Anruf resultieren können . Sie können auch diese Python - Version versuchen , die besser Störmeldeversand haben könnte: github.com/cheshirekow/uchroot
Nein. Wenn ich mich richtig erinnere, gibt es eine Kernel-Level-Sache, die Chroot tut, um dies zu verhindern. Ich kann mich nicht erinnern, was das für ein Ding war. Ich habe es untersucht, als ich mit Gentoos Catalyst Build-Tool rumgespielt habe (und ein Chroot unter Gentoo ist dasselbe wie ein Chroot unter Ubuntu). Es wäre zwar möglich, dies ohne ein Passwort zu erreichen ... aber solche Dinge sind dem Bereich potenzieller Sicherheitslücken überlassen und stellen sicher, dass Sie wissen, was Sie tun.