Ubuntu - root olmayan kullanıcı chroot hapishanesinde işlem yapabilir mi?


18

Kök olmayan bir kullanıcının Ubuntu'da bir chroot işlemi çalıştırması mümkün mü?


Bu eski FreeBSD dizisi aynı soruyu kapsar: lists.freebsd.org/pipermail/freebsd-security/2003-April/… Kısa cevap: Hayır, kök olmayan bir kroke hapishanesinde kök olarak bir işlemi çalıştıramazsınız.
David Harrison

krom hapishaneleri BSD'ye özgüdür. Linux'ta bir aldatmaca hapishane değildir. Son kontrol ettiğimde kullanıcı olarak krootlama yapmak mümkün değildi.
xenoterracide

1
@xenoterracide Hapishaneler BSD'ye özgüdür, ancak chroot Linux topluluğunda "chroot jail" olarak bilinir. Oldukça karışık.
pehrs

2
Ne yapmaya çalışıyorsun ve neden? Fakechroot ve schroot gibi gereksinimlerinize bağlı olarak uygulanabilir bir alternatif sağlayan araçlar vardır.
Zoredache

Bir süreci kök olmadan nasıl "hapse atabilirim?" Konusunda daha fazla ilgili tartışma vardı. listelenen bu görevi çözmek için daha fazla çalışma veya belirsiz yaklaşımlarla.
imz - Ivan Zakharyaschev

Yanıtlar:


12

Linux'ta chroot (2) sistem çağrısı yalnızca ayrıcalıklı bir işlemle yapılabilir. Sürecin ihtiyacı olan yetenek CAP_SYS_CHROOT'tur.

Kullanıcı olarak oturum açamamanızın nedeni oldukça basittir. Sudo gibi bir setuid programınız olduğunu varsayalım. Şimdi kendi / etc / sudoer'larınızla birlikte bir kroke koyun. Aniden bir ayrıcalık yükselmesi yaşarsınız.

Kendini geliştirmek ve setuid işlemi olarak çalıştırmak için bir program tasarlamak mümkündür, ancak bu genellikle kötü tasarım olarak kabul edilir. Kökün ekstra güvenliği setuid ile ilgili güvenlik sorunlarını motive etmez.


3
Linux'taki ad alanlarının yeni olasılıkları ile , belki de "katıştırılmış" bir kök kullanıcısı olacak yeni bir "kullanıcı" ad alanı oluşturmak (paylaşmamak) ve bunu gerçekleştirmek mümkündür chroot.
imz - Ivan Zakharyaschev

1
@ imz - IvanZakharyaschev Kesinlikle haklısın ve umarım bunu kolayca test edilebilir bir cevap olarak yazmanın özgürlüğünü benim için umursamazsın.
DVD

@hvd Harika! Çok kullanışlı olmalı, çünkü yeni bilinmeyen Linux özelliklerinin somut komutlarla nasıl kullanılacağını gösteriyor.
imz - Ivan Zakharyaschev

6

@ imz - IvanZakharyaschev pehrs'in cevabını isim alanlarının girişiyle mümkün olabileceğini söyledi, ancak bu test edilmedi ve bir cevap olarak yayınlanmadı. Evet, bu aslında root olmayan bir kullanıcının chroot kullanmasını mümkün kılar.

Statik olarak bağlanmış dashve statik olarak bağlanmış busyboxve bashkök olmayan olarak çalışan bir çalışan kabuk verildiğinde :

$ 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

Bu ad alanında kök kullanıcı kimliği bu ad alanının kök olmayan kullanıcı kimliği dışarıya eşleştirilir ve kullanıcı kimliğine göre 0. Düzenli olunan güncel bir kullanıcıya ait sistem gösterileri dosyaları neden tam tersi, ls -al rootolmadan, unshareyapar geçerli kullanıcıya ait olarak göster.


Not: Kullanabilen işlemlerin chroota chroot. Yana unshare -rvereceğini chrootsıradan bir kullanıcıya izin bir iç izin verildi, eğer bir güvenlik riski olacaktır chrootçevre. Gerçekten de, buna izin verilmez ve başarısız olur:

unshare: unshare başarısız oldu: İşleme izin verilmiyor

paylaşılmayan (2) belgelere uyan :

