Sess.io

Long sessions must be secure, right?

Você pode acessar os arquivos do desafio no nosso repositório https://github.com/HawkSecUnifei/Writeupsarrow-up-right

Ao fazer login, nos deparamos com uma tela de login. Temos a opção de pegar o código fonte da página.

Página inicial

Analisando o código, vemos que a flag é dividida em segmentos de 4 bytes. Temos também a função session_id_secure() que recebe o nome de usuário e senha concatenados. Vamos então analisar essa função

Essa função utiliza mt_rand() para gerar números pseudoaleatórios, mas antes disso, inicializa a seed do gerador (mt_srand()) com um valor derivado de $SEEDS. Esse array contém os segmentos da flag e a posição utilizada é determinada pelo primeiro caractere do hash md5($id), tomado como um número hexadecimal (0-9A-F) e reduzido ao intervalo válido pelo operador módulo (% count($SEEDS)).

Após definir a seed, a função gera um identificador de sessão composto por 1000 caracteres aleatórios escolhidos de ALPHA.

O problema é que mt_srand() torna a sequência gerada por mt_rand() completamente previsível. Com ferramentas como php_mt_seedarrow-up-right, podemos recuperar a seed utilizada a partir dos valores gerados.

Como o primeiro caractere do hash md5 sempre será um hexadecimal (0-9A-F), há no máximo 16 possíveis índices dentro do array $SEEDS. Isso significa que, ao testar diferentes entradas (username e password), conseguimos inferir qual segmento da flag foi usado como seed e, consequentemente, extrair partes dela.

Podemos agora fazer um script python para explorar de forma automática e achar a flag

circle-info

O código pode demorar bastante para rodar dependendo do seu hardware.

Atualizado