Perché strace non sta mostrando la chiamata di sistema effettuata nello shellcode?

4

Sono nuovo di shellcoding. Ho scritto codice assembly:

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"

Tuttavia, quando controllo la chiamata di sistema "sys_open" o non utilizzando lo strumento "strace", non mostra alcuna chiamata di sistema relativa all'apertura del file.

Cosa c'è di sbagliato con il mio shellcode ???

"strace" output:

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>
    
posta Rakesh Mane 29.01.2017 - 17:37
fonte

3 risposte

3

Ho trovato la soluzione. In realtà per errore ho compilato il programma di test dello shellcode come eseguibile a 64 bit ed è per questo che lo shellcode è stato eseguito come 64 bit e in modalità 64bit il syscall n. 5 è per "fstat" ed è quello che lo strace tool stava mostrando.

    
risposta data 29.01.2017 - 21:13
fonte
3

Sto modificando questa risposta per ripulire la confusione su -e open . -e esegue solo il filtraggio e non aggiunge ulteriori informazioni al registro strace. L'unico caso in cui strace non sta registrando open syscalls è quando un sottoprocesso a forcella li sta richiamando e il parametro -f non è impostato, che non è rilevante nel tuo caso.

    
risposta data 29.01.2017 - 17:42
fonte
2

Sull'architettura amd64 e anche su cpus x86 più recenti, le chiamate di sistema avvengono con sysenter opcode e non più con int 80h . Il tuo output strace mostra chiaramente che hai compilato il tuo codice in un amd64, nonostante tu abbia usato solo le istruzioni x86 e i registri a 32 bit (posso vedere che usa 32+ puntatori di bit).

Le differenze sono gestite con una lib condivisa a pagina singola, mappata dal kernel nello spazio utente (libvdso). La tua app dovrebbe chiamare questa libvdso solo come le normali funzioni.

Il modo più semplice per trovare il loro formato se si compila staticamente un codice C minimale e lo si disassembla (se non si vuole usare nemmeno glibc).

    
risposta data 29.01.2017 - 19:40
fonte

Leggi altre domande sui tag