AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 457117
Accepted
Greg Nisbet
Greg Nisbet
Asked: 2018-07-19 20:10:25 +0800 CST2018-07-19 20:10:25 +0800 CST 2018-07-19 20:10:25 +0800 CST

como descompartilhar a rede para o processo atual

  • 772

É possível executar um novo comando sem acesso à rede como não root usando unshare -r -n, por exemplo:

$ unshare -r -n ls
a.txt  b.txt

Um comando que requer acesso à rede falhará previsivelmente.

$ unshare -r -n curl unix.stackexchange.com
curl: (6) Could not resolve host: unix.stackexchange.com

Eu estou querendo saber se é possível remover o acesso à rede para o processo atual, potencialmente gravando em um arquivo mágico /sysou algo semelhante.

Eu gostaria de poder fazer algo como

$ /bin/sh -c 'echo 1 > /sys/unsharethis; curl unix.stackexchange.com'

Um trecho de strace-ing unshare -r -n lsmostra a unsharechamada do sistema

open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=4759040, ...}) = 0
mmap(NULL, 4759040, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7ec6968000
close(3)                                = 0
unshare(CLONE_NEWUSER|CLONE_NEWNET)     = 0
open("/proc/self/setgroups", O_WRONLY)  = 3
write(3, "deny", 4)                     = 4

O que me sugere que descompartilhar o acesso à rede do processo atual é de fato a única maneira de conseguir descompartilhar (ou seja, não pode ser passado como um argumento spawnou algo equivalente). Também sugere que descompartilhar de um script de shell não funcionaria a menos que o shell tivesse sido especificamente estendido para expor um wrapper em torno do unshare.

linux networking
  • 1 1 respostas
  • 2033 Views

1 respostas

  • Voted
  1. Best Answer
    A.B
    2018-07-20T17:06:21+08:002018-07-20T17:06:21+08:00

    Isso pode ser feito, mais ou menos, com o gdbdepurador, e se o processo em execução pode ser anexado (programas que alteram seu estado de despejo, ou são setgid etc. não podem ser anexados, a menos que sejam da raiz).

    Alguns arquivos opcionais podem ajudar a usar gdb como símbolos de depuração para libc6, e alguns arquivos de inclusão relacionados ao Linux para obter os valores reais de alguns símbolos mais tarde (por exemplo, no Debian: (possivelmente) e pacotes) libc6-dbg, mas na verdade uma vez que a "receita " for feito, eles provavelmente não serão mais necessários.libc6-devlinux-libc-dev

    Primeiro o que mais está fazendo? Sem isso, o novo usuário permanece e não pode nem escrever como seu usuário inicial:unshare() unshare -rnobody

    $ id
    uid=1000(user) gid=1000(user) groups=1000(user)
    $ strace unshare -r -n /bin/sleep 1 2>&1 |sed -n '/^unshare/,/^execve/p'
    unshare(CLONE_NEWNET|CLONE_NEWUSER)     = 0
    open("/proc/self/setgroups", O_WRONLY)  = 3
    write(3, "deny", 4)                     = 4
    close(3)                                = 0
    open("/proc/self/uid_map", O_WRONLY)    = 3
    write(3, "0 1000 1", 8)                 = 8
    close(3)                                = 0
    open("/proc/self/gid_map", O_WRONLY)    = 3
    write(3, "0 1000 1", 8)                 = 8
    close(3)                                = 0
    execve("/bin/sleep", ["/bin/sleep", "1"], [/* 18 vars */]) = 0
    

    Isso será usado mais tarde.

    $ ip -4 -br a
    lo               UNKNOWN        127.0.0.1/8 
    eth0@if19        UP             10.0.3.66/24 
    $ ping -c1 10.0.3.1
    PING 10.0.3.1 (10.0.3.1) 56(84) bytes of data.
    64 bytes from 10.0.3.1: icmp_seq=1 ttl=64 time=0.167 ms
    
    --- 10.0.3.1 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    
    rtt min/avg/max/mdev = 0.167/0.167/0.167/0.000 ms
    $ id
    uid=1000(user) gid=1000(user) groups=1000(user)
    $ echo $$
    338
    $
    

    Em outro terminal:

    $ gdb --pid=338
    Reading symbols from /bin/bash...(no debugging symbols found)...done.
    Reading symbols from /lib/x86_64-linux-gnu/libtinfo.so.5...(no debugging symbols found)...done.
    Reading symbols from /lib/x86_64-linux-gnu/libdl.so.2...Reading symbols from /usr/lib/debug/.build-id/b8/95f0831f623c5f23603401d4069f9f94c24761.debug...done.
    done.
    Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug/.build-id/aa/889e26a70f98fa8d230d088f7cc5bf43573163.debug...done.
    done.
    

    [...]

    (gdb)
    

    Agora vamos chamar a primeira função:

    (gdb) call unshare(CLONE_NEWNET|CLONE_NEWUSER)
    No symbol "CLONE_NEWNET" in current context.
    

    Ok, pode haver um método para que o gdb o conheça, mas não sou um guru:

    (gdb) !
    $ grep CLONE_NEW /usr/include/linux/sched.h # man 2 unshare
    #define CLONE_NEWNS 0x00020000  /* New mount namespace group */
    #define CLONE_NEWCGROUP     0x02000000  /* New cgroup namespace */
    #define CLONE_NEWUTS        0x04000000  /* New utsname namespace */
    #define CLONE_NEWIPC        0x08000000  /* New ipc namespace */
    #define CLONE_NEWUSER       0x10000000  /* New user namespace */
    #define CLONE_NEWPID        0x20000000  /* New pid namespace */
    #define CLONE_NEWNET        0x40000000  /* New network namespace */
    $ find /usr/include/ -name fcntl.h |xargs grep O_WRONLY # man 2 open
    /usr/include/asm-generic/fcntl.h:#define O_WRONLY   00000001
    $ exit
    exit
    (gdb) call unshare(0x50000000)
    $1 = 0
    (gdb) call open("/proc/self/setgroups", 1)
    $2 = 3
    (gdb) call write($2,"deny",4)
    $3 = 4
    (gdb) call close($2)
    $4 = 0
    (gdb) call open("/proc/self/uid_map", 1)
    $5 = 3
    (gdb) call write($5, "0 1000 1", 8)
    $6 = 8
    (gdb) call close($5)
    $7 = 0
    (gdb) call open("/proc/self/gid_map", 1)
    $8 = 3
    (gdb) call write($8, "0 1000 1", 8)
    $9 = 8
    (gdb) call close($8)
    $10 = 0
    (gdb) quit
    A debugging session is active.
    
        Inferior 1 [process 338] will be detached.
    
    Quit anyway? (y or n) y
    Detaching from program: /bin/bash, process 338
    

    No processo alterado, pode-se verificar que a eth0interface desapareceu:

    $ ip -br a
    lo               DOWN           127.0.0.1/8 
    $ echo $$
    338
    $ id
    uid=0(root) gid=0(root) groupes=0(root)
    $ touch /
    touch: setting times of '/': Permission denied
    $ touch ~/test1
    $ ls ~/test1
    /home/user/test1
    $ ping 10.0.3.1
    connect: Network is unreachable
    

    Não há como voltar atrás: o novo namespace de usuário não pode voltar ao namespace inicial. Se o processo estiver sendo executado com privilégios suficientes (por exemplo, root sem recursos perdidos nem SELinux), então seria possível (usando apenas unshare(CLONE_NEWNET)/ setns(savedopenedfd)).

    É claro que é possível criá-lo em um arquivo e alterar qualquer processo em execução permitido ou fazer com que o shell se altere a partir de um subprocesso gdb. Conteúdo de removenetwork.gdb, válido aqui apenas para alterar um processo com pid:gid== 1000:1000:

    ATUALIZAÇÃO: adicionado o tipo de retorno (aproximado) para as syscalls abaixo, isso deve evitar que algumas versões do gdb reclamem em ambientes não-dev:

    call (int)unshare(0x50000000)
    call (int)open("/proc/self/setgroups", 1)
    call (long)write($2,"deny",4)
    call (int)close($2)
    call (int)open("/proc/self/uid_map", 1)
    call (long)write($5, "0 1000 1", 8)
    call (int)close($5)
    call (int)open("/proc/self/gid_map", 1)
    call (long)write($8, "0 1000 1", 8)
    call (int)close($8)
    quit
    

    Exemplo:

    $ sh -c 'id; gdb --pid=$$ < removenetwork.gdb >/dev/null 2>&1; id; curl unix.stackexchange.com'
    uid=1000(user) gid=1000(user) groups=1000(user)
    uid=0(root) gid=0(root) groups=0(root)
    curl: (6) Could not resolve host: unix.stackexchange.com
    

    UPDATE : se o root não for necessário, como aparece para esta pergunta, não há necessidade de mapear para o root. Simplesmente substitua as ocorrências de write($XX, "0 1000 1", 8)por write($XX, "1000 1000 1", 11)(para o caso uid:gid== 1000:1000). Grupos suplementares ainda são inevitavelmente perdidos, mas o uid/gid não muda (é mapeado para si mesmo).

    • 2

relate perguntas

  • Inicie/pare o serviço systemd usando o atalho de teclado [fechado]

  • Roteador estranho funciona com centos 6 [fechado]

  • Necessidade de algumas chamadas de sistema

  • astyle não altera a formatação do arquivo de origem

  • Passe o sistema de arquivos raiz por rótulo para o kernel do Linux

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve