Format Strings
Informação Básica
Em C, printf
é uma função que pode ser usada para imprimir uma string. O primeiro parâmetro que essa função espera é o texto bruto com os formatadores. Os parâmetros seguintes esperados são os valores para substituir os formatadores do texto bruto.
Outras funções vulneráveis são sprintf()
e fprintf()
.
A vulnerabilidade ocorre quando um texto do atacante é usado como o primeiro argumento para essa função. O atacante será capaz de criar uma entrada especial abusando das capacidades de strings de formato printf para ler e escrever quaisquer dados em qualquer endereço (legível/gravável). Sendo capaz, dessa forma, de executar código arbitrário.
Formatadores:
Exemplos:
Exemplo vulnerável:
Uso Normal:
Com Argumentos Ausentes:
fprintf vulnerável:
Acessando Ponteiros
O formato %<n>$x
, onde n
é um número, permite indicar ao printf para selecionar o parâmetro n (da pilha). Portanto, se você deseja ler o 4º parâmetro da pilha usando printf, você poderia fazer:
e você leria do primeiro ao quarto parâmetro.
Ou você poderia fazer:
e leia diretamente o quarto.
Observe que o atacante controla o parâmetro pr
intf
, o que basicamente significa que sua entrada estará na pilha quando printf
for chamado, o que significa que ele poderia escrever endereços de memória específicos na pilha.
Um atacante controlando essa entrada será capaz de adicionar um endereço arbitrário na pilha e fazer com que o printf
acesse-os. Na próxima seção será explicado como usar esse comportamento.
Leitura Arbitrária
É possível usar o formatador %n$s
para fazer com que o printf
obtenha o endereço situado na posição n, seguindo-o e imprimi-lo como se fosse uma string (imprimir até encontrar um 0x00). Portanto, se o endereço base do binário for 0x8048000
, e sabemos que a entrada do usuário começa na 4ª posição na pilha, é possível imprimir o início do binário com:
Note que não pode colocar o endereço 0x8048000 no início da entrada, pois a string será concatenada com 0x00 no final desse endereço.
Encontrar o deslocamento
Para encontrar o deslocamento para a sua entrada, você pode enviar 4 ou 8 bytes (0x41414141
) seguidos por %1$x
e aumentar o valor até recuperar os A's
.
Last updated