¿Por qué strace no muestra que se está realizando una llamada al sistema en shellcode?

4

Soy nuevo en shellcoding. He escrito el código de montaje:

section .text
global _start

_start:
 jmp end

start:
  ;open file
  pop ebx ; get address of filename
  xor eax,eax
  mov [ebx+3], al
  mov al,5
  xor ecx,ecx
  mov edx,777
  int 80h
  ;exit

  xor eax,eax
  mov al,1
  mov ebx,1
  int 80h

end:
   call start
   db "AAAA"

Sin embargo, cuando verifico si la llamada al sistema "sys_open" se está realizando o no usando la herramienta "strace", no muestra ninguna llamada al sistema relacionada con la apertura de archivos.

¿Qué pasa con mi código de shell ???

salida "strace":

rakesh@rakesh-VirtualBox:~/shellcode$ strace ./a.out 



execve("./a.out", ["./a.out"], [/* 21 vars */]) = 0
brk(0)                                  = 0x6cf000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c53efe000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=62357, ...}) = 0
mmap(NULL, 62357, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7c53eee000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "7ELF
section .text
global _start

_start:
 jmp end

start:
  ;open file
  pop ebx ; get address of filename
  xor eax,eax
  mov [ebx+3], al
  mov al,5
  xor ecx,ecx
  mov edx,777
  int 80h
  ;exit

  xor eax,eax
  mov al,1
  mov ebx,1
  int 80h

end:
   call start
   db "AAAA"
rakesh@rakesh-VirtualBox:~/shellcode$ strace ./a.out 



execve("./a.out", ["./a.out"], [/* 21 vars */]) = 0
brk(0)                                  = 0x6cf000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c53efe000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=62357, ...}) = 0
mmap(NULL, 62357, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7c53eee000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "7ELF%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%>%pre%%pre%%pre%%pre%0%pre%%pre%%pre%%pre%%pre%"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1815224, ...}) = 0
mmap(NULL, 3929304, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7c5391e000
mprotect(0x7f7c53ad3000, 2097152, PROT_NONE) = 0
mmap(0x7f7c53cd3000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7f7c53cd3000
mmap(0x7f7c53cd9000, 17624, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7c53cd9000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c53eed000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c53eec000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c53eeb000
arch_prctl(ARCH_SET_FS, 0x7f7c53eec700) = 0
mprotect(0x7f7c53cd3000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ)     = 0
mprotect(0x7f7c53f00000, 4096, PROT_READ) = 0
munmap(0x7f7c53eee000, 62357)           = 0
fstat(1, {st_mode=03260764276, st_size=140733642434881, ...}) = 3
write(1, "20377%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%20377%pre%%pre%60377%pre%%pre%"..., 777 <unfinished ... exit status 1>
%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%>%pre%%pre%%pre%%pre%0%pre%%pre%%pre%%pre%%pre%"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1815224, ...}) = 0 mmap(NULL, 3929304, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7c5391e000 mprotect(0x7f7c53ad3000, 2097152, PROT_NONE) = 0 mmap(0x7f7c53cd3000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7f7c53cd3000 mmap(0x7f7c53cd9000, 17624, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7c53cd9000 close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c53eed000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c53eec000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c53eeb000 arch_prctl(ARCH_SET_FS, 0x7f7c53eec700) = 0 mprotect(0x7f7c53cd3000, 16384, PROT_READ) = 0 mprotect(0x600000, 4096, PROT_READ) = 0 mprotect(0x7f7c53f00000, 4096, PROT_READ) = 0 munmap(0x7f7c53eee000, 62357) = 0 fstat(1, {st_mode=03260764276, st_size=140733642434881, ...}) = 3 write(1, "20377%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%20377%pre%%pre%60377%pre%%pre%"..., 777 <unfinished ... exit status 1>
    
pregunta Rakesh Mane 29.01.2017 - 17:37
fuente

3 respuestas

3

Tengo la solución. En realidad, por error compilé el programa de prueba de Shellcode como un ejecutable de 64 bits y por eso se ejecutó el código de shell en 64 bits y en modo de 64 bits el syscall no 5 es para "fstat" y eso es lo que mostraba la herramienta strace.

    
respondido por el Rakesh Mane 29.01.2017 - 21:13
fuente
3

Estoy editando esta respuesta para eliminar la confusión sobre -e open . -e solo filtra y no agregará información adicional al registro de strace. El único caso cuando strace no está registrando open syscalls es cuando un subproceso bifurcado los está invocando y el parámetro -f no está establecido, lo que no es relevante en su caso.

    
respondido por el Rápli András 29.01.2017 - 17:42
fuente
2

En la arquitectura amd64, e incluso en las CPU x86 más recientes, las llamadas al sistema se realizan con el código de operación sysenter y ya no con un int 80h . La salida de strace muestra claramente que compiló su código en un amd64, a pesar de que solo usó instrucciones x86 y registros de 32 bits (puedo ver que utiliza punteros de más de 32 bits).

Las diferencias se manejan con una biblioteca compartida de una sola página, asignada por el núcleo al espacio de usuario (libvdso). Su aplicación solo debe llamar a este libvdso igual que las funciones normales.

La forma más fácil de encontrar su formato si compilas un código C mínimo de forma estática y lo desarmas (si no quieres usar incluso el glibc).

    
respondido por el peterh 29.01.2017 - 19:40
fuente

Lea otras preguntas en las etiquetas