3.6 KiB
#Notes RuntimeASLR
RuntimeASLR des chercheurs déjà codé ---> RASLR1 le notre --> RASLR2
Dans RASLR1, il y a un mécanisme de tracking des pointeurs.
1ère phase --> Taint policy generation --> En gros, on va donner au système en input des programmes avec lesquels le il va apprendre le comportement des instructions Intel. Cela crée alors une politique de détection des pointeurs. Cela permet de ne pas se base uniquement sur le type des variables afin de déctecter les pointeurs Ainsi, leur système va identifier les instructions en assembleur qui vont utiliser des pointeurs (ce qui permet d'utiliser des int en tant que pointeurs par exemple car ils vont être détectés).
Pour RASLR2, nous allons donner des restrictions sur le code utilisé et interdire l'utilisation de types qui ne pas des pointeurs comme des pointeurs. Ainsi, une simple analyse statique du code en C (avec un parser ?) pour détecter mes variables * (les addresses) seront détéctés. Ainsi, on peut lancer un analysur de code qui va détecter tous les pointeurs à mettre à jour lorsque nous lancerons la randomisation.
Lors de l'analyse statique, on dectectera aussi les forks. On pourra alors insérer dans le code des instructions en plus avant les forks et après les définitions des pointeurs. Ainsi, lorsqu'une personne compilera avec gcc le programme en mettant en option la librairie que nous avons créée, lorsque le programme tombera sur une instruction de création de poiteur ou de mise à jour de pointeur, nous mettrons à jour la table des pointeurs et lorsqu'un fork se lance, on fait une randomisation à l'aide de la table.
Autre idée ---> Ne pas toucher à la pile et le tas et seulement randomiser le reste (les autres sections). En effet, une attaque ROP va de toute manière utiliser les instructions situées dans le code ou dans les libs donc bouger les autres sections permet de ne pas toucher aux autres. Aussi, pourquoi pas au lieu de faire un ASLR à chaque fork() seulement, aussi le faire tous les n appels de fonctions (par exemple tous les 10 appels à l'instruction call
en assembleur).
Trucs à faire --->
- Définir les instructions pour lesquelles le précompilateur va ajouter une instruction
- Définir les instructions que l'on va ajouter suite à l'analyse, quand les mettre et ce qu'elle font
- Coder le parser et l'analyseur avec l'ajout des instruction, coder la librairie qui va gérer tout ça qui pourra s'interfacer avec gcc (ou alors juste dans le code C ajouter un include vers notre librairie)
##Definition des instructions en C qui vont être détectées par l'analyseur et pour lesquelles nous allons ajouter des instructions.
- L'instruction
fork()
sera détectée. Lorsqu'elle sera détectée, nous rajouterons un appel à une fonction qui va randomiser l'espace d'adressages pour le fils. Il fait rajouter cette instuctions seulement lorsque le fils a été créé.
if ((pid = fork()) == 0){
//Code du fils
libRASLR_randomize();
else{
//code du père, on fait rien
}
-
La creation de pointeurs. Il faudra détecter les formes du types
<type> * <nom_var>
. Ainsi, nous rajoutons cette variable dans une table qui recense les pointeurs avec un offset par rapport au bas de la pile (l'origine de la pile). On peut pourquoi pas trouver la base de la pile en parsant au debut de programme le fichier /proc//maps. Ainsi, lorsque nous lancerons la randomisation, il suffira à la fin de relancer le parsing de /proc//maps. -
Voir pour parser les appels en assembleur de l'instruction call mais en fait direct voir les apppels de fonctions en C c'est plus simple (forme <nomfonction(*))