Newsgroup: it.comp.os.dibattiti
Titolo: Dubbio esistenziale

So (o almeno credo di ricordare) che una delle peculiarità dell'architettura
NT è quella di separare l'area di memoria del codice da quella -accessibile
all'utente- dei dati.
Cosa che a suo tempo fu una grande innovazione rispetto a OS/2 che invece,
al pari di windows, condivideva codice e dati in un'unica area di memoria,
col risultato che, essendo per forza l'area dati accessibile a chi *usa* un
programma, si poteva con facilità mandare il codice in crash.
E allora mi chiedo: perchè i buffer overflow danno tanto fastidio a NT e
derivati? Non dovrebbero essere immuni ad ogni attacco di questo tipo, in
base al principio suesposto?
saluti incasinati

 base al principio suesposto?
Anche se un buffer overflow causa il cambiamento di
un puntatore che viene usato per qualche scrittura?
Tra l'altro e` si vero che il codice e` protetto,
ma se hai:
void (tip)(void);
char trick[] = { ... /* qualche byte */ ...};
....
tip = ()(void)trick; /* non ricordo esattamente... */
tip();
...
Potrebbe anche funzionare...
Il che consentirebbe di eseguire codice che _non_ si
trova nell'area programma.
Cioe` non modifichi l'area programma, semplicemente
scrivi dove puoi e magari modifichi un jump...
bye,
-- 
piergiorgio


$ cd /pub
$ more beer

 base al principio suesposto?
Infatti, non funziona esattamente cosě.
Un articolo interessante...
http://www.siforge.org/articles/2003/02/23-win-exploit.html
 

 scrivi dove puoi e magari modifichi un jump...
Bravo, modifichi un jump! E come fai se l'istruzione jump si trova in
un'area di memoria protetta?
saluti incomprensibili

 un'area di memoria protetta?
1) il return point di una subroutine e` sullo
stack, cioe` area dati, non programma.
2) un function pointer e` nell'area dati, non
programma.
Basta?
bye,
-- 
   Piergiorgio Sartor

 
http://www.siforge.org/articles/2003/02/23-win-exploit.html
Molto parziale, l'exploit č basato su bladeenc che gira su piattaforma
windows9x.
C'č da considerare che, se il programma in questione č buggato e fa una
(
p.es
.) jump in area dati, tutto il meccanismo di protezione va a carte
quarantotto (č il caso di bladeenc?).
Basta questo a dire che il meccanismo di divisione dell'area codice e dati
di NT "non funziona esattamente cosě"? Credo di no.
saluti enigmatici

 programma.
Scusa, ma l'area dati non serve solo al passaggio dei parametri? Ci gira
anche del codice?
Io ricordo (forse mi sbaglio) che l'area non protetta serviva solo allo
scambio di parametri, se ci gira codice il meccanismo di protezione serve a
ben poco.
saluti dubbiosi

 ben poco.
