Slides

8 views
Skip to first unread message

Felipe

unread,
Sep 18, 2012, 2:05:06 PM9/18/12
to seguridad-...@googlegroups.com
Sobre shellcodes.

      Un SHELLCODE es un arreglo opaco de bytes que al ponerlos en memoria(ejecutable)
      y pasarle el control ejecuta un shell(o cualquier otra cosa).

Primero preparemos un programa que simule una situación de pos-explotación http://pastebin.com/Fus1b46S
Eso debería hacer ago como:
         1) Alocar memoria ejectutable
         2) Leer el contenido de un archivo(shellcode)
         3) Pasar el control

Listo. Ahora intentemos hacer un shellcode (cacho de mem que al pasarle el control imprime "YOU WIN!")
Consideremos el assembler del holamundo...

  1. .section .data
  2. message:
  3.     .ascii "YOU WIN!\n"
  4.     len = . - message
  5.  
  6. .section .text
  7. .globl _start
  8. _start:
  9.     #write mesaje to stdout
  10.     movl $len, %edx              # LEN
  11.     movl $message, %ecx          # BUFFER
  12.     movl $1, %ebx                # FD
  13.     movl $4, %eax                # WRITE
  14.     int $0x80                    # SYSCALL
  15.     #exit
  16.     movl $0, %ebx                # RETVALUE
  17.     movl $1, %eax                # EXIT
  18.     int $0x80                    # SYSCALL


Esto claramente tiene 2 "secciones" o cachos de memoria diferentes: .text y .data. El codigo vive en .text y message en .data.
Se ensambla asi:

 $ as -32 01-holamundo.s -o 01-holamundo.o 


Y podemos inspeccionar lo generado usando los comandos objdump, nm, readelf , od:

$ objdump -s 01-holamundo.o 

01-holamundo.o:     file format elf32-i386

Contents of section .text:
 0000 ba0b0000 00b90000 0000bb01 000000b8  ................
 0010 04000000 cd80bb00 000000b8 01000000  ................
 0020 cd80                                 ..              
Contents of section .data:
 0000 486f6c61 204d756e 646f0a             Hola Mundo.     


Lo importante es que tiene "relocations" es decir que hay diferentes secciones que se referencian entre si. En este caso en el código hay una referencia a message que esta' en otra sección.  Las relocations se pueden ver con el "-r":

$objdump -r 01-holamundo.o 

01-holamundo.o:     file format elf32-i386

RELOCATION RECORDS FOR [.text]:
OFFSET   TYPE              VALUE 
00000006 R_386_32          .data

Normalmente el loader (man ld) se ocupa de poner las secciones en memoria, asignar los permisos y resolver esas "relocations":

       ld combines a number of object and archive files, relocates their data and ties up symbol references.
       Usually the last step in compiling a program is to run ld.


Para construir un shellcode usando las toolchains clásicas necesitamos código que no tenga relocations y que use una sola sección. (o bien implementar el loader a mano (si en assembler)). Ok, para esto podemos hacer:

1) Mezclar todas las secciones en una sola => .text. 
     Los datos aparecerán a continuación del código(se pueden inventar otros layouts).
2) Las referencias a variables deben ser calculadas en función de offsets estáticos y 
    de la posición actual del código en memoria (que se obtiene de la pila haciendo un call).

El assembler queda con esta pinta. 

# BASIC SHELLCODE
.section .text                         #everything in one section
.globl _start 
_start:
    call dummy
dummy: #<--------------------------------\
    popl %ecx                           #address of dummy in ecx
    #write mesaje to stdout using int 80
    movl $len, %edx                     # LEN

    # add the distance from dummy tu message to get
    # the absolute pointer to message
    # no matter where this code is put in memory
    addl $offset_dummy_to_message, %ecx # buffer
    movl $1, %ebx                       # FD
    movl $4, %eax                       # WRITE
    int $0x80                           # SYSCALL
    #exit
    movl $0, %ebx                       # RETVALUE
    movl $1, %eax                       # EXIT
    int $0x80                           # SYSCALL

    # The GNU Assembler knows the sizes of intructions
    # and is able to calculate distances between labels
    # statically at 'assembling' time 
    offset_dummy_to_message = message-dummy   # This wont generate 
                                              # nothing in the binary 
message:
    # This is in the .text section and inmediatelly 
    # after the last instruction 
    .ascii "YOU WIN\n"
    len = . - message



Se ensambla asi:

$as -32 02-holamundo-shellcode.s -o 02-holamundo-shellcode.o

Esto genera un archivo ELF con una sola sección y sin "relocations". Se puede investigar con :

$objdump -S 02-holamundo-shellcode.o
$objdump -r 02-holamundo-shellcode.o

 Para sacar el binario correspondiente a la sección .text (también se puede ver con  objdump -D) usamos este python...

  1. from elftools.elf.elffile import ELFFile
  2. import sys
  3.  
  4. if len(sys.argv) != 3:
  5.         print "Usage:\t%s file.o file.bin"%sys.argv[0]
  6.         sys.exit()
  7.  
  8. #read the ELF object file
  9. elf = ELFFile(file(sys.argv[1]))
  10.  
  11. #read .text data (abort if not found)
  12. text = elf.get_section_by_name('.text').data()
  13. print "Section .text is %d bytes long"%len(text)
  14. print "Dumping .text section to %s ..."%sys.argv[2]
  15. file(sys.argv[2],"wb").write(text)
  16. print "done."

Adjunto un tgz con todo esto.
Cualquier consulta .. mail.

Salut!
f/
===
Ha llegado a mi atención que las slides de _la_ clase estan medio escondidas, entonces adjunto.
 
Seguridad.pdf
basic-shellcode.tgz
Reply all
Reply to author
Forward
0 new messages