Ubuntu - o usuário não-root pode executar o processo na cadeia chroot?

15

É possível que um usuário não root execute um processo chroot no Ubuntu?

    
por Hawkeye 25.04.2010 / 10:50

6 respostas

10

No Linux, a chamada de sistema chroot (2) só pode ser feito por um processo que é privilegiado. A capacidade que o processo precisa é CAP_SYS_CHROOT.

O motivo pelo qual você não pode fazer chroot como usuário é bem simples. Suponha que você tenha um programa setuid como o sudo que verifica o / etc / sudoers se você tiver permissão para fazer alguma coisa. Agora coloque-o em um chroot chroot com seus próprios / etc / sudoers. De repente, você tem um escalonamento instantâneo de privilégios.

É possível projetar um programa para chroot em si e executá-lo como um processo setuid, mas isso geralmente é considerado um design ruim. A segurança extra do chroot não motiva os problemas de segurança com o setuid.

    
por 25.04.2010 / 21:38
5

@ imz - IvanZakharyaschev comenta a resposta de pehrs de que isso pode ser possível com a introdução de namespaces, mas isso não foi testado e postado como uma resposta. Sim, isso realmente torna possível para um usuário não-root usar o chroot.

Dado um dash vinculado estaticamente e um busybox vinculado estaticamente e um shell bash em execução como não-raiz:

$ 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

O ID do usuário raiz nesse namespace é mapeado para o ID do usuário não-raiz fora desse namespace e vice-versa, e é por isso que o sistema mostra arquivos pertencentes ao usuário atual como pertencentes ao ID do usuário 0. Um% regularls -al root, sem unshare , mostra-os como pertencentes ao usuário atual.

Nota: é bem conhecido que os processos que são capazes de usar chroot , são capazes de sair de um chroot . Como unshare -r concederia permissões de chroot a um usuário comum, seria um risco de segurança se isso fosse permitido dentro de um ambiente chroot . De fato, isso não é permitido e falha com:

unshare: unshare failed: Operation not permitted

que coincide com a documentação unshare (2) (desculpas pela ousadia estranha, mas é assim que parece):

EPERM (since Linux 3.9)

CLONE_NEWUSER was specified in flags and the caller is in a chroot environment (i.e., the caller's root directory does not match the root directory of the mount namespace in which it resides).

    
por 02.12.2014 / 20:25
2

Hoje em dia, você quer estar olhando para LXC (Linux Containers) em vez de chroot / BSD jail. Está em algum lugar entre um chroot e uma máquina virtual, dando a você muito controle de segurança e configuração geral. Acredito que tudo que você precisa para executá-lo como usuário é ser um membro do grupo que possui os arquivos / dispositivos necessários, mas também pode haver recursos / permissões do sistema envolvidos. De qualquer forma, deve ser muito factível, uma vez que o LXC é bastante recente, muito depois do SELinux, etc. ter sido adicionado ao kernel do Linux.

Além disso, lembre-se de que você pode simplesmente escrever scripts como root, mas dar aos usuários permissão segura para executar esses scripts (sem uma senha, se preferir, mas certifique-se de que o script seja seguro) usando o sudo.

    
por 26.04.2010 / 03:09
1

A combinação de fakeroot / fakechroot oferece um simulacro do chroot para necessidades simples, como a produção de arquivos tar onde os arquivos parecem pertencer ao root. Fakechroot manpage é o link .

Você não recebe nenhuma nova permissão, mas se você possui um diretório (por exemplo, fake-distro) antes de invocar

fakechroot fakeroot chroot ~/fake-distro some-command

Agora procure por algum comando como se você fosse root e possuísse tudo dentro da fake-distro.

    
por 06.07.2015 / 14:14
1

Parece que com user-namespaces é possível chroot sem root. Aqui está um exemplo de programa que demonstra que é possível. Eu só comecei a explorar como os namespaces do Linux funcionam e, portanto, não tenho certeza se esse código é a melhor prática ou não.

Salvar como user_chroot.cc . Compile com g++ -o user_chroot user_chroot.cc . O uso é ./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;
    }
}

Eu testei isso em um mínimo de rootfs gerados com multistrap (executado como não-raiz). Alguns arquivos de sistema como /etc/passwd e /etc/groups foram copiados do host rootfs para o guest rootfs.

    
por 26.10.2016 / 22:17
0

Não. Se bem me lembro, há algo no kernel que o chroot faz que o impede. Não me lembro o que era aquilo. Eu investiguei de volta quando mexia com a ferramenta Catalyst Build do Gentoo (e um chroot no gentoo é o mesmo que um chroot no Ubuntu). Embora seja possível fazer isso sem uma senha ... mas essas coisas são deixadas para o reino das possíveis vulnerabilidades de segurança e para garantir que você saiba o que está fazendo.

    
por 25.04.2010 / 12:13