Curso MIT "Segurança de sistemas de computadores". Palestra 7: A Sandbox do Cliente Nativo, Parte 1

Instituto de Tecnologia de Massachusetts. Curso de Aula nº 6.858. "Segurança de sistemas de computador". Nikolai Zeldovich, James Mickens. 2014 ano


Computer Systems Security é um curso sobre o desenvolvimento e implementação de sistemas de computador seguros. As palestras abrangem modelos de ameaças, ataques que comprometem a segurança e técnicas de segurança baseadas em trabalhos científicos recentes. Os tópicos incluem segurança do sistema operacional (SO), recursos, gerenciamento de fluxo de informações, segurança de idiomas, protocolos de rede, segurança de hardware e segurança de aplicativos da web.

Palestra 1: “Introdução: modelos de ameaças” Parte 1 / Parte 2 / Parte 3
Palestra 2: “Controle de ataques de hackers” Parte 1 / Parte 2 / Parte 3
Aula 3: “Estouros de Buffer: Explorações e Proteção” Parte 1 / Parte 2 / Parte 3
Palestra 4: “Separação de Privilégios” Parte 1 / Parte 2 / Parte 3
Palestra 5: “De onde vêm os sistemas de segurança?” Parte 1 / Parte 2
Palestra 6: “Oportunidades” Parte 1 / Parte 2 / Parte 3
Palestra 7: “Sandbox do Cliente Nativo” Parte 1 / Parte 2 / Parte 3

Hoje falaremos sobre um sistema chamado Native Client , que o Google usa no mundo real. É uma tecnologia sandbox para executar código em diferentes plataformas. É usado no navegador Chrome , permitindo que aplicativos da Web executem códigos de máquina arbitrários. Este é realmente um sistema bem legal. Também ilustra os recursos de isolamento e uma técnica peculiar de separação de sandbox ou privilégio chamada isolamento de falhas de software, isolamento de falhas de software , sem usar o sistema operacional ou a máquina virtual para criar a sandbox.



Em vez disso, o Native Client adota uma abordagem completamente diferente para examinar instruções específicas em um arquivo binário para descobrir se é seguro executá-lo ou não. Portanto, antes de começarmos a estudar os detalhes técnicos do sistema, vamos descobrir por que esses caras realmente querem executar código de máquina? O interesse específico deles é aplicar esta solução em um navegador da Web, onde você já pode executar o código JavaScript , o Flash Player e alguns outros processos. Por que esses caras estão tão empolgados com a capacidade de executar código na plataforma x86 ? Afinal, parece que este é um passo para trás.

Público: eles querem obter cálculos muito rápidos.

Professor: Sim, essa é uma enorme vantagem do código de máquina. Mesmo que não seja seguro a longo prazo, fornece alto desempenho. Tudo o que você não faria em JavaScript , por exemplo, escreva um programa e o compile, realmente funcionará muito mais rápido. Existem outras razões?

Público: executando código existente?

Professor: certo. É importante que nem tudo possa ser escrito em JavaScript . Portanto, se você possui um aplicativo existente ou, na terminologia do setor, código "herdado" que pretende executar na Internet, essa parece ser uma ótima solução. Como você pode usar apenas uma biblioteca existente, por exemplo, algum tipo de "mecanismo" gráfico complexo que é sensível ao desempenho e a muitas outras coisas complexas que você não deseja reimplementar, e essa será uma boa solução.
Se você está apenas programando um novo aplicativo da Web, deve usar seu próprio cliente se não estiver particularmente preocupado com herança ou desempenho?

Público-alvo: então você não precisa usar JavaScript .

Professor: sim, essa é uma boa razão. Se você não gosta de JavaScript , não precisa usá-lo, certo? Você pode usar, por exemplo, C , executar código Python , escrever em Haskell , em qualquer idioma que achar mais adequado.

Portanto, esta é uma lista bastante convincente de motivação para executar seu próprio código em um navegador, e é muito difícil obter direitos para tal ação. Em apenas um segundo, consideraremos os detalhes técnicos e agora quero mostrar uma demonstração simples de treinamento que recebi do site do Native Client .



