Escreva dentro de um socket aberto por outro processo no Linux

7

É possível no Linux um processo escrever dentro de um soquete aberto por outro?

Digamos que eu abra uma conexão para o google.com usando o netcat:

myuser@linux:~$ nc google.com 80

Agora posso pesquisar o processo pid e abrir a pasta do descritor de arquivos:

myuser@linux:~$ ls -la /proc/24105/fd
totale 0
dr-x------ 2 myuser myuser  0 2012-03-10 19:01 .
dr-xr-xr-x 7 myuser myuser  0 2012-03-10 19:01 ..
lrwx------ 1 myuser myuser 64 2012-03-10 19:02 0 -> /dev/pts/12
lrwx------ 1 myuser myuser 64 2012-03-10 19:02 1 -> /dev/pts/12
lrwx------ 1 myuser myuser 64 2012-03-10 19:01 2 -> /dev/pts/12
lrwx------ 1 myuser myuser 64 2012-03-10 19:02 3 -> socket:[3947162]

Então, agora eu gostaria de fazer a solicitação HTTP usando um eco dentro desse soquete:

myuser@linux:~$ echo "GET / HTTP/1.1" >> /proc/24285/fd/3
bash: /proc/24285/fd/3: no such device or address

Fazer isso como root não altera o resultado.

Não consigo escrever dentro do soquete, mas posso escrever dentro do stdin:

myuser@linux:~$ echo "GET / HTTP/1.1" >> /proc/24285/fd/0
myuser@linux:~$

Mas não é o que eu quero fazer.

Eu estava pensando: um soquete do Linux deve ser tratado como um arquivo, não é? Um ou mais processos podem usar o mesmo soquete, então por que não posso fazer isso?

    
por otaku22 10.03.2012 / 19:17

2 respostas

5

Isso não é possível porque seria difícil de implementar e raramente é útil. Soquetes são muito mais complexos que os tubos:

  • Os soquetes são bidirecionais.
  • Existem diferentes tipos de soquetes. Alguns soquetes não são fluxos de bytes (por exemplo, soquetes UDP são soquetes de datagrama, que enviam pacotes e não bytes).
  • Os soquetes executam multiplexação (e há alguma sobrecarga entre os soquetes usados pelos servidores que aguardam conexões e soquetes usados pelas conexões abertas reais).

Como os soquetes são bidirecionais, eles geralmente são usados para comunicação em protocolos bidirecionais. Se você injetar dados na conversa, o outro lado pode enviar uma resposta aos seus dados e não há como enviar a resposta ao solicitante correto. Isso reduz consideravelmente a utilidade de permitir a injeção de dados em soquetes.

Se você estiver tentando entrar em contato com o mesmo servidor de um cliente existente e não tiver uma conversa já existente, já existe uma maneira de fazer isso: entrar em contato com o servidor da mesma maneira (abrir um soquete no sistema de arquivos ou para uma porta TCP ou UDP). Se o socket é um sem nome entre dois processos, é uma boa dica que você não deveria entrar, então o sistema operacional não facilita.

Com um soquete de datagrama (não é o caso aqui), você não pode injetar dados diretamente porque o shell só entende fluxos de bytes, ele não sabe chamar send em vez de write para enviar um pacote.

Se você tiver a cooperação de um ponto de extremidade, será possível informar ao descritor do arquivo de uso a passagem 1 2 3 .

Caso contrário, você pode fazer com que o processo que tenha o soquete aberto envie os dados, com ptrace (é o que o gdb usa sob o capô). Isso suspende o processo, muito pelo design, para que seus truques sujos não confundam muito o processo. Mesmo com o processo suspenso, você corre um grande risco de tornar as estruturas de dados do processo inconsistentes com a realidade das modificações de dados ou ambientes que você injetou. (Observe que, mesmo que o sistema permitisse injetar dados em um soquete, haveria um risco semelhante, embora menor, de confundir o processo com essas inconsistências.)

    
por 12.03.2012 / 02:03
1

Eu diria que é possível, mas ambos os processos precisam cooperar para fazer isso. Você pode ter um processo envia um descritor de arquivo por uma conexão de soquete para outro processo. Eu encontrei este exemplo, que parece funcionar em uma máquina Arch linux atualizada.

    
por 11.03.2012 / 01:46