EPERM (Linux 3.9'dan beri)

CLONE_NEWUSER bayraklarda belirtildi ve arayan bir chroot ortamında (yani, arayanın kök dizini, içinde bulunduğu bağlama ad alanının kök diziniyle eşleşmiyor).


Bağlama ad alanında pivot_root çalıştırmanın, chroot'a benzer bir etkisi vardır, ancak kullanıcı ad alanlarıyla çakışmayı önler.
Timothy Baldwin

1
Bir kullanıcı aynı UID veya alt PID ve kullanıcı ad alanlarında dışında bir işlem ise / proc içine inerek bir chroot veya ad ad bağlama.
Timothy Baldwin

2

Bu günlerde, chroot / BSD hapishanesi yerine LXC'ye (Linux Kapsayıcıları) bakmak istiyorsunuz. Bir chroot ve sanal makine arasında bir yerdedir ve size çok fazla güvenlik kontrolü ve genel yapılandırılabilirlik sağlar. Bir kullanıcı olarak çalıştırmak için gereken tek şeyin, gerekli dosyalara / cihazlara sahip olan grubun bir üyesi olması gerektiğine inanıyorum, ancak yetenekler / sistem izinleri de olabilir. Her iki durumda da, Linux çekirdeğine SELinux vb. Eklendikten çok sonra LXC oldukça yeni olduğu için çok yapılabilir.

Ayrıca, komut dosyalarını kök olarak yazabileceğinizi, ancak sudo kullanarak kullanıcılara bu komut dosyalarını çalıştırmak için güvenli izin verdiğinizi (isterseniz bir parola olmadan, ancak komut dosyasının güvenli olduğundan emin olun) unutmayın.


1

Fakeroot / fakechroot kombinasyonu, dosyaların köklere ait olduğu görünen katran arşivleri üretmek gibi basit ihtiyaçlar için bir benzetme simülatörü verir. Fakechroot manpage http://linux.die.net/man/1/fakechroot .

Yine de yeni bir izin almazsınız, ancak çağırmadan önce bir dizininiz varsa (örneğin, sahte dağıtım)

fakechroot fakeroot chroot ~/fake-distro some-command

şimdi kök gibi bir komut arar ve sahte dağıtımdaki her şeye sahip olursun.


Bu güzel bir fikir, ama sembolikleri öngörülemez bir şekilde ele alıyor gibi görünüyor. Benim ~/fake-distrokullanımları busybox, sembolik bağlar ls, mvve diğer ortak programları /bin/busybox. Eğer açıkça ararsam /bin/busybox mv ..., işler işe yarar, ama ararsam /bin/mv ...alırım sh: /bin/mv: not found. export FAKECHROOT_EXCLUDE_PATH=/Fakechroot'u çalıştırmadan önce ayar yapmak bu semptomu düzeltir, ancak daha sonra diğer sembollere (örn /usr/bin/vim -> /usr/bin/vim.vim.
Ponkadoodle

belki FAKECHROOT_EXCLUDE_PATH = /: / usr yardımcı olur?
sylvainulg

1

Görünüşe göre kullanıcı-ad alanları ile root olmadan krootlamak mümkün. İşte bunun mümkün olduğunu gösteren bir örnek program. Yalnızca linux ad alanlarının nasıl çalıştığını keşfetmeye başladım ve bu kodun en iyi yöntem olup olmadığından tamamen emin değilim.

Farklı kaydet user_chroot.cc. İle derleyin g++ -o user_chroot user_chroot.cc. Kullanımı ./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;
    }
}

Ben çok köklü (kök olmayan olarak yürütülen) ile oluşturulan minimal rootfs üzerinde bu test ettim. Bazı sistem dosyaları gibi /etc/passwdve /etc/groupskonuk rootfs içine konak rootfs kopyalanmıştır.


Failed to unshare user namespaceLinux 4.12.10'da (Arch Linux) başarısız oluyor.
Ponkadoodle

@wallacoloo belki printf () öğesini perror () olarak değiştirebilir ve asıl hatanın ne olduğunu görebilir. başarısız bir çağrıdan kaynaklanabilecek hata kodları için man7.org/linux/man-pages/man2/unshare.2.html adresine bakın unshare. Daha iyi hata mesajlarına sahip olabilecek bu python sürümünü de deneyebilirsiniz: github.com/cheshirekow/uchroot
cheshirekow

1
Aslında @wallacoloo, kernel yapısındaki ayrıcalıklı olmayan kullanıcı ad alanlarını devre dışı bırakıyor gibi görünüyor: lists.archlinux.org/pipermail/arch-general/2017-Şubat /…
cheshirekow

0

Hayır. Doğru hatırlıyorsam, krootun bunu engelleyen bazı çekirdek düzeyinde bir şey var. O şeyin ne olduğunu hatırlamıyorum. Gentoo'nun Catalyst Build aracıyla uğraşırken onu tekrar araştırdım (ve gentoo üzerinde bir kroket ubuntu üzerinde bir chroot ile aynı). Her ne kadar bir parola olmadan gerçekleşmek mümkün olsa da ... ancak bu tür şeyler potansiyel güvenlik açıkları alanına bırakılır ve ne yaptığınızı bildiğinizden emin olunur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.