Non ci "gira" codice, ci stanno dati, ma fra i
dati ci sono anche "indirizzi" di esecuzione.
Quando, ad es. in C, hai una chiamata a funzione,
quello che succede e` che l'indirizzo di ritorno,
cioe` l'indirizzo del codice subito dopo il jump
alla funzione, viene salvato sullo stack.
Alla fine della funzione, questo indirizzo viene
usato da un altro jump per tornare a quel punto.
Se questo _dato_, che sta sullo stack, cioe`
nell'area _dati_, viene modificato, il jump di
ritorno salta da qualche altra parte.
Se un buffer overflow riesce a modificare lo stack,
allora puo` cambiare tutti i dati dello stack,
inclusi il punto di ritorno di una eventuale funzione
che e` in esecuzione in quel momento, magari proprio
la funzione che cause l'overflow...
bye,
-- 
   Piergiorgio Sartor

 quarantotto (č il caso di bladeenc?).
Aridaie, non fa nessun salto nell'area dati,
semplicemente gli indirizzi di jump _stanno_
nell'area dati, che risulta modificabile.
bye,
-- 
   Piergiorgio Sartor

 alla funzione, viene salvato sullo stack.
Ok, questo è logico e normale; pensavo che lo stack fosse diverso da quella
che viene definita "area dati per il passaggio dei parametri".
Se quell'area (non protetta) contiene anche lo stack con gli indirizzi di
ritorno, il meccanismo di protezione del codice di NT è una puttanata
galattica, perchè ovviamente lo stack è modificabile, e l'utente può
eseguire codice con le autorizzazioni (
p.es
.) di una dll che gira con
privilegi maggiori.
Per questo mi chiedevo come mai NT teme tanto i buffer overflow; se è come
dici la cosa è *tristemente* evidente.
saluti lampanti

 dici la cosa è *tristemente* evidente.
Ma non solo NT, la cosa succede in ogni caso in
cui il codice "critico" non controlla/limita un
eventuale buffer.
Il problema, poi, e` se il codice in questione
e` semplice "user code" o "supervisor code".
Ovviamente, nel secondo caso, la situazione e`
davvero grave, mentre nel primo si puo` anche
sopravvivere (dipende, magari non un web server).
L'esempio di bladeenc non credo possa inficiare
la sicurezza complessiva della macchina, dato che
comunque gira solo in user mode (spero...).
bye,
-- 
   Piergiorgio Sartor

 dei parametri" per eccellenza... :-)
Certo che sě! Non l'ho pensato subito proprio perchč, ai tempi dell'uscita
di NT, Microsoft fece un gran battage proprio su questo punto, e allora
pensavo che lo stack facesse comunque parte dell'area di memoria protetta,
cioč che l'area per il passaggio dei parametri fosse stata separata.
saluti delusi

 di NT "non funziona esattamente così"? Credo di no.
Forse non è chiaro lo scopo dell'esempio.
L'exploit approfitta della vulnerabilità per andare a scrivere
direttamente nello stack. L'exploit NON modifica il codice del programma
in memoria (situazione peraltro protetta).

 in memoria (situazione peraltro protetta).
Pensavo che lo stack fosse protetto come il codice, dato che ms a suo tempo
strombazzò alquanto sull'architettura che separava codice e dati. E' ovvio
che se lo stack è scrivibile con i diritti dell'utente (con gli stessi
diritti con cui si passa un parametro ad una dll di sistema), tutta la
sicurezza va a farsi benedire.
saluti benedetti

 la funzione che cause l'overflow...
Ciao Piergiorgio,
Premessa: non so che tool/metodi vengono usati per provocare, da exploit
conosciuti, un buffer overflow ed un code injection.
Domanda: che cosa comporta, nel metodo usato per operare l'exploit, ed in
particolare il code injection, il fatto che ci sia uno stesso daemon buggato in
ascolto, ma su architetture hardware diverse e magari anche sistemi operativi
diversi?
Riformulo la domanda piu' concretamente: all'atto pratico: dal punto di vista
dell'hacker, cosa cambia nelll'explitare un sendmail buggato stessa versione su
linux debian intel, e su linux debian dec alpha?
bye G.L.
--
La logica non attiene alla verosimiglianza delle ipotesi,
ma alla coerenza delle tesi con le ipotesi.

 sicurezza va a farsi benedire.
Su quel versante c'e' poco da fare per qualsiasi S.O. l'unica difesa
possibile e' la verifica paranoica dei parametri che vengono passati
e mantenere fuori dalle palle (del kernel) tutto il codice non
strettamente necessario (leggasi driver delle schede grafiche):
quello che non esiste (in kernel mode) non fa danno (almeno al kernel).
NT 3.x da questo punto di vista e' (stato) meglio dei successivi,
ma d'altronde e' noto a mamma MS interessa molto di piu' che gli
utenti stiano sotto
\user in NT 3.x
sotto
\WinNT\Profiles in NT 4.0
e sfanculati tra
\Profiles e \Documents and Settings
in Win2000 e XP (almeno per quanto riguarda All Users e Administrator)
Questo sicuramente rende piu' divertente il passaggio da una versione
all'altra di Windows (quei cazzoni di utenti Unix si trovano gli
utenti sotto /home da tempo immemore, sai che palle...)
In ogni caso dipende molto da cosa deve fare il sistema: un crash
di OpenOffice con perdita totale delle 400 pagine di tesi non salvata
a causa di X-Windows e' perfettamente equivalente alla perdita di
400 pagine di tesi non salvata a causa di un BSOD.
Che Linux resti in piedi dopo il crash di X potrebbe non fregare una
mazza a nessuno (per quanto riguarda il giramento di palle).
C:\>iao Angelo
[1] La separazione tra dati e codice e' una "condicio sine qua non"
    per avere in memoria un'unica copia del codice e la multi utenza
    e' una novita' recente solo per il mondo MS.
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 sicurezza va a farsi benedire.
In realta' ogni processo ha 2 stack. Uno stack di sistema e uno stack
utente che risiedono in 2 zone diverse. L'unico modo per fare danno e'
toccare lo stack di sistema che l'OS ha riservato a quel processo in un
dato punto della memoria. Lo stack di processo e' quello che risiede
(nei processori a 32bit) a partire da 0xfff fff nella VM del processo. 
Attaccare invece lo stack di sistema (che e' quella che si usa dopo una 
supervisor call) invece puo' portare a notevoli frutti in questo senso
visto che hai tutti i diritti se non ritorna correttamente dalla SVC.
Il Tanenbaum ne parla in un capitolo anche se la sua spiegazione e'
parecchio semplicistica.
-- 
try: troll.uses(Brain)
except TypeError, data: 
   troll.plonk()
Co-Responsabile Hardware Information & Technology 
http://hit.edengames.net

 linux debian intel, e su linux debian dec alpha?
Immagino, principalmente, l'hacker debba sapere
di che CPU si tratta, in modo da poter inserire
il codice il linguaggio macchina opportuno.
Se poi la CPU dovesse supportare diversi meccanismi
di protezione della memoria, le cose potrebbero
cambiare ancora.
Ad es. se lo stack e lo heap fossero a tutti
gli effetti separati e protetti, forse non sarebbe
cosi` facile passare i dati da uno all'altro.
bye,
-- 
   Piergiorgio Sartor

     e' una novita' recente solo per il mondo MS.
Recente non direi, visto che si parla di quasi dodici anni fa.
saluti separati

 visto che hai tutti i diritti se non ritorna correttamente dalla SVC.
Evidente, e allora mi chiedo ancora, che senso ha non proteggere lo stack di
sistema?
Io mi aspetto di poter pasticciare il codice come mi pare, ma solo in aree
di memoria a me accessibili coi diritti che mi porto dietro.
saluti autorizzati

 Recente non direi, visto che si parla di quasi dodici anni fa.
Dipende dalla scala dei tempi.
Tenendo presente che all'epoca Unix aveva gia' piu' di 20 anni e
non e' stato certo il primo S.O. multiutente... :-)
C:\>iao Angelo


 come dici la cosa è *tristemente* evidente.
La cosa *tristemente* evidente è che non è un problema di NT. Ne mi
risulta che NT "tema" i buffer overflow più di altri sistemi, non capisco
perchè dovrebbe.

 Non so se sia possibile e non so se abbia senso. I parametri di
