obj2s.sh – Objdump para Shellcode (Shell Script)

Introdução

No último post eu mostrei como transformar a saída do objdump em shellcode utilizando somente comandos do sistema. Após publicar o material, percebi que seria útil envolver todos aqueles comandos em um arquivo e criar um script, e foi isso que fiz.

Problemas

Percebi também que a solução do post anterior contém alguns problemas. O maior deles é que se ocorre um jump relativo, por exemplo, o endereço de salto é casado pelo sed que irá colocar um \x nele. O script postado aqui hoje resolve esse problema fazendo uma leitura somente dos bytes da shellcode, sem casar com o endereço das instruções de salto.

Uma coisa que deixei de falar foi em relação a plataforma. Eu considerei uma máquina x86-32 bits e por isso fiz algumas considerações exclusivas a essa plataforma, como o tamanho máximo das instruções (parâmetro do cut).

Sabendo disso, o script só funcionará para a plataforma x86-32 porque é necessário saber de antemão o tamanho máximo das instruções. Entretanto, se você programa em shell script ou tem uma pequena noção, ficará fácil alterar o script para que ele funcione em uma plataforma específica.

O script

Segue o código:

#!/bin/bash
#[obj2s.sh]
# Transforma a saída do objdump em shellcode
# OBS: Script testado em uma máquina IA-32
#
# [Autor]
# Marcos Paulo Ferreira (Daemonio)
# undefinido gmail com
# daemoniolabs.wordpress.com
#
# [Como usar]
# $ objdump -d programa | ./objs
# ou
# $ objdump -d programa | ./objs -1
# A opção '-1' gera somente a shellcode,
# excluindo as instruções em assembly.
#
# Versão 1.0, by daemonio @ Sun Mar 18 15:07:21 BRT 2012
# Versão 1.1, by daemonio @ Sun Aug 12 14:04:29 BRT 2012
#     - Corrigido o erro que ignorava alguns endereços.
#       O erro estava no primeiro grep da linha 48.
#

# Se '1', gera shellcode com comentário
COMM=1

# Função de conversão
function obj2s {
if [ "$COMM" = "0" ]
then
    cut -f1-7 -d' ' | tr -d ' ' | sed 's/../\\x&/g;1s/^/"/;$s/$/"/' | paste -s -d ''
else
    sed 's/\([0-9a-f][0-9a-f] \)\{1,7\}/&\n/;' | sed 's/ //g;s/../\\x&/g;N;s,\(.*\)\n *\(.*\),"\1" /* \2 */,' | column -t
fi
}

#
# Main
#

# Testa linha de comando
[ "$1" = "-1" ] && COMM=0

# Nome do vetor
echo 'char shellcode[] = '

# Shellcode
grep '[0-9a-f]:' | grep -v file | cut -f2 -d: | tr -d '\t' | obj2s

# Dois pontos do fim da declaração
echo ';'

#EOF

Uso

Usá-lo é simples, basta passar a saída do objdump para ele:

$ objdump -d shellexecve | ./obj2s.sh
char shellcode[] = 
"\x6a\x0b"              /*  push  $0xb         */
"\x58"                  /*  pop   %eax         */
"\x99"                  /*  cltd  */
"\x52"                  /*  push  %edx         */
"\x68\x2f\x2f\x73\x68"  /*  push  $0x68732f2f  */
"\x68\x2f\x62\x69\x6e"  /*  push  $0x6e69622f  */
"\x89\xe3"              /*  mov   %esp,%ebx    */
"\x31\xc9"              /*  xor   %ecx,%ecx    */
"\xcd\x80"              /*  int   $0x80        */
;

$ objdump -d shellexecve | ./obj2s.sh -1
char shellcode[] = 
"\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80"
;

Conclusão

Até então esse script tem funcionado perfeitamente em meus testes. Qualquer erro ou dica de implementação fique livre para comentar.

Deixe um comentário