CTF Starter Pack

Um guia inicial para competições Capture The Flag

Introdução

Este guia destina-se a entusiastas de segurança da informação e que desejam participar de CTFs.

O que são CTFs?

CTF significa Capture the Flag. No contexto de segurança da informação, são competições que envolvem diversas áreas como descoberta de vulnerabilidades, técnicas de espionagem e criação de exploits e ferramentas.

De maneira geral, nessas competições os jogadores são apresentados a problemas, programas com falhas de segurança ou sistemas para serem invadidos. Em cada problema, programa ou sistema, há uma chave secreta ou "flag". Encontrar essa flag é a prova que você resolveu o desafio e enviando no campo especificado faz seu time ganhar pontos.

Tipos de CTFs

Os CTFs são divididos em dois tipos:

Attack-defense

Todos os times recebem uma Máquina Virtual com algumas falhas de segurança. O objetivo é capturar as flags através das vulnerabilidades dos outros times e protegendo seu próprio time de invasões corrigindo suas falhas de segurança.

Jeopardy-sytle

Todos são apresentados a questões de diversas categorias, níveis de dificuldades e pontuações, também chamadas de challenges. As categorias variam de competição para competição, as principais são

Quando ocorrem os CTFs?

Esses eventos ocorrem em vários perídos e lugares, sendo organizados por pessoas diferentes. Alguns podem acontecer remotamente (on-line) ou presencialmente (on-site).

Uma ótima plataforma para acompanhar as datas das principais competições é o CTFtime.

Como se preparar para CTFs?

O melhor jeito de se preparar para essas competições é praticando.

Abaixo está uma lista de alguns sites com ótimo conteúdo para treinar.

Para auxiliar esse processo, este guia pretende abordar alguns conceitos básicos para resolver esses desafios de forma didática e rápida.

E ainda, uma ótima forma de treinar é observar resoluções (ou write-ups) de desafios que você não conseguiu ou quer ver outra resolução dele.

Onde treinar?

Alguns dos sites abaixo serão usados como exercício para este guia.

WeChall

Plataforma com desafios de diversas áreas e dificuldades.

OverTheWire

Site com diversos wargames onde é necessário conectar no respectivo servidor por meio do terminal. O desafio Bandit é muito recomendado para aprender comandos de Linux.

picoCTF 2018

A edição 2018 de uma competição muito famosa e voltada para estudantes. Apresenta ótimos desafios introdutórios e de diversas áreas.

Hack The Box

Plataforma voltada para invasão de máquinas, simula cenários reais de pentest. Possui também alguns desafios de várias áreas, como os outros, e é preciso "hackear" o site para conseguir o login.

Referências

CTF-BR

OpenCTF

Trail of Bits

CTFtime

Como identificar uma flag?

Todo challenge de um CTF costumar ter pelo menos uma chave-secreta como reposta, normalmente chamada de flag.

O formato de como essa flag é apresentada varia de competição para competição. Muitas vezes é uma string bem distintiva, de forma que, quando você ver uma, saberá que é uma flag. Além disso, a competição costuma explicitar o formato de flag que deverá ser enviado.

Por exemplo, flags podem estar explícitas como

flag{M4C4L191Jd912}

Assim, a flag é flag{M4C4L191Jd912} ou M4C4L191Jd912, dependendo da competição.

Elas podem ser indicadas por uma frase como

The answer is ABidaBBeBelaB

Assim, a flag é ABidaBBeBelaB.

Ou apenas um sentença compreensível como

ther5s_n0_Place_l1ke_h0m3

Assim, a flag é a própria sentença ther5s_n0_Place_l1ke_h0m3.

Mesmo assim, podem existir várias outras formatações diferentes para uma flag, como um link ou uma expressão matemática. Mas essas apresentadas serão as mais comuns.

Exercícios

WeChall: get sourced

Criptografia

Aprenda as técnicas de criptografia e como abordá-las em CTFs. Desde a criptografia clássica das cifras até a criptografia moderna das chaves públicas.

Criptografia

O que é criptografia?

Criptografia vem do grego kryptós e graphein, que significam "secreta" e "escrita", respectivamente. Até a era moderna, ela era sinônimo de encriptação, que é a conversão de uma mensagem legível para algo aparentemente sem sentido, e é esse o conceito usado em CTFs.

Para entender melhor essa ideia, digamos que Alice quer mandar uma mensagem para Bob sem que uma terceira pessoa, digamos Eve, descubra seu counteúdo.

Para isso, Alice usa um certo algoritmo para tornar a mensagem ilegível de forma que só Bob saberá reverter a mensagem encriptada.

crypto-introduction.png

Assim, quando Eve interceptar a mensagem por meio do canal inseguro, se ela não possui o algoritmo criptográfico usado por Alice e Bob, ela não será capaz de entender a mensagem.

Ao longo da história, várias técnicas de ocultar mensagens foram desenvolvidas. Antes da criptografia pré-computacional, a criptografia clássica era formada por um conjunto de métodos de substituição e transpoisção de caracteres. E com o advento da computação, a criptografia moderna se tornou amplamente embasada em teorias matemáticas e práticas de ciência da computação.

Para esse guia, começaremos com os métodos da criptografia clássica.

Criptografia

Cifra de César

A Cifra de César é um dos métodos mais simples e comuns de encriptação. Mesmo não sendo muito comum em CTFs, ainda é um conhecimento básico de criptografia.

Esse método tem esse nome pois era usado por Júlio César em suas correspondências

Nessa cifra, cada letra da mensagem é substituida por uma letra do alfabeto deslocado por um número fixo.

Por exemplo, se queremos encriptar a mensagem hack the planet, podemos deslocar cada letra do alfabeto 3 vezes para direita (ou right 3). Assim, a substituição teria esse formato:

original A B C D E F G H I J K L M
right 3 D E F G H I J K L M N O P
original N O P Q R S T U V W X Y Z
right 3 Q R S T U V W X Y Z A B C
texto original: hack the planet

texto cifrado:  kdfn wkh sodqhw

Dessa forma, o texto gerado se torna incompreensível de forma que só quem sabe o algoritmo usado poderá recuperá-lo.

ROT13

Um dos tipos mais comuns de Cifra de César é o ROT13. Nele, o alfabeto é deslocado 13 vezes. Como o alfabeto tradicional possui 26 letras, o ROT13 possui a propriedade de que o mesmo algoritmo usado para encripitar a mensagem é usado para decriptar.

Detectando

Mensagens encriptadas pela cifra de césar normalmente produzirão um amontoado de caracteres sem significado, como kdfn wkh sodqhw, e suas letras terão uma distribuição de frequência similar à língua usada (provavelmente inglês), mas com as letras trocadas. Esse conceito será abordado com mais profundidade em Cifras de Substituição.

Devido a facilidade de quebrar essa cifra, pode ser conveniente tentar solucioná-la sem nem ao menos uma análise de frequência.

Solucionando

Como num alfabeto usual são usados apenas 26 caracteres, a Cifra de César possui apenas 25 tipos de rotações possíveis (pois a rotação 26 é a própria mensagem). Assim, um testa tudo, onde você faz todos os tipos de rotações possíveis, é a opção mais simples.

Existem ferramentas online muito eficientes para quebrar uma Cifra de César, como o site dcode, porém não é muito difícil codificar um testa tudo para isso.

Codificando um testa tudo

Primeiro, codificaremos uma função rot() que aplica a rotação em um caractere, de acordo com o deslocamento determinado (o shift):

def rot(char, shift):
  return chr((ord(char) - ord('A') + shift)%26 + ord('A'))

Assim, podemos usar essa função para criar um caesar_brute_force() que recebe um texto cifrado e imprime todas as rotações possíveis.

def caesar_brute_force(cipher_text):
    cipher_text = cipher_text.upper()
    for i in range(26):
        line = ''
        for c in cipher_text:
            line += rot(c, i) if c.isalpha() else c
        print(f'rot{i}:\t{line}')

Exercícios

OverTheWire: Krypton 1

OverTheWire: Krypton 2

WeChall: Caesar

Criptografia

Cifras de Substituição Simples

Agora que você está familiarizado com a Cifra de César, vamos apresentar uma generalização desse conceito: as cifras de substituição simples.

Em uma cifra de substituição simples, cada letra é substituida individualmente de acordo com um alfabeto de substituição. Esse alfabeto pode ser uma rotação fixa do alfabeto normal (como a cifra de César) ou algum embaralhamento mais complexo.

Alguns exemplos notáveis de cifra de substituição simples são:

Cifra de Atbash

Seu nome tem origem da primeira, última, segunda e penúltima letra Hebraica (Aleph-Taw-Bet-Shin)

Nessa cifra, cada letra é mapeada para o alfabeto invertido, ou seja, a primeira vira a última, a segunda vira a penúltima e assim por diante.

original: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
cifra:    Z Y X W V U T S R Q P O N M L K J I H G F E D C B A

Assim, se usarmos essa cifra em may the force be with you, obteremos:

original: M A Y  T H E  F O R C E  B E  W I T H  Y O U
cifrado:  N Z B  G S V  U L I X V  Y V  D R G S  B L F

A Cifra de Atbash pode ser interpretada como um caso particular da Cifra de Affine, uma cifra que usa aritimética modular para encriptar.

Cifra da Palavra-Chave

A Cifra da Palavra-Chave ou keyword cipher consiste em escolher uma chave e usá-la para decidir como as letras serão susbtituidas.

As palavras repetidas dessa chave serão removidas e a própria chave será o começo do alfabeto a ser mapeado. O resto das letras continuarão em ordem alfabética, tirando as letras já usadas.

Por exemplo, escolhendo a chave Marvin, o novo alfabeto terá esse formato

original: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
cifra:    M A R V I N B C D E F G H J K L O P Q S T U W X Y Z

Assim, ao encriptar a mensagem Arthur Dent, obteremos:

original: A R T H U R  D E N T
cifrado:  M P S C T P  V I J S

Detectando

Como mencionado na seção de Cifra de César, uma mensagem encriptada por uma cifra de substituição simples terá uma distribuição de frequência das letras semelhante ao da língua usada, mas com as letras trocadas.

Essa distribuição de frequência de um texto pode ser identificada através de uma análise de frequência.

Nas línguas naturais, algumas letras aparecem mais frequentemente que outras, como uma espécie de digital do idioma. Por exemplo, a letra mais comum na lígua inglesa é o "e", em português é o "a".

Essa análise de frequência pode ser feita simplesmente contando as letras do texto. Existem ferramentas online para isso como o site dcode ou pode ser feito rapidamente com um biblioteca em Python, onde text é o texto a ser analisado:

from collections import Counter
Counter(text.upper()).most_common()

Solucionando

O ponto fraco de cifras de substituição simples é que elas são muito suscetíveis à análises de frequência.

Assim, se você tiver um texto de tamanho razoável, por volta de 50 caracteres, é possível analisar a frequência com que as letras aparecem e deduzir qual foi o alfabeto de substituição usado.

O site guaballa é um excelente decodificador de cifras de substituição simples.

Referências

Cifra de Atbash: Jeremiah's Game

Cifra da Palavra-Chave: GeeksforGeeks

Learn Cryptography

Exercícios

OverTheWire: Krypton 3

Criptografia

Cifra de Vigenère

Devido à vulnerabilidade das cifras de substituição simples, foi necessário a criação de uma cifra que conseguisse se proteger disso. A Cifra de Vigenère veio com esse propóstio e é basicamente uma extensão da fórmula da Cifra de César. Ela gera uma distribuição praticamente uniforme em uma análise de frequência e foi considerada inquebrável por 3 séculos.

Ela tem esse nome em homenagem a Blaise de Vigenère

Essa Cifra consiste basicamente em pegar uma palavra-chave e aplicar a cifra de César várias vezes, de acordo com os caracteres da palavra-chave.

Por exemplo, se nós queremos encriptar a mensagem the cake is a lie usando a palavra-chave portal, primeiro cada caractere da palavra-chave terá um número de rotações equivalente (de acordo com sua posição no alfabeto):

letra P O R T A L
rotações 16 15 18 20 1 12

Assim, para cada letra da mensagem será rotacionada de acordo com a sequência de rotações acima:

mensagem:         T H E  C A K E  I S  A  L I E
chave:            P O R  T A L P  O R  T  A L P
mensagem cifrada: I V V  V A V T  W J  T  L T T

Essa cifra, diferentemente das cifras de substituição simples, é uma Cifra de Substituição Polialfabética.

Detectando

Um texto encriptado por essa cifra pode ser detectado através de uma análise de frequência.

A Cifra de Vigenère costuma gerar textos com uma distribuição de frequência das letras próximo ao uniforme. Se um texto cifrado que não é esperado esse tipo de distribuição obter esse resultado, provavelmente é Cifra de Vigenère, ou alguma outra Cifra Polialfabética.

Solucinando

Mesmo gerando uma distribuição uniforme em análises de frequência, essa cifra tem uma vulnerabilidade: a palavra-chave é usada várias vezes em um texto grande.

Dessa forma, se a chave tiver tamanho 5, por exemplo, e ajustarmos o texto em linhas de comprimento 5, cada coluna terá a mesma rotação. Assim, podemos chutar tamanhos da palavra-chave e usar a mesma análise de cifra de substituição simples para cada coluna.

Uma ferramenta online muito útill para quebrar a Cifra de Vigenère é o site dcode.

Referências

GeeksforGeeks

Exercícios

OverTheWire: Krypton4

OverTheWire: Krypton5

picoCTF-2018: blaise's cipher

Criptografia

One-Time Pad

Por muitos anos, o problema de esconder os padrões da língua ainda persistia, porém no final do século XIX surgiu aquele que seria o método mais forte de criptografia: o one-time pad.

Funcionamento

Primeiro, precisamos gerar uma sequência aleatória de bits do mesmo tamanho da mensagem, essa será o one-time pad. Essa chave deverá ser passada por um meio seguro para o destinatário.

Para esse exemplo, usaremos codificação em base64 para os caracteres.

mensagem:     H O P E
one-time pad: y T 2 5

Depois, vamos criar o texto cifrado a partir da mensagem e do one-time pad. Para isso, codificaremos a mensagem e o one-time pad em binário e realizamos a operação de ou exclusivo bit a bit, ou XOR.

A operação XOR de dois bits retorna 1, se eles forem diferentes, e 0, se forem iguais.

mensagem:      H O P E ->  000111 001110 001111 000100
one-time pad:  y T 2 5 ->  110010 010011 110110 111001
                           |
                       XOR |
                           V
texto cifrado: 1 d 5 9 ->  110101 011101 111001 111101

Já para recuperar a mensagem, usamos exatamente a mesma operação, realizando um XOR bit a bit com o texto cifrado e o one-time pad.

Após um uso, o one-time pad deverá ser destruído.

A criptografia perfeita

No final da década de 1940, Claude Shannon provou que se cada chave for usada uma única vez e ela for gerada aleatoriamente, então o método de one-time pad é perfeitamente seguro.

Isso pode ser visualizado pelo seguinte exemplo: digamos que temos uma mensagem de 24 bits, logo temos 2^24 possíveis valores para a chave. A partir disso, temos dois problemas:

Poderíamos tentar verificar todas as chaves. Para uma mensagem de 24 bits, ainda é uma alternativa viável, mas de expandirmos para 54, mesmo se checando 1 milhão de valores por segundo, ainda levaríamos mais de 570 anos para checar todas as possibilidades.

Outro problema é que cada possível chave gera uma possível mensagem com igual probabilidade das demais, assim se checarmos todas as chaves, veríamos todas as combinações possíveis de mensagens de 24 bits.

chave possível mensagem
A A A A 1 d 5 9
A A A B 1 d 5 8
... ...
+ J z 5 L U K E
... ...
y T 2 5 H O P E
... ...

Dessa forma, não há como distinguir a mensagem real de todas as outras possibilidades.

Entetanto, mesmo a técnica de One-time pad sendo simples e teoricamente inquebrável, na prática ela possui alguns pontos negativos, que costumam trazer suas vulnerabilidades:

Esses dois últimos pontos, especialmente, acabam tornando o one-time pad teórico impraticável.

Linear Feedback Shift Register

Como alternativa às longas sequências de bits realmente aleatórias, foi criado um algoritmo determinístico capaz de produzir valores pseudo-aleatórios: o linear feedback shift register ou LFSR.

Valores pseudo-aleatórios são sequências de bits que parecem ser aleatórias. Elas não são aleatórias de fato, pois são criadas por algoritmos determinísticos, mas, para efeitos práticos, tem as mesmas propriedades de sequências aleatórias.

Esses valores pseudo-aleatórios são criados da seguinte maneira:

Primeiro, precisamos de uma sequência de bits inicial, chamada de seed. Essa seed dará o tamanho do registrador, que é um elemento que armazena todos os bits necessários para gerar o próximo.

Depois, geraremos uma nova sequência através da operação XOR de dois bits, colocando os bits resultantes à direita.

Por exemplo, a imagem acima representa o registrador com a seed. Nela, os bits 11 e 9 foram escolhidos para gerar o próximo. Essas posições são chamadas de tap, ela é uma numeração que começa do 1, indo da direita para esquerda.

Para descrever essas posições do algoritmo, usamos a notação [N, k] LFSR, que representa um algoritmo de LFSR com um registrador de N bits com taps em N e k. Na imagem acima, temos um [11,9] LFSR.

Abaixo, está uma pequena simulação de um [5,4] LFSR com a seed 00001.

[5,4] LFSR

            novo bit
               V
seed ->  00001 0
         00010 0
         00100 0
         01000 1
         10001 1
         00011 0
         00110 0
         01100 1
         11001 0
         10010 1
         00101 0
           ^
      registrador

Assim, precisamos apenas criar uma lista de pequenas seeds e distribuí-las por um canal seguro, usando elas para criar chaves do one-time pad, por meio do LFSR.

Exercícios

Krypton 6

Referências

Khan Academy

Computer Science - Sedgewick & Wayne

Mensagens alemãs não aleatórias

Criptografia

Cifras de Transposição

Na tentativa de encontrar um método alternativo às cifras de substituição simples, que estavam se tornando frágeis, foram criadas as Cifras de Transposição. Nessa cifra, o texto permanece o mesmo mas as ordem dos caracteres são alteradas, embaralhando a mensagem de acordo com um padrão.

Existem vários padrões diferentes para realizar a transposição, os dois mais famosos são a transposição colunar simples e a rail fence.

Transposição colunar

Com essa regra, a mensagem é escrita horizontalmente numa matriz de largura fixa e a saída é o texto lido verticalmente nessa matriz.

Numa transposição colunar simples essa leitura é feita por colunas da esquerda para direita. Por exemplo, com texto a wizard is never late a encriptação será da forma

Texto: A WIZARD IS NEVER LATE

Matriz:

A W I Z A R
D I S N E V
E R L A T E

Texto cifrado: ADEWIRISLZNAAETRVE

Para decriptar, escrevemos o texto cifrado verticalmente numa matriz de mesma largura e lemos o texto horizontalmente.

A ordem de leitura de colunas pode ser determinada também de acordo com uma palvra-chave. O tamanho da palavra-chave definirá a largura da matriz usada e cada caractere determina a ordem que as colunas serão lidas. Por exemplo, usando a chave FRODO, numeramos as letras em ordem alfabética: 25314. Assim, podemos usar essa ordem para ler as colunas e gerar o texto cifrado

Texto: A WIZARD IS NEVER LATE

Ordem:  2 5 3 1 4

Matriz: A W I Z A
        R D I S N
        E V E R L
        A T E

Texto cifrado: ZSRAREAIIEEANLWDVT

Rail Fence

Nesse tipo de transposição, os caracteres são escritos numa matriz usando um padrão fixo em zigue-zague e a saída é o texto lido horizontalmente. o rail fence admite várias variações, como a linha que a primeira letra começa e o número de linhas usadas. Por exemplo, usando um rail fence com duas linhas

Texto: A WIZARD IS NEVER LATE

Matriz:

A - I - A - D - S - E - E - L - T -
- W - Z - R - I - N - V - R - A - E

Texto ciffrado: AIADSEELTWZRINVRAE

Outro exemplo mas com três linhas será da forma

Texto: A WIZARD IS NEVER LATE

Matriz:

A - - - A - - - S - - - E - - - T -
- W - Z - R - I - N - V - R - A - E
- - I - - - D - - - E - - - L - - -

Texto ciffrado: AASETWZRINVRAEIDEL

Para descriptografar, é necessário o conhecimento do padrão usado e preencher as lacunas com o texto cifrado horizontalmente e depois ler em zigue-zague.

Essa técnica foi usada na Guerra Civil norte-americana para cifrar as mensagens dos confederados e dos federalistas.

Identificando

Como apenas a ordem do texto é alterada, a distribuição de frequência das letras será muito parecida com a frequência da língua usada. Assim, uma análise de frequência do texto cifrado é um ótimo método para identificar o uso de uma cifra de transposição.

Além disso, podem ter sido usadas cifras de substituição em conjunto, dificultando a indentificação.

Solucionando

Um primeiro método que podemos pensar para quebrar cifras de transposição é testar todas as possíveis permutações dos caracteres. Porém, um texto de 20 caracteres geraria 20! possíveis permutações. Se computássemos 100 milhões de valores por segundo, demoraríamos mais de 300 anos para computar todos. Logo, testar todas as possibilidades é inviável.

Como existem vários métodos diferentes de cifras de transposição, cada um necessita de uma abordagem diferente.

Nesses dois posts no StackExchange: [1] e [2], Ilmari Karonen mostra métodos para resolver manualmente cifras de transposição colunar.

Referências

Applied Cryptography, second edition

Exercícios

WeChall: Transposition I

Códigos

Aprenda várias formas de representar dados no computador e suas aplicações em CTFs.

Códigos

Dados e códigos

Nos computadores, todos os dados são guardados da mesma forma: em código binário. Esse código é como uma sequência de '0's e '1's, e essas sequências são agrupadas e sofrem modificações para representar tudo o que vemos em um computador.

Mas se tudo são apenas zeros e uns, o que diferencia um texto de uma música? A diferença é o modo como esses dados são representados.

Para cada tipo de dado existe uma codificação diferente aplicada a ela, e por isso um mesmo dado pode ter várias interpretações dependendo da codificação que você trabalha.

Um exemplo de uma representação de um valor binário é como um número.

Um número em binário pode ser convertido para um número em decimal. Por exemplo, 00101010 é o número 42 em decimal.

Uma representação mais comum para um código binário é a base hexadecimal, que tem a vantagem de que cada casa pode representar uma sequência de 4 bits. Por exemplo, o mesmo número 00101010 é 2A em hexadecimal (0010 = 2 e 1010 = A).

Nas próximas seções, você verá outras formas de representar os dados no computador.

Códigos

Código ASCII

Nessa seção, vamos apresentar uma das codificações mas famosas para representar texto em um computador: o ASCII.

O nome ASCII vem do inglês American Standard Code for Information Interchange que significa "Código Padrão Americano para o Intercâmbio de Informação"

O ASCII, originalmente baseado no inglês, codifica 128 caracteres específicos com 7 bits. Como um computador normalmente trabalha na escala de bytes (8 bits), o ASCII é mais frequentemente encontrado numa representação de 8 bits.

A tabela abaixo mostra todos os caracteres do código ASCII.

ascii-table.png

Você pode usar essa tabela para decodificar uma sequência de números em binário, decimal ou hexadecimal para ASCII.

ASCII em Python

Uma maneira mais fácil de manipular a codificação ASCII, em vez de usar manualmente uma tabela, é por meio de códigos. Em Python, usamos as funções ord() e chr() para isso.

A função ord() recebe uma string de tamanho 1 e retorna um inteiro que representa o código da letra, se ela for ASCII, devolverá seu código ASCII. Por exemplo, ord('a') devolverá 97.

Já a função chr() é o inverso da anterior. Ela recebe um inteiro e devolve o caractere com o respectivo código ASCII. Por exemplo, chr(97) devolverá 'a'.

Exercícios

WeChall: ASCII

WeChall: URL

Referências

ASCII table

Python Built-in Functions

Códigos

Base64

Agora que você já teve contato com o código ASCII, vamos conhecer o Base64, um método para codificar e decodificar dados binários em caracteres ASCII.

Esse método é utilizado frequentemente para transferir dados em meios que só suportam formatos ASCII, por exemplo, enviar anexos por e-mail (que usa o MIME).

O nome base64 origina-se do fato de que esse sistema é constituido de 64 caracteres, representando exatamente 6 bits de dados. Com isso, três bytes de 8 bits podem ser representados por 4 digitos de 6 bits em Base64.

A tabela abaixo mostra a equivalência entre os valores de um conjunto de 6 bits e os caracteres usados para codificação.

Quando os bits da mensagem original não são multiplos de 6, são adicionados zeros como padding. Assim, na mensagem codificada é colocado um = para cada dois zeros de padding. Aliás, esse = é uma forma bem comum de reconhecer um texto codificado em Base64.

Abaixo está um exemplo de um texto codificado em Base64:

texto:          M        |        a        |        n
8 bits:  0 1 0 0 1 1 0 1 | 0 1 1 0 0 0 0 1 | 0 1 1 0 1 1 1 0
6 bits:  0 1 0 0 1 1 | 0 1 0 1 1 0 | 0 0 0 1 0 1 | 1 0 1 1 1 0       
Valor:        19     |      22     |      5      |      46
texto:        T      |      W      |      F      |      u
(Base64)

E se tirarmos o n, a codificação vai necessitar de um padding:

texto:          M        |        a        |  
8 bits:  0 1 0 0 1 1 0 1 | 0 1 1 0 0 0 0 1 |  
6 bits:  0 1 0 0 1 1 | 0 1 0 1 1 0 | 0 0 0 1 0 0 | 0 0 0 0 0 0      
Valor:        19     |      22     |      5      |  (padding)
texto:        T      |      W      |      E      |      =
(Base64)

Ferramentas

Para manipular textos em Base64, pode-se usar o comando Unix base64.

Por exemplo, se tivermos uma arquivo sagan.txt com o texto The Cosmos is all that is or ever was or ever will be. Podemos convertê-lo para um arquivo sagan64.txt com o comando

base64 sagan.txt > sagan64.txt

O resultado será o arquivo sagan64.txt com o texto VGhlIENvc21vcyBpcyBhbGwgdGhhdCBpcyBvciBldmVyIHdhcyBvciBldmVyIHdpbGwgYmUK.

Agora, para decodificar o arquivo sagan64.txt, usamos o mesmo comando com a flag -d:

base64 -d sagan64.txt

Exercícios

OverTheWire: Krypton 0

Decodifique essa mensagem

Esteganografia

Aprenda como esconder uma mensagem em plena vista e suas aplicações em CTFs

Esteganografia

Cifra de Bacon

Nessa seção veremos um primeiro exemplo de Esteganografia: a Cifra de Bacon.

Ela tem esse nome pois foi criada por Francis Bacon em 1605.

A ideia por trás dessa cifra, diferente de uma cifra criptográfica comum, é esconder a mensagem secreta por meio de um texto legível, apenas mudando a grafia de suas letras.

Essa é uma cifra de substituição, e cada letra é representada por um conjunto de 5 caracteres binários ('a' e 'b' ou '0' e '1'). O alfabeto de substituição da Cifra de Bacon possui dois modelos:

A = aaaaa  I/J = abaaa    R = baaaa
B = aaaab    K = abaab    S = baaab
C = aaaba    L = ababa    T = baaba
D = aaabb    M = ababb  U/V = baabb
E = aabaa    N = abbaa    W = babaa
F = aabab    O = abbab    X = babab
G = aabba    P = abbba    Y = babba
H = aabbb    Q = abbbb    Z = babbb
A = aaaaa  I = abaaa  Q = baaaa  Y = bbaaa
B = aaaab  J = abaab  R = baaab  Z = bbaab
C = aaaba  K = ababa  S = baaba
D = aaabb  L = ababb  T = baabb
E = aabaa  M = abbaa  U = babaa
F = aabab  N = abbab  V = babab
G = aabba  O = abbba  W = babba
H = aabbb  P = abbbb  X = babbb

Dessa forma, substituímos o 'A' da mensagem secreta por 'aaaaa', um 'B' por 'aaaab' e assim por diante. Por exemplo, digamos que queremos esconder a mensagem fly you fools. Assim, a substituição das letras será da forma abaixo, usando a cifra de 26 letras:

texto original: F     L     Y     Y     O     U     F     O     O     L     S
texto cifrado:  aabab ababb bbaaa bbaaa abbba babaa aabab abbba abbba ababb baaba

Com isso, podemos usar esse padrão e esconder em uma mensagem comum de tamanho maior ou igual ao texto cifrado, como according to all known laws of aviation, there is no way a bee should be able to fly.

Assim, removendo os espaços e pontuações para facilitar a associação, podemos esconder a mensagem no texto de várias formas, como associar letras maiúsculas ao 'a' e minúsculas ao 'b', associar a letras com ou sem itálico ou até com duas fontes diferentes. Para esse exemplo, usaremos maíusculas e minúsculas.

falsa mensagem: accordingtoallknownlawsofaviationthereisnowayabeeshouldbeabletofly
texto cifrado:  aababababbbbaaabbaaaabbbababaaaabababbbaabbbaababbbaaba
mensagem final: acCoRdInGTOAllkNOwnlaWSOfAvIatioNtHeREIsnOWAyaBeESHouLdbeabletofly

Voltando à formatação original da mensagem, temos: acCoRdInG TO All kNOwn laWS Of AvIatioN, tHeRE Is nO WAy a BeE SHouLd be able to fly. Com isso, quem interceptar essa mensagem esteganográfica, não vai imaginar que ela possui algo além de uma escrita engraçada.

Identificando

Em uma primeira observação, uma mensagem oculta pela cifra de Bacon pode ser identificada pela mudança alternada dos padrões das letras: maíuscula e minúscula, itálico, fonte, ou até a alternância explícita de duas letras.

Outra abordagem, seria uma análise de frequência. Como a cifra de Bacon é um tipo de cifra de substituição, ela é sensível a uma análise de frequência.

Solucionando

Para solucionar desafios que contém Cifra de Bacon, o primeiro passo é identificar o modo como a mensagem foi escondida. Depois disso, é preciso percorrer o texto e transformá-lo em sequências de 'a's e 'b's.

Assim, você pode guardar o alfabeto de substituição com um dicionário e usá-lo para substituir os blocos de 5 caracteres pela letra correspondente.

Por exemplo, podemos implementar isso com um código em Python:

bacon_to_letter_26 = {
    'aaaaa':'A', 'aaaab':'B', 'aaaba':'C', 'aaabb':'D', 'aabaa':'E',
    'aabab':'F', 'aabba':'G', 'aabbb':'H', 'abaaa':'I', 'abaab':'J',
    'ababa':'K', 'ababb':'L', 'abbaa':'M', 'abbab':'N', 'abbba':'O',
    'abbbb':'P', 'baaaa':'Q', 'baaab':'R', 'baaba':'S', 'baabb':'T',
    'babaa':'U', 'babab':'V', 'babba':'W', 'babbb':'X', 'bbaaa':'Y',
    'bbaab':'Z'
}

def format(text, a='a', b='b'):
    """Format a steganographic text to a binary sequence"""
    formated_text = ''
    for c in text:
        if not c.isalpha():
            continue
        if c.istitle():
            formated_text += b
        else:
            formated_text += a
    return formated_text

def decode(text, a='a', b='b', bacon_alpha=bacon_to_letter_26):
    """Decode a encrypted Bacon cipher text"""
    cipher = format(text, a=a, b=b)
    output = ''
    while len(cipher) >= 5:
        token, cipher = cipher[:5], cipher[5:]
        if token in bacon_alpha:
            output += bacon_alpha[token]
        else:
            break
    return output

if __name__ == '__main__':
    input  = input()
    output = decode(input)
    print(output)

Exercícios

WeChall: Baconian

WeChall: Bacon Returns

Referências

Esteganografia

Interpretar imagem como texto

Como foi explicado na seção de dados e códigos, qualquer arquivo no computador pode ser interpretado como uma sequência binária, e dessa forma, tem sua representação em texto. Assim, esse recurso pode ser usado para esconder informação numa imagem.

Um recurso comum em CTFs é colocar um trecho de texto puro em alguma região arbitrária da imagem. Por exemplo, se queremos esconder a palavra such cake na imagem doge.jpg, podemos usar o comando Linux:

echo "such cake" >> doge.jpg

Com isso, "such cake" ficará no final dos dados da imagem.

Solucionando

Para extrair a informação escondida por esse método, várias ferramentas podem ser usadas. As duas principais são os comandos de Linux strings e hexdump.

O comando strings imprime basicamente todas as sequências de dados imprimíveis de um arquivo. Por exemplo, o comando aplicado a imagem doge.jpg

strings doge.jpg

Com isso, o final da saída do comando será algo da forma:

strings-example.png

Já o comando hexdump permite que a imagem seja analisada de forma mais minuciosa, onde o formato de leitura e impressão pode ser especificado pelo usuário. Por exemplo, um uso do comando com a imagem doge.jpg, onde a flag -C representa a forma canônica de impressão hex+ASCII:

hexdump -C doge.jpg

O final da saída desse comando é algo da forma:

hexdump-example.png

Exercícios

WeChall: Stegano I

picoCTF-2018: hex-editor

Referências

HowtoForge

Sanfoudry

Esteganografia

LSB: Least Significant Bits

Um dos métodos mais comuns e populares nos dias de hoje para se esconder uma mensagem numa imagem é a técnica de LSB ou Least Significant Bits. Esse método consiste em esconder a informação nos bits menos significativos de uma imagem.

Representação da imagem

Como mencionado em Dados e Códigos, todos os arquivos no computador são sequências binárias e com as imagens não é diferente.

Uma imagem é composta, na maioria das vezes, por duas partes. O cabeçalho (ou header) é onde ficam armazenadas as informações sobre a imagem, como o seu formato e dimensões. Já o corpo da imagem é onde ficam armazenados a informação dos seus pixels de fato.

Cada formato tem suas particularidades para representar um pixel, por simplicidade vamos considerar um pixel de 24 bits de uma imagem lossless.

Por exemplo, um pixel com a cor em RGB #ebc700 teria sua representação em binário como 11101011 11000111 00000000 onde

Red Green Blue
8 bits 8 bits 8 bits
11101011 11000111 00000000

Escondendo na imagem por LSB

Para esconder informação em uma imagem usando o método de LSB, alteraremos os bits menos significativos de cada byte no corpo da imagem.

Por exemplo, se temos uma imagem de três pixels

pixel 1: 11101011 11000111 00000000
pixel 2: 01000010 10000110 11110100
pixel 3: 11110100 01010111 01000010

Se queremos esconder o byte 01100001, uma nova imagem será gerada com a mensagem nos últimos bits (destacado por * * ).

pixel 1: 1110101*0* 1100011*1* 0000000*1*
pixel 2: 0100001*0* 1000011*0* 1111010*0*
pixel 3: 1111010*0* 0101011*1* 01000010

Dessa forma, ao esconder a mensagem nos bits menos significativos, fazemos apenas uma pequena alteração na imagem. Por exexmplo, o pixel 1 foi da cor #ebc700 para #eac701.

lsb_diff.png

Assim, vemos que a imagem precisa ser maior que a mensagem que vamos esconder nela. Nessa caso, no mínimo 8 vezes maior. Para contornar esse problema, alguns algoritmos usam 2 ou 3 bits menos significativos de cada byte, aumentando a alteração da imagem.

Para recuperar a mensagem, fazemos o processo inverso: identificando os bits menos significativos no corpo e remontando em bytes.

pixel 1: 1110101*0* 1100011*1* 0000000*1*
pixel 2: 0100001*0* 1000011*0* 1111010*0*
pixel 3: 1111010*0* 0101011*1* 01000010

-> mensagem: 01100001

Ferramentas para LSB

Stéganô

O pacote Stéganô possui várias ferramentas para esteganografia. A maioria sua a técnica de LSB.

Ele necessita de Python 3 e pode ser instalado por

sudo pip3 install Stegano

Uma das ferramentas desse pacote é o comando stegano-lsb.

Ele pode ser usado para esconder uma mensagem em uma imagem com o argumento hide, como por exemplo

stegano-lsb hide -i dog.png -o dog_steg.png -m "dont-worry-be-happy"

Já com o comando reveal, podemos recuperar a mensagem a partir da imagem.

stegano-lsb reveal -i dog_steg.png

Além disso, em vez de modificar os pixels sequncialmente a partir do começo, um outro comando, o stegano-lsb-set, permite inserir a informação de acordo com outros padrões especificados. Ele recebe um argumento para um gerador, como por exemplo eratosthenes, que produz os pontos onde os pixels serão modificados.

Assim, é preciso usar o mesmo gerador para esconder e recuperar a mensagem:

stegano-lsb-set hide -i dog.png -o dog_steg2.png -g eratosthenes -m "dont-worry-be-happy"

stegano-lsb-set reveal -i dog_steg2.png -g eratosthenes

zsteg

O zsteg é uma ótima e super simples ferramenta para detectar steganografia em imagem. Ela necessita de Ruby e pode ser instalada por

gem install zsteg

Para detectar uma informação escondida por um LSB simples, pode-se digitar apenas

zsteg dog_steg.png

O resultado será algo como

zsteg-example.png

Informações adicionais

Muitas vezes, a técnica de LSB pode ser usada junto a uma criptografia para proteger ainda mais a mensagem e dificultar sua detecção.

Na vida real, a técnica de LSB pode ser usada como marca d'água digital para detectar cópias de mídias não autorizadas. O programa OpenStego é um ótimo exemplo de software com essa finalidade.