E` possibile, ma forse l'overhead e` troppo
perche` sia effettivamente praticabile.
bye,
-- 
   Piergiorgio Sartor

 di memoria a me accessibili coi diritti che mi porto dietro.
Sinceramente non lo so. Credo che sia una cosa poco utile da
implementare sull'OS visto che la protezione ci puo' far poco se da root
faccio sovrascrivere zone di memoria sulle quali ho i diritti essendo
root... Il problema sta nella capacita' del programmatore di evitare
questo problema.


 root...
Se uno è root sono cazzi sua! :-)
saluti premeditati

 perchč dovrebbe.
Non facevo paragoni tra NT ed altri sistemi, d'altronde si sa che i buffer
overflow fanno bei danni anche sotto *nix.
saluti salomonici

 a nessuno (per quanto riguarda il giramento di palle).
Uff... che monotonia. Ti prometto la prima volta che perderò un po' di
lavoro a causa di un bsod di 2000/XP sarai il primo a saperlo, per ora
lasciami godere della mia immensa fortuna visto che il portatile in 3 anni
di onorato servizio non ne ha ancora visto uno... :-P 
A proposito: che c'entra con gli exploit? Già, rammentare windows che
crasha è come dire "piove governo ladro" :-)

non e' stato certo il primo S.O. multiutente... :-)
Si pero all'epoca il costo di Unix era di molto superiore ad un NT
senza parlare poi del fatto che l'unico che mi ricordo che girasse un
piattaforma Intel era lo SCO.

 lavoro a causa di un bsod di 2000/XP sarai il primo a saperlo...
in effetti io non ho quasi mai visto un bsod, un paio di volte a causa di
overclock spinti oltre ogni umana decenza.
Probabilmente dipende dai drivers che si installano, ma se uso linux non è
certo a causa dell'instabilità di win2k.
O perchè non trovo la versione delle dll! :-)
saluti stabili

 Se uno è root sono cazzi sua! :-)
Eh no. Se voglio accedere al sottosistema posix (per es.) per fare una
read(); non lo posso fare da utente ma devo fare una SVC e da supervisor
sono dio...


 il codice il linguaggio macchina opportuno.
Suppongo possa compilare il codice malizioso da sorgente, altrimenti diventa dura...


 Suppongo possa compilare il codice malizioso da sorgente, altrimenti diventa dura...
Uhm, certo, ma forse non e` sempre fattibile,
magari serve un controllo piu` fine, non saprei.
bye,
-- 
   Piergiorgio Sartor

 č certo a causa dell'instabilitą di win2k.
Idem.

 crasha è come dire "piove governo ladro" :-)
Lamentazioni a braccio sul fatto che mamma MS e' molto piu' sensibile
allle cazzate (es. layout delle directory e dell'interfaccia grafica)
che alla cose sostanziali: non lo facevo da almeno tre giorni :-)
C:\>iao Angelo


 Idem.
Se e' per questo nemmeno il sottoscritto usa Linux perche' gli crasha
Windows. Io lo trovo piu' divertente e piu' sicuro per andare in
giro su Internet: ma ho avuto anche io la mia bella inchiappettata
e non a causa di un dialer. Se uno e' fesso e' fesso sotto qualsiasi
S.O. :-(
C:\>iao Angelo


 che alla cose sostanziali: non lo facevo da almeno tre giorni :-)
Crisi d'astinenza?
bye,
-- 
   Piergiorgio Sartor

 ringraziarti :-)
Beh, allora mi raccomando prova quando hai aperto openoffice con una tesi
di 400 pagine non salvata. Almeno la prossima volta che reiteri l'esempio
potrai avere un granulo di fondatezza :P

 magari serve un controllo piu` fine, non saprei.
E' lavoro di fino... da hacker infatti.   :-)


 al principio suesposto?
non fintantochè CreateThread alloca uno stack eseguibile
-- 
  < 
http://www.reactos.com/
 >  Open source clone of Windows NT. Current
      Don't stand, REACT!      version 0.1.1. C, C++ and ASM developers
                               and beta testers are welcome!

 altri os no di certo >:)
io non leggo "innovazione". Tu forse leggi "innovazione" ovunque. Forse 
sulla bottiglia di latte, di mattina, leggi "innovazione". La marca dei 
biscotti ti appare come "innovazione". I titoli scorrevoli di RaiNews24 
ripetono "innovazione" (succede anche a me con "uccidili tutti". Questo 
prima del caffè). Però io leggo, al più, "peculiarità". Almeno questo è 
quello che hai quotato


 ai tempi del DOS, in una certa misura
Uhm, proprio no, sotto dos andavi a leggere e scrivere dove ti pareva.
saluti real mode

 potrai avere un granulo di fondatezza :P
Scherzi!?!!! Per perdere roba non ho bisogno di ricorrere a cose cosi'
sofisticate. Mi basta cercare di attacare la lampada e staccare la
mia presa invece di quella del collega assente :-)
Tornando ai crash...
http://localhost.ee/fun/kassipildid/
Qualcuno mi ha riportato un crash di NT e una reinstallazione di WinME
solo a causa della visualizzazione di questo sito.
Se vuoi provare :-)
Disclaimer: Se visualizzate la pagina, quello che puo' accadervi sono
            solo ed esclusivamente fatti vostri (e del vostro ie
            buggato). _*E NON STO SCHERZANDO*_.


 solo a causa della visualizzazione di questo sito.
Maddai! Provato adesso sulla macchina win2k che ho su intranet in ufficio;
richiesta di installazione di real non so cosa (prontamente negata) e
paginone blu impietosamente killato tramite task manager.
saluti metropolitani

 solo a causa della visualizzazione di questo sito.
Si è bloccato IE. Un baco del plug-in shockwave?
Killato e ripartito.

 comporta...
Il debugger lo sa benissimo. Infatti chi "progetta" un exploit sa bene
cosa comporta...

 lo stack di sistema?
lo č. Senno' ogni singolo buffer overflow sarebbe un crash del sistema


 partire da 0xfff fff nella VM del processo.
sě. Sulla Luna, magari. Da dove l'hai tirata fuori, quella cifra?


 e la multi utenza e' una novita' recente solo per il mondo MS.
il "recente" sono dieci anni quest'anno. Prego confrontare con MacOS. O 
con OS/2


 protetta? 
qualsiasi chiamata a funzione richiede la scrittura dello stack


 Per questo mi chiedevo come mai NT teme tanto i buffer overflow;
codice antiquato, insufficiente supporto da parte del compilatore


 piattaforma Intel era lo SCO.
storiella: il porting di SysV per x86 venne fatto proprio da Microsoft. 
Comprarono una licenza dalla AT&T e rivendettero il risultato, sotto il 
nome di Xenix, ad altri vendor, tra cui SCO, che fině per ereditarlo


, 
cinque anni fa. Lě era un'applet Java, qui un filmato Flash full-screen 
e in entrambi i casi "dopo che sono stato su quel sito Windows ha avuto 
problemi č ho dovuto reinstallarlo!!!!" (errori di ortografia e quattro 
punti esclamativi intenzionali) Come dice il proverbio? "quando il dito 
indica la luna, lo sciocco guarda il dito"


 codice antiquato, insufficiente supporto da parte del compilatore
Ti faccio notare che (anche se fra le righe) si parla di IIS.
E a questo punto riformulo la domanda a te:
L'architettura di NT (ricordo di aver letto molto tempo fa) prevede la
separazione del codice dall'area dati; il codice gira cioè in un'area di
memoria inaccessibile all'utente che passa i parametri a una funzione
(
p.es
. una dll di sistema).
Mi si fa giustamente notare che esiste lo stack, che non contiene nè codice
nè dati, ma gli indirizzi di ritorno.
Bene, mi aspettavo che lo stack esistesse nell'area di memoria del codice,
cioè protetta da possibili taroccamenti; pare che invece lo stack condivida
l'area accessibile all'utente (quella usata per il passaggio dei
parametri).
Qual'è la verità?
saluti dubbiosi

 nome di Xenix, ad altri vendor, tra cui SCO, che fině per ereditarlo
