Format Strings
Basic Information
Em C printf
é uma função que pode ser usada para imprimir alguma 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 aparece quando um texto de atacante é usado como o primeiro argumento para essa função. O atacante será capaz de criar uma entrada especial abusando das capacidades da string de formato printf para ler e escrever qualquer dado em qualquer endereço (legível/escrevível). Sendo capaz assim de executar código arbitrário.
Formatters:
Exemplos:
Exemplo vulnerável:
Uso Normal:
Com Argumentos Faltando:
fprintf vulnerável:
Acessando Ponteiros
O formato %<n>$x
, onde n
é um número, permite indicar ao printf para selecionar o n-ésimo parâmetro (da pilha). Então, se você quiser 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 ler diretamente o quarto.
Observe que o atacante controla o parâmetro printf
, 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 endereços arbitrários na pilha e fazer com que printf
os acesse. Na próxima seção, será explicado como usar esse comportamento.
Leitura Arbitrária
É possível usar o formatador %n$s
para fazer printf
obter o endereço situado na n posição, seguindo-o e imprimí-lo como se fosse uma string (imprimir até que um 0x00 seja encontrado). Então, 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:
Observe que você não pode colocar o endereço 0x8048000 no início da entrada porque a string será cortada em 0x00 no final desse endereço.
Encontrar offset
Para encontrar o offset da sua entrada, você pode enviar 4 ou 8 bytes (0x41414141
) seguidos de %1$x
e aumentar o valor até recuperar os A's
.
Last updated