Exercícios

(to-do)

Referências

Computerphile

Stéganô

zsteg

Esteganografia

Imagem em áudio

Mais uma forma interessante de esteganografia é esconder uma imagem em um áudio. Nela, a imagem é transformada em ondas sonoras de forma que ela pode ser vista através de seu espectrograma.

O espectrograma

Um espectrograma é uma forma de visualizar a intensidade de um sinal através do tempo e em várias frequências.

Os espectrogramas são gráficos de duas dimensões (frequência x tempo), com a terceira dimensão, a amplitude, sendo representada pela variação das cores. O tempo é normalmente representado no eixo x em sentido crescente. Já a frequência (medida em Hz) é representada no eixo y, com frequências mais baixas em baixo e mais altas em cima. Por fim, a amplitude (medida em dB) é representada com cores mais escuras para amplitudes menores e cores mais claras para maiores.

Para visualizar o espectrograma de um áudio, pode-se usar o programa sonic visualizer (mais simples) ou audacity (mais robusto).

Escondendo uma imagem em um áudio

Primeiro, precisamos realizar a conversão da imagem para o áudio. Isso pode ser feito utilizando a ferramenta img-encoder, no GitHub.

Por exemplo, se queremos converter a imagem aesthetic.png

aesthetic.png

No demo online dessa ferramenta, adicionamos a imagem em Open-Image..., e convertemos com Encode. Renomearemos o resultado para aesthetic.wav.

Utilizando o sonic-visualizer para visualizar o áudio gerado, mudamos a visualização para Add spectrogram, com o comando Shift+G.

sonic-visualizer-example.png

Agora, precisamos juntar esse áudio em outra música para camuflar a informação. Por exemplo, usaremos a música リサフランク420 現代のコンピュー.mp3. Abrindo a música com audacity, importamos o nosso áudio com Ctrl+Shift+i.

Com a ferramenta Time Shift Tool, podemos mudar a posição do áudio esteganográfico para o começo ou fim (assim a música vai interferir menos o áudio).

Porém, o áudio esteganográfico ainda pode ser percebido devido a seu ruído. Para diminuir esse efeito, primeiro selecionamos a track do áudio (clicando em uma 'área neutra' do Painel de Controle, na parte esquerda da track) e clicando em Effect e Amplify. Assim, podemos mudar a amplitude do som para dificultar sua detecção (algo em torno de -20 dB).

audacity-example.png

Assim, selecinando todas as tracks e exportando a música gerada para WAV, steg-macintosh-plus.wav, teremos uma música audível mas com uma imagem escondida em seu espectrograma.

sonic-visualizer-example2.png

Referências

PNSN: Espectrogramas

Selecionando Tracks no Audacity

Mental Floss

Esteganografia

O que é esteganografia?

Em um primeiro contato com a área, esteganografia provavelmente será o nome que lhe causará mais estranheza. O termo vem do grego steganos, que significa "encoberto, escondido" e graphein, que significa "escrita".

Esteganografia é a técnica de ocultar uma mensagem dentro de outra. Diferentemente da criptografia, onde torna-se a mensagem ilegível, a esteganografia procura esconder o fato de que a mensagem existe em primeiro lugar.

stegano-introduction.png

Assim, a falsa mensagem funcionará como uma espécie de cobertura da mensagem real, desviando a atenção de quem estiver buscando a mensagem real. Alguns exemplos poderiam ser o ato de escrever com tinta invisível entre as linhas de uma carta comum ou escrever um texto nos bits de uma imagem sem alterá-la visualmente.

Nas próximas seções, serão abordadas técnicas de esteganografia e suas aplicações em CTFs.

Sites para treinar

Sites para treinar

Bandit

O Bandit é um wargame para totais iniciantes, focado em programas/comandos de terminal do linux. Ele te ensina o básico para você conseguir progredir e te preparar para outros desafios.

Como funciona

Como a maioria dos jogos do tipo, ele é organizado em níveis. Você começa no nível 0 e tenta completá-lo. Ao terminá-lo, você consegue informações para começar o próximo nível (geralmente a senha do usuário do nível X + 1). Todos os níveis do Bandit têm uma página de explicação (vistas na barra lateral), que embora não estritamente necessárias, contém informações importantes sobre como como prosseguir ao próximo nível, além de comandos sugeridos.

Para poder jogar, tudo que você precisa é de um cliente de SSH.
Conecte-se em bandit.labs.overthewire.org na porta 2220.

É bem possível (e provável) que você encontre alguma situação em que você fique preso. Não se preocupe e não desista! O objetivo do jogo é te ensinar o básico, e para aprender, muitas vezes é preciso pesquisar. É muito importante saber usar eficientemente uma ferramenta de pesquisa como o Google ou o DuckDuckGo.

Tem muitas coisas que você pode tentar quando não souber exatamente como continuar:

Primeiro, se você sabe de algum comando (e no Bandit você sempre sabe quais comandos são necessários, porque eles estão na página do nível) mas não sabe usá-lo, você pode consultar o manual dele, utilizando o comando man <comando>. Por exemplo, se quiser saber como funciona o comando find, basta executar man find. Aliás, o próprio comando man tem um manual, então se você quiser ler um manual sobre o manual, só executar man man.

Se o comando não tiver uma página no manual, ele pode ser built-in do shell, então nesse caso você pode executar help <comando> para ver uma página de ajuda resumida.

Mas se nada der certo, você pode sempre pedir ajuda, seja no nosso Discord, Telegram, ou qualquer outro meio.

Divirta-se!