Se ricordo bene, quel codice era a malapena funzionante; nel 1987 Olivetti
venne fuori con un System V targato Microsoft; lo ebbi tra le mani per
qualche settimana, finchč non riuscii ad agguantare uno Xenix/286 targato
SCO che si riusciva ad installare con successo. :-)
Credo che SCO abbia fatto un bel po' di lavoro su quel codice, se deriva
davvero da quello MS.
saluti storici

nome di Xenix, ad altri vendor, tra cui SCO, che fině per ereditarlo
Buono a sapersi non la conoscenza questa parte.

 parametri).
Lo stack è "scrivibile" da programma. E' lo stesso programma che lo
gestisce, scrivendo printf("Hello world!"); sembra di no, ma
disassemblando la chiamata te ne rendi conto... e il sistema come fa a
sapere se tu hai scritto la chiamata in C o in assembly? :-)
Comunque il problema non è questo. Il problema è che il sistema non può
proteggere il programma da letture/scritture taroccate quando queste sono
"lecite" dal punto di vista dell'integrità. Anche sui dati si possono
creare dei bei danni. Un esempio banale, che ho davanti in questo momento:
creazione di una finestra, il nome della windowclass è in una variabile
statica, se "qualcosa" andasse a scrivere su quella variabile il
programma funzionerebbe in modo completamente diverso. Oppure, il
puntatore alla WindowProc viene memorizzato in una struttura WNDCLASSEX
che certamente sta nell'area dati, cambiarlo e metterne un'altro vuol dire
cambiare tutto il programma!
Ho fatto esempi stupidi perchè in realtà non sono exploit possibili, ma se
fosse possibile potrebbero accadere un sacco di cose carine...  :-)

 sapere se tu hai scritto la chiamata in C o in assembly? :-)
Scusa, ma qui non ti seguo.
saluti incomprensibili

 Scusa, ma qui non ti seguo.
Se tu scrivi (per puro esempio) printf("Hello world"); il compilatore ti
traduce la chiamata in linguaggio macchina con scrittura dello stack.
Potresti fare la stessa cosa in assembly, a quel punto toccheresti con
mano che a scrivere nello stack non č il sistema ma il programma stesso.

 sì. Sulla Luna, magari. Da dove l'hai tirata fuori, quella cifra?
L'ho tirata fuori a caso. Di fare il calcolo non ne ho voglia.
Sommariamente 32/4 = 8 quindi mi sono mangiato 2 lettere. Colpa mia.
Il concetto pero` resta e su questo c'e` poco da dire mi pare no?
-- 
try: troll.uses(Brain)
except TypeError, data: 
   troll.plonk()
Co-Responsabile Hardware Information & Technology 
http://hit.edengames.net

 mano che a scrivere nello stack non č il sistema ma il programma stesso.
Bravo! Ai bei tempi dell'asm86 c'era il segmento codice, il segmento dati e
il segmento stack, vale ancora, vero?
Certo che non esiste piů il real mode e l'indirizzamento segmentato, ma
siccome ms ai tempi di NT disse che il codice di sistema era protetto
grazie alla separazione codice-dati, e qualcuno mi ha fatto ricordare
(giustamente) che esiste lo stack, mi chiedevo:
Questo stracazzo di stack, č nella stessa area di memoria dei dati? Ha
un'area di memoria sua? E' accessibile all'utente o č accessibile solo al
codice che lo usa?
saluti perplessi 

 cioč che l'area per il passaggio dei parametri fosse stata separata.
Non credo di prendere un granchio se dico che questo sistema di gestione
della memoria e' stato *COPIATO* pari pari da unix che lo usava gia' da
anni e anni (e lo usa ancora).
Infatti sui sistemi unix i bachi riguardanti la sicurezza dei server che
vengono continuamente corretti, il piu' delle volte riguardano proprio
buffer overflow.


 al codice che lo usa?
Lo stack non č parte dell'heap. Viene virtualmente riservato ad ogni
thread in esecuzione; quindi non potrei giurarci ma penso sia visibile
addirittura al solo thread di appartenenza.

 indica la luna, lo sciocco guarda il dito"
Chi mi ha detto che ha dovuto reinstallare WinME e' seduto difronte a me
di scrivania.
Ha detto palle? Puo' darsi, io l'ho riportato per evitare rogne :-)


 codice che lo usa?
Provo a risponderti.
Premetto che so come funziona la cosa sotto *nix e che sono certo
(facciamo al 99%) che funzioni cosi' anche sotto NT.
Ogni processo ha un'area dov'e' memorizzato il codice, che non e'
modificabile (a meno di chiamare la funzione exec() sotto *nix, ma non
divaghiamo) e poi ha un'area dati, modificabile, dove sono memorizzate
le variabili.
Quest'area dati si divide in heap e stack.
Nello heap ci vanno le variabili globali, ossia quelle che in C dichiari
fuori dal main() e da tutte le altre funzioni, e le variabili gestite
dinamicamente, ossia quelle che in C allochi dinamicamente con la
malloc().
Nello stack ci vanno le variabili automatiche, ovvero quelle di ogni
singola funzione, che dopo che la funzione e' stata eseguita vengono
disallocate, appunto, automaticamente.
Lo stack (stack in inglese vuol dire pila) a grandi linee funziona
cosi': c'e' il primo livello dello stack, che contiene le variabili
automatiche del "livello iniziale" del programma, ovvero, in C, la
funzione main(). Quando main() chiama una qualsiasi funzione, ad esempio
pippo(), viene allocato un altro "pezzo", "livello" (chiamalo come vuoi)
di memoria sulla pila (stack), che e' quello relativo a pippo() (il cui
codice NON e' nello stack, ma nell'area codice). Questo nuovo livello
dello stack (ovvero pila: ora si capisce perche' si chiama pila?)
contiene le variabili automatiche di pippo() (ovvero quelle dichiarate
nella funzione) e l'indirizzo di ritorno da pippo().
Se pippo() chiama a sua volta la funzione paperino(), viene allocato un
altro "pezzo" di memoria sullo stack, che contiene le variabili
automatiche di paperino(), il ritorno dalla funzione paperino() (che
sara' l'indirizzo dell'istruzione, nell'AREA CODICE di pippo(),
successiva a quella che ha chiamato paperino(), per intenderci).
Quando paperino() finisce di essere eseguita, viene letto l'indirizzo di
ritorno dal "pezzo di stack" di paperino(), che e' il "pezzo di stack"
in cima alla pila, poi viene disallocato il "pezzo di stack" di
paperino(), e l'esecuzione continua dall'indirizzo letto, che sara'
l'istruzione, all'interno di pippo(), successiva alla chiamata di
paperino().
Quando pippo() finisce di essere eseguita, viene letto l'indirizzo di
ritorno dal "pezzo di stack" di pippo(), che e' "pezzo di stack" in cima
alla pila (prima era il secondo, perche' sopra c'era quello di
paperino()), poi viene disallocato il "pezzo di stack" di pippo(), e
l'esecuzione continua dall'indirizzo letto, che sara' l'istruzione,
all'interno di main(), successiva alla chiamata di pippo().
Poi quindi riprende l'esecuzione di main() dall'istruzione successiva
alla chiamata di pippo(), e il "pezzo di stack" di main() rimane quello
in cima alla pila (e anche l'unico).
Si capisce quindi che ogni processo ha una sua area dati formata da suo
stack e un suo heap.
Ogni processo puo' scrivere e modificare solo la sua area dati, formata
da stack e heap, e NON l'area codice, che contiene il codice delle
funzioni (e della parte principale del programma, che in C e' vista
sempre come una funzione, la main()).
Ogni singola funzione del processo, puo' modificare SOLO il SUO pezzo di
stack e lo heap del processo in questione.
Non puo' modificare i pezzi di stack delle funzioni che chiama, perche'
intanto che viene eseguita la funzione chiamata, non viene eseguita (e'
ovvio) la funzione chiamante, e quando riprende l'esecuzione della
funzione chiamante, il pezzo di stack della funzione chiamata non c'e'
piu'.*
Per regola non puo' modificare nemmeno i pezzi di stack delle funzioni
da cui e' stata chiamata, ovvero quelli, nello stack, al di sotto del
suo pezzo (che e' in cima).
Quindi, ripeto, gni funzione di un processo puo' modificare SOLO:
- lo HEAP (mucchio) DEL PROCESSO
- il SUO PEZZO DI STACK nello stack DEL PROCESSO
*) - O meglio, in realta' i dati non vengono cancellati, restano li',
solo che la memoria e' disallocata (cioe' puo' essere riutilizzata),
quindi alla chiamata di una nuova funzione (anche la stessa) sara'
riallocata, quindi sovrascritta. Quindi, anche se la funzione chiamante
la modifica, non succede niente.
---- Da qui in poi prendi quello che scrivo "con le molle"
Ora, se grazie ad un overflow viene modificato l'indirizzo di ritorno
dalla funzione che e' eseguita, e' come se la stessa funzione
modificasse il suo indirizzo di ritorno, che e' NEL SUO pezzo di stack
(cosa che di solito non avvine, ma niente lo impedisce).
Se questo indirizzo e' un puntatore a una zona di memoria dell'area dati
del processo (niente lo impedisce) che contiene codice "cattivo" ecco
che l'esecuzione riparte da li' con grande dispiacere di tutti.
Se grazie all'overflow e' stato scritto sullo stack della funzione del
codice eseguibile in una variabile, o in una zona di memoria puntata da
un puntatore, e, sempre con l'overflow, si cambia l'indirizzo di ritorno
della funzione, mettendoci l'indirizzo della prima istruzione di quelle
"iniettate" nel pezzo di stack della funzione (con l'overflow), cosa
succede?
Succede che quando la funzione ha finito di essere eseguita, viene letto
quell'indirizzo, il pezzo di stack della funzione viene disallocato (ma
la roba che c'era dentro NON viene cancellata, resta lě in attesa di
essere sovrascritta) e l'esecuzione riparte da quel punto, ovvero un
punto dell'area dati del processo, che fa parte dello stack, e nello
specifico di quell' "ex" pezzo di stack che e' stato disallocato e puo'
essere sovrascritto, ma questo non succedera' mai (perche' il codice
iniettato non chiama nessuna funzione).
Credo che sia una spiegazione esaustiva, rileggendola mi rendo conto che
non sono il massimo della chiaezza a spiegare le cose, ma ho fatto del
mio meglio.


 quello che hai quotato
Porca miseria, e allora? Non mi sembra una cosa cosi' grave, ne'
un'offesa verso nessuno. Forse ti senti attaccata perche' prendi questo
come un insulto a NT e tu lo vuoi difendere, ma non mi sembra che in
questo thread qualcuno abbia attaccato NT, ne' la Microsoft.
Sorridi, che fa bene!! ;)


 fatto del mio meglio.
Per me e' stato un interessante ripasso di alcuni concetti da me mai
completamente approfonditi o un po' sbiaditi dal tempo.
Alessandro.

Bimbo Vispo wrote:
[SNIP]
Ergo: l'area codice e' solo eseguibile (anche leggibile?), ma non e'
scrivibile, l'area dello stack e' leggibile, scrivibile, ed anche...
eseguibile.
Ma non esiste un flag di pagina o segmento che impedisca l'esecuzione di codice
in una determinata area del processo (quella appunto dei dati e dello stack)?
Quanti problemi ci eviteremmo riguardo il rischio di esecuzione di codice in
area dati? Gli exploit basati su stack overflow e code injection, sarebbero
ancora possibili?
bye G.L.
--
La logica non attiene alla verosimiglianza delle ipotesi,
ma alla coerenza delle tesi con le ipotesi.

 con OS/2
<pungolo>
Beh... prima dei servizi terminal, microsoft deteneva un concetto
abbastanza strano, o perlomeno limitato, della c.d. multiutenza...  <g>
</pungolo>



$ cd /pub
$ more beer

 quello che hai quotato
Ah, tanto per cronaca, scrisse questo:
Cosa che a suo tempo fu una grande innovazione rispetto a OS/2 che 
invece, al pari di windows, condivideva codice e dati in un'unica area 
di memoria,
La parola ``innovazione'' c'è. Leggi e parla dopo... e sorridi ;)


 L'ho tirata fuori a caso. Di fare il calcolo non ne ho voglia.
macchč calcolo e calcolo. Lo stack č caricato dove pungette vaghezza al 
sistema operativo di caricarlo. Qui ho un processo con tre thread i cui 
stack sono caricati a 0x130000, 0xcb0000 e 0xdb0000


 che passa i parametri a una funzione (
p.es
. una dll di sistema).
"inaccessibile all'utente" non significa niente, in questo contesto


 dati?
DS == SS, come qualunque debugger ti (di)mostrerà



Dovrebbe essere molto utile, ma non l'arma definitiva. 
cfr l'articolo/intervista "killing buffer overflows" sempre da de
raadt, nn  mi ricordo dove. 
Il problema è che la gente se ne sbatte. 
Da quanto tempo sono in giro patch per aumentare la sicurezza di Linux
? grcsec, openwall, LIDS... 
eppure no c'è stato un "backporting" verso il tree principale.. 
PS
buona paqua a tutto il NG ^_^

 ancora possibili?
Ipotizzo una risposta:
Credo che per come e' gestita la memoria virtuale a livello hardware, si
possa solo decidere se una pagina e' leggibile o scrivibile, non se puo'
essere eseguita.
Quindi, visto che l'area dati per forza di cose dev'essere leggibile,
ecco che possono anche essere eseguite istruzioni al suo interno.
Probabilmente, con delle modifiche a livello hardware...


 impedirlo?
un sacco di programmi non funzionerebbero piů. Se serve, spiego meglio


 abbastanza strano, o perlomeno limitato, della c.d. multiutenza...
storia vecchia. Ora Terminal Server è di serie


 Almeno questo è quello che hai quotato
-- 


 <g> </pungolo>
Ricordo il libretto di installazione di Windows 2000 Server che proclamava
che tale prodotto era il primo sistema operativo a supportare servizi di
terminale...
Si trattava di ignoranza o traduzione ingenua?
Alessandro

 Si trattava di ignoranza o traduzione ingenua?
O banalmente il ricordo come postumo di una sbronza di lambrusco?
I servizi terminal erano già presenti su NT Terminal Server un paio di
anni prima, senza contare i precedenti sviluppi con Cytrix.
Quindi o dai dei riferimenti ufficiali del suddetto proclama oppure ci
metto sopra il bollino di "cazzata scritta tanto per togliere la polvere
dalla tastiera"... <grin>
 

 polvere dalla tastiera"... <grin>
Cerchero' con tutte le mie forze di smentire questa infamia...
Martedi' sono in ufficio, spero di raccogliere prove sufficienti.
Alessandro
...che comunque sistemi operativi che supportano accesso via terminale ce ne
erano anche prima di NT...

 ne erano anche prima di NT...
Se facevi questa affermazione, sarei stato zitto e non te l'avrei
contestata. Per quanto banale...

 anni prima, senza contare i precedenti sviluppi con Cytrix.
Che io sappia, i "terminal services" di NT son perlopiu` proprio i 
precedenti sviluppi di Citrix e Insigna, poi riacquistati indietro da 
Microsoft per farne i suoi terminal services.
Per la cronaca, e` esistita una variante di Windows NT 3.x con UI 
multiutente ("NTrigue", di Insigna) che parlava direttamente X protocol.
Lo usavo, e non era affatto male (per il deployment insieme a 
workstation unix).
Vedi
http://hepwww.rl.ac.uk/ukhepsysman96/UKsysmanMeet96/Ntrigue/
-- 
   |   \    \  | ___|_  |_  | ianezz a casa sua... :-)
   |  _ \  | \ | _|    /   /  Visita il LinuxTrent a
  _|_/  _\_|  _|____|___|___| 
http://www.linuxtrent.it

 stack sono caricati a 0x130000, 0xcb0000 e 0xdb0000
