Domanda

Questa è una shellcode di sfruttare la vulnerabilità buffer overflow. Imposta la setuid(0) e genera una shell utilizzando execve(). Qui di seguito è il modo in cui ho interpretato:

xor    %ebx,%ebx       ; Xoring to make ebx value 0
lea    0x17(%ebx),%eax ; adds 23 to 0 and loads effective addr to eax. for setuid()
int    $0x80           ; interrupt
push   %ebx            ; push ebx
push   $0x68732f6e     ; push address // why this address only????
push   $0x69622f2f     ; push address // same question
mov    %esp,%ebx
push   %eax
push   %ebx
mov    %esp,%ecx
cltd                   ; mov execve sys call into al
mov    $0xb,%al
int    $0x80           ; interrupt

Qualcuno può spiegare i passi interi in modo chiaro?

È stato utile?

Soluzione

int è il codice operativo per innescare un interrupt software. interrupt software sono numerati (da 0 a 255) e gestiti dal kernel. Nei sistemi Linux, interrupt 128 (0x80) è il punto di ingresso convenzionale per chiamate di sistema. Il kernel si aspetta che gli argomenti delle chiamate di sistema nei registri; in particolare,% eax registrare l'identifica quale chiamata stiamo parlando di sistema.

  1. Imposta% ebx a 0
  2. Calcola% ebx + 23 e memorizzare il risultato in% eax (il codice operativo è lea come "indirizzo effettivo carico", ma non di accesso alla memoria è coinvolto, questo è solo un modo subdolo di fare un'aggiunta).
  3. chiamata
  4. Sistema. % Eax contiene 23, che significa che la chiamata di sistema è setuid. Che utilizza la chiamata di sistema un argomento (la porta UID), reperibile in% ebx, che contiene convenientemente 0 a quel punto (è stato impostato nella prima istruzione). Nota: al ritorno, registri sono non modificato, eccetto% eax che contiene il valore restituito della chiamata di sistema, normalmente 0 (se la chiamata è stata un successo)
  5. .
  6. Push% ebx nello stack (che è ancora 0).
  7. Spingere $ 0x68732f6e sullo stack.
  8. Spingere $ 0x69622f2f in pila. Poiché la pila cresce "down" e poiché i processori x86 utilizzano poco codifica endian, l'effetto di istruzioni 4 a 6 è che% esp (stack pointer) ora punti in una sequenza di dodici byte, di valori 2f 2f 62 69 6e 2f 73 68 00 00 00 00 (in esadecimale). Questa è la codifica della stringa "// bin / sh" (con una terminazione pari a zero, e tre zeri in più in seguito).
  9. Sposta% esp al% EBX. Ora% ebx contiene un puntatore alla stringa "// bin / sh" che è stato costruito sopra.
  10. Push% eax nello stack (% eax è 0 a quel punto, è lo stato restituito da setuid).
  11. Push% ebx sullo stack (puntatore su "// bin / sh"). Istruzioni 8 e 9 di generazione in pila una matrice di due puntatori, il primo è il puntatore su "// bin / sh" e il secondo un puntatore NULL. Tale matrice è ciò che la chiamata di sistema execve utilizzerà come secondo argomento.
  12. Sposta% esp al% ECX. Ora% ecx punti nella matrice costruita con le istruzioni 8 e 9.
  13. Sign-estendono% eax in% edx:% eax. cltd è la sintassi AT & T per quello che la documentazione Intel chiamano cdq. Poiché% eax è zero, a quel punto, questo set% EDX a zero anche.
  14. Set% al (il byte meno significativo% eax) per 11. Poiché% eax era zero, l'intero valore di% eax è ora 11.
  15. chiamata
  16. Sistema. Il valore di% eax (11) identifica il chiamata di sistema come execve. execve prevede tre argomenti, in% EBX (puntatore ad una stringa di denominazione del file da eseguire),% ECX (puntatore a un array di puntatori a stringhe, che sono gli argomenti del programma, il primo è una copia del nome del programma, a essere utilizzato dal programma richiamato stessa) e% edx (puntatore a un array di puntatori a stringhe, che sono le variabili di ambiente;. Linux tollera tale valore per essere NULL, per un ambiente vuoto), rispettivamente

Quindi, il codice chiama prima setuid(0), quindi chiama execve("//bin/sh", x, 0) in cui i punti x ad un array di due puntatori, prima di essere un puntatore a "// bin / sh", mentre l'altro è NULL.

Questo codice è abbastanza contorto perché vuole evitare zeri: quando assemblati in opcode binari, la sequenza delle istruzioni usi solo non-zero byte. Ad esempio, se l'istruzione 12 era stato movl $0xb,%eax (modificando l'intera% eax a 11), allora la rappresentazione binaria di tale codice operativo avrebbe contenuto tre byte di valore 0. La mancanza di zero marchi quella sequenza utilizzabile come il contenuto di un zero stringa terminata C. Questo è inteso per attaccare programmi buggy attraverso buffer overflow, naturalmente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top