Isso é bastante simples, porque você pode pegar um programa C ++ ou C e executá-lo em um navegador. Você pode olhar para esta página da web, que é um arquivo HTML que possui um monte de código JavaScript .



O motivo da existência desse código JavaScript é que ele permite que você interaja com partes do Native Client . Em relação à operação do navegador, o significado de uma solução é que você tenha algum tipo de página da Web que contém código JavaScript . E essa solução funciona com os privilégios das páginas e permite que você faça várias coisas na própria página da Web, por exemplo, se comunique com a rede em algumas circunstâncias.

O Native Client permite que você execute seu módulo dentro do navegador, para que o código JavaScript possa interagir com ele e receber uma resposta. Isso mostra alguns dos códigos JavaScript necessários para o Native Client para interagir com o módulo NaCl específico que estamos prestes a executar.



E você pode enviar mensagens para este módulo. Como isso é feito? Você pega o objeto deste módulo em JavaScript , denomina-se postMessage e , portanto, suporta o envio dessa mensagem para o módulo NaCl . Quando o módulo NaCl responder, ele iniciará a função de mensagem em JavaScript . E, nesse caso em particular, uma caixa de diálogo é exibida no navegador.



Portanto, no lado do JavaScript , essa é uma interface de página da web bastante simples. A única coisa que você precisa fazer adicionalmente é atribuir o módulo NaCl dessa maneira. Ou seja, basta inserir um módulo com um ID específico aqui . O mais interessante aqui é o código hello com a extensão nmf . Ele apenas diz que há um arquivo executável que você precisa baixar e começar a trabalhar com ele em um ambiente NaCl .



Esse código nativo é realmente como qualquer outro código C ++ que você possa escrever. A parte interessante é essa função de processamento de mensagens do HandleMessage .



Esta é uma classe C ++ e, sempre que o código JavaScript enviar uma mensagem para o código nativo , ele executará essa função. Ele executa uma verificação if (message = = 'hello') . Nesse caso, ele criará algum tipo de linha de resposta e a enviará de volta. Isso é coisa bem simples. Mas, para detalhes, vamos tentar executá-lo e ver o que acontece.

Podemos construir e executar um pequeno servidor Web que servirá a esta página e ao módulo Native Client . Aqui eu posso ir para este URL , e aqui vemos a página do NaCl . O módulo recebeu nossa mensagem de boas-vindas do JavaScript , respondeu de volta com uma string no JavaScript e o código JavaScript acionou uma caixa de diálogo pop-up contendo essa resposta.



Então isso realmente funciona.

Tente descobrir se podemos causar uma falha no cliente nativo . Espero que não, mas podemos pegar esse código e esse buffer e escrever um monte de bobagens nele, por exemplo, 65536 e ver o que acontece.



Espero que isso não cause o travamento do meu navegador porque o Native Client está tentando fornecer isolamento. Mas vamos ver o que acontece.

Reinicie o servidor web. Vemos que a entrada do módulo ainda é bem-sucedida, nosso navegador não foi ferido. No entanto, as mensagens com o cliente não ocorreram; portanto, a caixa de diálogo está ausente. Vamos dar uma olhada no console JavaScript na parte inferior da página e ver se o módulo Native Client nos informa sobre a falha do módulo NaCl .



É possível que o argumento que inseri tenha causado um estouro de buffer ou acesso a algum endereço errado, mas, em qualquer caso, o módulo NaCl é realmente capaz de isolar a corrupção acidental de memória de forma que não afete o navegador.

Esta é uma demonstração rápida desse sistema na forma em que você pode usá-lo como usuário final ou desenvolvedor. Vejamos mais alguns exemplos. Por exemplo, como o Native Client funcionará, ou por que precisamos disso, e não de um design alternativo.

Portanto, se seu objetivo é isolar seu próprio código, existem várias alternativas com as quais você pode fazer isso. De fato, as pessoas costumavam ter problemas ao usar código legado e outros idiomas antes do aparecimento do Native Client . Eles os resolveram de várias maneiras, o que pode não ter sido tão seguro e conveniente quanto o Native Client , mas forneceu os mesmos recursos de isolamento.