Ti sfugge che io non sto parlando della memoria fisica ma della memoria
virtuale. Che in memoria fisica stia a quei 3 indirizzi lo so anche io
ma nella memoria virtuale sta sempre e dico _SEMPRE_ agli ultimi
indirizzi perche` cosi` e` stato pensato. Non ti va bene? Non sei d'accordo?
mi spiace veramente tanto...


 Microsoft per farne i suoi terminal services.
Infatti Metaframe è precedente a NT TS edition del '98. Tutto comunque a
dimostrare l'evidenza, ovvero che Win2000 server non è il primo sistema
multiutente tantomeno nella stessa storia di windows. Aspetto con ansia i
riferimenti in cui la microsoft lo dichiara.

 storia vecchia. Ora Terminal Server è di serie
Storia giovane, quindi... :-) Saro' pedante, ma tengo a sottolineare che
diverse applicazioni, se si installa il servizio terminal service in
modalita', se non sbaglio, "applicazioni", e non "amministrazione", vanno
configurate per poter girare senza problemi... in un terminale. Questo fa
pensare che NT non e' multiuser su terminali fisicamente distinti in
modo... cosi' naturale e scontato, sia per cio' che riguarda il sistema,
sia per cio' che riguarda le applicazioni. IMHO non e' nato, per diversi
aspetti, per supportare cio' in modo "naturale" (Anche se, ad onor del
vero, ho letto che il modello di comunicazione client-server fra
applicazioni e GUI, e' stato studiato proprio per supportare i terminal.
Forse il problema sono unicamente le applicazioni non esattamente studiate
per girare sui terminal).



Infatti la frase era un po' diversa ma ugualmente sconvolgente.
Sulla "Guida introduttiva" di Windows 2000 Server (codice a barre X05-07194)
a pagina 25 (sezione "Novita' di Windows 2000 Server", paragrafo "Servizi
terminal integrato") si legge:
"Windows 200 Server e' l'unico sistema operativo server che integra i servizi
di emulazione del terminale."
Alessandro.


Esatto il problema e che molte applicazioni non sono realizzate per
funzionare in modalità terminal server, esiste un white papaer molto
chiaro che indica come devono essere realizzati i programmi per
funzionare "bene" in modalità terminal.


Penso che il giochino stia nella parola servizi.... ;-)

 essere eseguita.
Ecco, io mi chiedevo se la mmu di una cpu intel (o altra cpu) sia in grado di operare
un controllo piu' fine, fra leggibilita', scrivibilita', eseguibilita'. Infatti per
quello non ho dato per scontato che una pagina con l'ipotetico flag di eseguibilita',
sia anche leggibile. Mi spiego meglio, una cpu potrebbe distinguere fra una "fetch"
di istruzione e operandi, ed una operazione di lettura di cella di memoria richiesta
da un'istruzione. Sulla falsariga dello stesso concetto, comunque, si puo' rendere
una pagina leggibile e scrivibile, ma non eseguibile.


 buona paqua a tutto il NG ^_^
Altrettanto (in ritardo, vabbe'...)    :-)


 Non ti va bene? Non sei d'accordo? mi spiace veramente tanto...
no, è semplicemente falso


 no, è semplicemente falso
Sai che forse dovrei iniziare io con le barzellette dei bambini morti?
Sei brava e hai vinto.


 che alla cose sostanziali: non lo facevo da almeno tre giorni :-)
Questioni molto soggettive, non esiste una definizione univoca di cazzate.
Per esempio, se tutti i servizi soggetti a buffer overflow fossero scritti
in un limguaggio managed, tipo Java . uno qualunque del linguaggi CLR ?
Tutti i problemi di cui sopra sarebbero risolti? mi sa di si'. E in maniera
strutturale, senza confidare nel buon programmatore.
Mah... io credo ci si arrivera'.
Saluti.


Rimarrebbero comunque i bachi dell'OS/interprete/virtual machine...
Alessandro.

 Rimarrebbero comunque i bachi dell'OS/interprete/virtual machine...
Ovviamente. Ma e' ovvio risponderti che potrebbero al piu' essere solo li'.
Da N a 1.
Saluti.


Ovviamente :-)
Alessandro.

 una pagina leggibile e scrivibile, ma non eseguibile.
Capisco quello che intendi dire.
Non ti so dire se le mmu delle cpu x86 hanno la possibilita' di marcare
una pagina come eseguibile, comunque mi sa che non e' solo un problema
di mmu, questa e' la situazione come me la immagino io:
Ogni volta che la cpu esegue una istruzione, prima di eseguirla la legge
dalla memoria, dall'indirizzo contenuto nel registro PC (Program
Counter).
Il PC viene incrementato automaticamente all'esecuzione di ogni
istruzione, per passare a quella successiva.
Oppure puo' essere modificato da istruzioni di jump o ritorno da
funzione.
Sta di fatto che comunque a ogni istruzione la cpu legge dalla memoria
la nuova istruzione, e se non ha i permessi di lettura, si genera un
errore.
Se vogliamo che l'errore (o non errore) si generi in base ai diritti di
eseguibilita' (e non di lettura) dobbiamo implementare un meccanismo a
livello hardware per fare in modo che la cpu dica alla mmu (o chi per
lei) se l'istruzione di lettura della memoria e' fatta per prendere
un'istruzione o un dato.
E credo che il casino sia qui.
Poi non so, magari e' una cosa che esiste gia'.
In tutti i casi, a occhio e croce credo di poter dire con una certa dose
di sicurezza che anche se 'sto sistema esiste, nessun SO lo usa.



Se hai un po' di tempo e riesci a farlo stare in meno di cento righe... ;-)
Alessandro.


Quasi nessuno? (il fatto che compaia un pinguino nei link e' solo dovuto alla
mia maggiore frequentazione con quella specie, ma non escludo ci sia anche la
versione diavoletto e, forse, finestra)
http://pageexec.virtualave.net/
http://pageexec.virtualave.net/docs/pageexec.txt
Alessandro
...che posta il link ma deve ancora trovare il tempo per leggerli.

 paginone blu impietosamente killato tramite task manager.
Fare Alt+F4 pareva brutto ? :-) A me lo ha chiuso regolarmente.
Bye, G.

 studiate per girare sui terminal).
non esistono applicazioni "non esattamente studiate per "ecc. ecc. Sono 
semplicemente programmi non multiutente, che non funzionano allo stesso 
modo con e senza Terminal Server. No, le persone che usano Windows come 
Administrator con una password vuota non esistono, ai fini del discorso
-- 
  < 
http://www.reactos.com/
 >  Open source clone of Windows NT. Current
      Don't stand, REACT!      version 0.1.1. C, C++ and ASM developers
                               and beta testers are welcome!

 morti? 
portami un dump che mostra uno stack caricato all'indirizzo che dici tu 
(chè io ho già pronta la risposta)


 (chè io ho già pronta la risposta)
A parte che del dump a me nun me interessa nulla perche` io ho detto che mi
importa come vede la memoria il processo e non come e` lo stato fisico della
memoria. Detto questo:
/*****************************************************/
#include <stdio.h>
int Global[10];
int main(argc, argv) {
  void f();
  int Local[10];
  void *Brk;
  extern char **environ;
  Brk = sbrk(0);
  printf("indirizzo esadecimale environ:%X\n", environ);
  printf("indirizzo esadecimale argv:%X\n", argv);
  printf("indirizzo esadecimale Local:%X\n", Local);
  printf("indirizzo esadecimale Brk:%X\n", Brk);
  printf("indirizzo esadecimale Global:%X\n", Global);
  printf("indirizzo esadecimale f:%X\n", f);
  printf("indirizzo esadecimale main:%X\n", main);
  printf("indirizzo esadecimale printf:%X\n", printf);
  Brk=sbrk(4096);
  Brk=sbrk(0);
  printf("indirizzo esadecimale Brk dopo incremento:    %X\n",Brk);
}
void f(){}
/********************************************************/
dialtone@vercingetorix:~/Documents$ gcc prova.c -o prova
dialtone@vercingetorix:~/Documents$ ./prova
indirizzo esadecimale environ:BFFFF96C
indirizzo esadecimale argv:BFFFF964
indirizzo esadecimale Local:BFFFF8D0
indirizzo esadecimale Brk:80497E8
indirizzo esadecimale Global:80497C0
indirizzo esadecimale f:80484AC
indirizzo esadecimale main:80483B0
indirizzo esadecimale printf:80482F0
indirizzo esadecimale Brk dopo incremento:    804A7E8
-- 
try: troll.uses(Brain)
except TypeError, data: 
   troll.plonk()
Co-Responsabile Hardware Information & Technology 
http://hit.edengames.net

 Administrator con una password vuota non esistono, ai fini del discorso
Ripeto, IMHO non c'entra una cippa.
bye G.L.
--
La logica non attiene alla verosimiglianza delle ipotesi,
ma alla coerenza delle tesi con le ipotesi.

modo con e senza Terminal Server. 
Mai provato a installare Office 2000 su Terrminal Server, ma anche far
usare Visual Basic, in realtà esistono applicazioni che funzionano
bene su sistemi non terminal e portati su Terminal necessitano di
Resource Kit o di "magie" sul registry da fare per risuciere a
installarle.
A parte questi due casi, che comunque poi funzionano una volta
installati correttamente in quest url
http://microsoft.com/windows2000/techinfo/planning/terminal/tsappdev.asp
Sono indicate tutte le caratteristiche che deve avere un applicazione
per essere "ottimizzata" per terminal server, tra cui i maledetti
"splash screen" super colorati.... 

 Ripeto, IMHO non c'entra una cippa.
ma i link che vengono postati li leggi o ti basta che vengano postati?
primo: il documento si intitola "Optimizing Applications for"ecc. ecc., 
e notare l'"Optimizing"
secondo: indovina? io l'ho già letto. Io so quello che dico. La maggior 
parte dei "requisiti per funzionare in Terminal Services" sono generici 
requisiti di multiutenza, con un particolare accento su:
 - basso consumo di risorse
 - minimizzazione delle bitmap e degli effetti grafici
 - non usare caratteristiche dell'hardware per identificare un utente


 Detto questo:
[...]
non odi non aver mai ragione?
indirizzo esadecimale environ:3F2E78
indirizzo esadecimale argv:3F2BD8
indirizzo esadecimale Local:22FF38
indirizzo esadecimale Global:405040
indirizzo esadecimale f:40143A
indirizzo esadecimale main:401382
indirizzo esadecimale printf:402B08


 non odi non aver mai ragione?
C'e` una qualche ragione per la quale i tuoi risultati siano piu`
importanti dei miei?  Mi sembrava che la discussione fosse finita dicendo
che a volte capita in un modo e a volte nell'altro.


 dicendo che a volte capita in un modo e a volte nell'altro.
tu hai detto "lo stack viene caricato a questo indirizzo". Punto. Non è 
vero. Lo stack è dove punta lo stack pointer in questo momento. Ci sono 
architetture con uno stack infinito, o non contiguo. Forse Minix carica 
un solo stack per processo e sempre allo stesso indirizzo, ma è l'unico


 un solo stack per processo e sempre allo stesso indirizzo, ma è l'unico
Ti ho gia` dato ragione in un messaggio precedente, non sei contenta?


 ...che posta il link ma deve ancora trovare il tempo per leggerli.
Beh, ho letto il link, anche se non tutto, e mi e' parso di capire che
quella e' una patch; quindi, in effetti, e' vero che nessun os usa 'sto
sistema: linux standard non ce l'ha, va patchato.
Comunque c'e' una distribuzione linux con le patch per il kernel e tutti
i pacchetti compilati con gcc patchato, che ha una gestione innovativa
dello stack e dello heap per evitare i buffer overflow.
Si chiama TrustedDebian.
(Non c'entra col progetto debian ufficiale, si chiama cosi' perche'
l'hanno fatta modificando debian.)
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

Ora l'ho letto tutto:
Da quello che ho capito, per ottenere l'implementazione delle pagine col
flag executable, usano una feature hardware dei nuovi processori intel e
amd, che pero' era stata pensata per altri scopi. E da come e'
implementata la cosa, mi pare di capire che si ha un decadimento di
prestazioni. (Un page fault per ogni richiesta di accesso alla memoria).
Magari e' per questo che non mettono 'ste funzionalita' nel kernel
ufficiale.
Comunque, se solo Intel e AMD si svegliassero, non penso che gli
costerebbe molta fatica aggiungere lo spazio per un flag nelle mmu delle
loro prossime cpu.


 kernel ufficiale.
Le stime danno una perdita di performance dall'1% all'8% in base al tipo di
controlli effettuati (
http://www.trusteddebian.org/faq.html
 FAQ n. 10),
accettabile se si vuole la sicurezza prima di tutto.
Certo non e' nello stile di unix... (l'efficienza prima di tutto) ;-P
Alessandro.

 l'hanno fatta modificando debian.)
E' da li' che son partito :-)
Alessandro.

 Certo non e' nello stile di unix... (l'efficienza prima di tutto) ;-P
Beh, pero' e' perfetto per Windows! <g>
-- 
il *Vide* - ICQ #5301833
Linux user #224141 on Linux machine #106981
http://www.heavy-metal.it
Tessera #8 "Tira Clarenzo e m' illumino d' immenzo"

  - non usare caratteristiche dell'hardware per identificare un utente
Ribadisco quanto detto sopra.


 base al principio suesposto?
Non so se questa sia gia` passata da qui,
comunque, in ogni caso:
http://zdnet.com.com/2100-1103-994794.html
Si e` sfruttato un buffer overflow per far
girare Linux sulla X-Box.
bye,
-- 
   Piergiorgio Sartor

 realizzate quando windows _non era_ un ambiente multiuser".
e io insisto: sono solo regole di buon vicinato, Terminal Server di per 
sè è trasparente alle applicazioni. L'user switching di Windows XP Home 
non è che un Terminal Server travestito, e non sento lamentele



L'user switching di XP impone una console attiva alla volta (i programmi
della sessione continuano a girare, ma non c'e' interazione con l'utente).
E' una condizione di lavoro un po' particolare...
Alessandro.

_non era_ un ambiente multiuser".
Emmm scusa ma guarda che non è un documento che spiega come rendere
compatibili le applicazioni "old" con Terminal Server ma su come
scrivere il software per gestire meglio l'ambiente terminal che per
certi suggerimenti non c'entra nemmeno nulla con un ambiente
multiuser, è un documento sul come fare a non sul come sistemare
quello che c'e' ! 

 quello che c'e' !
A maggior ragione, e' cio' che ho affermato precedentemente: che mi frega che le
applicazioni siano multiutente o monoutente (nel senso piu' comune del termine,
ovvero che possano essere lanciate piu' sessioni e/o che le varie sessioni
possano sharare gli stessi dati)? Mi interessa che girino correttamente su una
sessione terminal.


sessione terminal.
Okkey quindi ? Non riesco a capire dove vuoi andare a parare

massi69 wrote:

Ok. Ma era per me ok da prima. Mi sembra che, perlomeno a te, fosse gia' chiaro il
mio pensiero, almeno cosi' mi appariva dalla risposta che tu hai dato al mio primo
post, nel merito della questione.


bye G.L.
;-)