Então, o que você deve fazer se realmente deseja executar o código da máquina em um navegador? Uma opção é confiar no desenvolvedor. Talvez uma variante dessa abordagem seja a pergunta ao usuário se ele deseja executar algum trecho de código no navegador ou não.

Então, todo mundo entende aproximadamente que tipo de plano é esse, certo? Por exemplo, em vez de toda essa estratégia de compilação do Native Client , eu poderia apenas criar um programa C , executá-lo em um navegador e ele me perguntaria se eu quero executar este site ou não? E se eu clicar em "sim", acidentalmente em "roçada" na memória do navegador, ele travará. Então é possível, certo? Isso, é claro, resolve todos esses problemas, mas o que há de errado nisso?

Eu acho que o ruim é que esta solução é insegura. Essa é uma maneira de contornar esse sistema e muitos outros sistemas.

A Microsoft tinha um sistema chamado ActiveX que basicamente implementou esse plano. Você pode enviar os binários para o IE , o navegador do seu computador, e até que eles retornem com um certificado de um desenvolvedor específico assinado por, por exemplo, Microsoft ou outra pessoa, o navegador não executará seu código. Você acha que esse é um plano útil?

Público: É uma questão de confiança!

Professor: sim, é. Você realmente precisa confiar um pouco que o desenvolvedor assinará apenas os "binários" que não farão nada errado. Mas muitas vezes é impossível descobrir se isso é algo ruim ou não, então eles simplesmente escrevem o código C e o assinam cegamente sem fazer uma enorme quantidade de trabalho. Nesse caso, você pode obter certos problemas no futuro.

Da mesma forma, a decisão de perguntar ao usuário se ele realmente deseja executar alguma coisa não garante segurança. Mesmo que o usuário queira ter cuidado, na verdade não está claro como ele deve decidir? Suponha que eu realmente queira entender se posso deixar este programa funcionar? Disseram-me que está tudo bem, talvez tenha sido criado por desenvolvedores respeitáveis ​​do Google.com ou Microsoft.com . No entanto, este é o arquivo executável foo.exe e eu absolutamente não sei o que está dentro dele. Mesmo se eu desmontar o código dele, será muito difícil dizer se ele fará algo ruim ou não. Portanto, é realmente difícil para o usuário decidir se a execução do código é segura para o sistema.



Assim, o Native Client pode atuar como um mecanismo pelo qual os usuários podem ter alguma confiança em dizerem sim ou não a algum programa.

Então, na prática, acho que deveria haver uma opção proposta por nosso palestrante convidado Paul Yang na semana passada. Ele aconselhou a execução do plug-in " play extension " ou "play the extension" no navegador Chrome . Ou seja, antes de iniciar qualquer extensão, incluindo o Native Client , você precisa clicar nessa coisa. De certa forma, é o mesmo que perguntar ao usuário. Mas, neste caso, mesmo que o usuário decida responder "sim", o sistema ainda estará seguro, porque o Native Client será incluído no trabalho. Nesse sentido, temos um mecanismo de segurança duplo: primeiro pergunte ao usuário e, em seguida, com uma resposta positiva, inicie o cliente sandbox, o que não permitirá que o navegador trave.

Portanto, outra abordagem que deve ser aplicada é usar o sandbox, implementado por meio do SO ou hardware, ou isolar processos. Foi isso que examinamos nas duas últimas palestras.

Talvez você usaria mecanismos de isolamento do Unix . Se você tivesse algo mais complexo, usaria o FreeBSD ou o Capsicum . É ótimo para isolar um pedaço de código na sandbox, porque você pode limitar seus recursos. O Linux possui um mecanismo semelhante chamado Seccomp , que abordamos brevemente na última palestra, e também permite que você faça essas coisas.

Portanto, já existe um mecanismo para escrever código isoladamente em sua máquina. Por que esses caras estão contra o uso desta solução existente? Parece que eles estão "inventando a roda" por algum motivo. Então o que está acontecendo?

Público: talvez eles queiram minimizar erros?

Professor: sim, de certa forma, eles não confiam no sistema operacional. Talvez eles estejam realmente preocupados com erros do SO. É provável que o kernel do FreeBSD ou Linux contenha bastante código C que eles não desejam ou não podem verificar se estão corretos, mesmo que quisessem. E no Capsicum ou no Seccomp, o trabalho é realizado com base no plano de isolamento; portanto, basta que o kernel tenha apenas um pequeno e fiel pedaço de código, para que o sandbox mantenha e aplique o isolamento.



Público-alvo: como você tem muito mais maneiras de usar navegadores, precisa lidar com vários sistemas operacionais, como iOS e Android, e acessar ...

Professor: sim, de fato, outra consideração interessante é que geralmente muitos sistemas operacionais apresentam erros. Além disso, de fato, diferentes sistemas operacionais são de alguma forma incompatíveis entre si. Isso significa que cada sistema operacional possui seu próprio mecanismo, conforme mostrado aqui: O Unix possui Capsicum , o Linux possui Seccomp , mas essas são apenas variações do Unix . O Mac OS possui cinto de segurança , o Windows tem outra coisa e a lista continua.

Portanto, no final, cada plataforma com a qual você trabalha tem seu próprio mecanismo de isolamento. E o que realmente não os incomoda muito é que eles terão que escrever um código diferente para Mac , Windows e Linux . Mais ainda, isso afeta a maneira como você escreve essas coisas para trabalhar dentro da caixa de areia. Como no Native Client, você realmente escreve um pedaço de código que é executado da mesma maneira que o código do SO "nativo", da mesma forma que o código da Apple , o código do Windows ou o código do sistema Linux é executado.

E se você usar esses mecanismos de isolamento, eles realmente impõem restrições diferentes ao programa colocado na sandbox. Portanto, você precisa escrever um programa que será executado dentro da caixa de proteção do Linux , outro programa para ser executado dentro da caixa de proteção do Windows e assim por diante.

Isso é o que é realmente inaceitável para eles. Eles não querem lidar com problemas desse tipo. Que outras considerações você tem?

Público-alvo: presumivelmente desempenho do sistema. Porque se você usar Capsicum , precisará cuidar de recursos suficientes para garantir que os processos funcionem dentro da caixa de proteção. Aqui eles podem enfrentar o mesmo problema.

Professor: sim, é verdade. O plano de isolamento de falhas de software é realmente muito intensivo em recursos, o que no nível do sistema operacional pode causar uma falta de recursos para dar suporte à sandbox. Acontece que, em seu próprio cliente nativo, eles realmente usam a sandbox e a sandbox do SO para fornecer segurança adicional. Assim, de fato, eles não ganham no desempenho de sua implementação, embora provavelmente possam.

Público: talvez eles queiram controlar tudo. Como eles podem controlar o que acontece no navegador, mas se o enviaram ao computador do cliente no sistema operacional, eles não sabem o que poderia acontecer lá.

Professor: pode-se dizer que sim, o sistema operacional pode ter erros ou não gerenciar o sandbox suficientemente bem. Ou a interface é um pouco diferente, então você não sabe o que o sistema operacional está prestes a revelar.

Público: e isso não impedirá que o código faça algumas coisas ruins. Há muitas coisas que o código faz, por exemplo, que você deseja executar análise estática, mas os loops de código impedem a ação do programa.

Professor: na verdade, é muito difícil determinar se existe ou não um processo em loop infinito, mas, em princípio, essa abordagem permite detectar alguns problemas de código. Eu acho que um exemplo realmente interessante, que eu não conhecia até ler o artigo deles, mostra que esses caras estão preocupados com erros de hardware e não apenas com vulnerabilidades do SO que podem ser executadas pelo código. Por exemplo, o próprio processador possui algumas instruções que podem congelar ou reiniciar o computador. Basicamente, seu equipamento não deve ter esse erro, porque o sistema operacional depende do fato de que o hardware, em qualquer caso, ajudará a alcançar o kernel, a fim de eliminar as consequências de um erro do usuário.

Mas acontece que os processadores são tão complexos que têm erros, e esses caras dizem que encontraram evidências disso. Se houver instruções complexas que o processador não esperava receber, ele será interrompido em vez de processar o núcleo do sistema. Isso é ruim. Eu acho que isso não é catastrófico se eu apenas executar algumas coisas úteis no meu laptop, mas muito pior se o computador congelar quando visito algum tipo de página da web.

Portanto, eles queriam criar um nível de proteção mais alto para os módulos do Native Client do que aquele que fornece isolamento no nível do sistema operacional, mesmo sem erros de hardware. Então, sobre segurança, eles se comportam como paranóicos, incluindo o problema de segurança de hardware.

Vamos ver agora como o Native Client realmente isola os processos na sandbox. Assim, o Native Client adota uma abordagem diferente, que pode ser chamada de "isolar falhas de software".



O plano não é confiar no fato de que o sistema operacional ou o equipamento verificará as coisas enquanto o programa estiver em execução, mas confiar neles para revisar as instruções com antecedência e decidir que elas podem ser executadas com segurança. Assim, de fato, basta examinar o arquivo binário para verificar todas as instruções possíveis e verificar se elas serão seguras ou não. Depois de ter decidido que tudo estará seguro, você pode simplesmente iniciar o processo porque sabe que ele consiste em coisas seguras e não haverá falhas.

Portanto, o que eles farão é examinar quase todas as instruções no código binário enviado ao navegador e decidir se instruções específicas são seguras ou não.

? . ? , , .

- ALU , , . , . , , . , , , .



? , , . , , , . , «» , ? .

, , , - , . «» , - . , «» , . , , , , .
, ( ) . . , if , , . , , – .

, , , . . , , . , , , , «» .



. , , . , , .

, , , , - , . , , , , . Trusted Service Runtime , . . Google . , NaCl .

, , , , , — , — . , .

: , , NaCl ? , ?

: , , , NaCl . , malloc pthread_create , Trusted Service Runtime . - , Unix , - . , , JavaScript -. RPC JavaScript , .



, , NaCl Unix -, - , -.

. , Native Client . – Native Client ?

, Native Client . , , . , , x86 . , , «», .

, . , , 0 256 . , , , , .

? , ?

: , .

: , . , , . , , ? , ?

: .

: !

: -, , . .

: , . , . , , . , , , Trusted Service Runtime . , , Trusted Service Runtime , . , .

, , NaCl , . , 0. , NaCl . .

28:00

:

Curso MIT "Segurança de sistemas de computadores". 7: « Native Client», 2


.

, . Você gosta dos nossos artigos? Deseja ver materiais mais interessantes? Ajude-nos fazendo um pedido ou recomendando a seus amigos, um desconto de 30% para os usuários da Habr em um análogo exclusivo de servidores básicos que inventamos para você: Toda a verdade sobre o VPS (KVM) E5-2650 v4 (6 núcleos) 10GB DDR4 240GB SSD 1Gbps de US $ 20 ou como dividir o servidor? (as opções estão disponíveis com RAID1 e RAID10, até 24 núcleos e até 40GB DDR4).

3 meses de graça ao pagar por um novo Dell R630 por um período de seis meses - 2 x HDD Intel Deca-Core Xeon E5-2630 v4 / 128GB DDR4 / 4x1TB ou SSD 2x240GB / 1Gbps 10 TB - de US $ 99,33 por mês , apenas até o final de agosto, faça o pedido pode estar aqui .

Dell R730xd 2 vezes mais barato? Somente nós temos 2 TVs Intel Dodeca-Core Xeon E5-2650v4 128GB DDR4 6x480GB SSD 1Gbps 100 a partir de US $ 249 na Holanda e nos EUA! Leia sobre Como criar um prédio de infraestrutura. classe usando servidores Dell R730xd E5-2650 v4 custando 9.000 euros por um centavo?

Source: https://habr.com/ru/post/pt418223/


All Articles