Custom Protocol

Le code source du kernel exploit PSP de Qwikrazor87 expliqué

Guidobot et Wololo nous expliquent le code source du kernel exploit pour l'émulateur PSP découvert par Qwikrazor87 sur les PS Vita en firmware 3.36. Attachez vos ceintures !

Le développeur Guidobot, à l'origine du 138Menu que vous utilisez peut-être sur votre PS Vita, a posté avant-hier sur les forums de Wololo une explication relativement détaillée à propos du dernier exploit kernel PSP découvert par Qwikrazor87 sur les PS Vita en firmware 3.36 dont le code source a été révélé il y a 2 jours par l'auteur lui-même. Une petite traduction française s'impose...

Suivez le Guidobot !
Suivez le Guidobot !

Vous vous souvenez peut-être que nous évoquions une situation de compétition (ou race condition), cela semble être confirmé. Tout d'abord, sachez qu'une situation de compétition est une sorte de faille présente dans un système qui ne se manifeste que lorsque plusieurs "événements" causés par des acteurs (dont au moins un a la capacité de modifier l'état de la ressource impliquée) interviennent dans un ordre inattendu. Dans les codes multi-tâches (multithread), cela peut être assez commun si le verrouillage adéquat de chaque ressource partagée n'est pas fait correctement par les tâches (threads).

Dans un tel cas, la fonction exploitée vérifie que les paramètres sont valides avant de continuer, mais avant d'utiliser ces valeurs, un autre thread "malveillant" peut venir modifier le contenu de certains paramètres avec le fameux contenu exploité.

Explications en images
Explications en images

Ici, la fonction donnant l'accès au noyau (kernel) s'appelle sceMeVideo_driver_4D78330C (à comprendre comme étant le "do_some_stuff(data)" sur l'illustration ci-dessus), et la fonction avec la situation de compétition est le fameux scevideoCodecStop (le "myfonction" sur l'illustration). Vous avez une idée générale du fonctionnement de ce kernel exploit, si vous souhaitez connaître tout sur tout, nous vous invitons à voir les explications du code source plus bas. ;)

//sceVideocodecStop kxploit reverse by GUIDOBOT
//u sont inconnus, p sont les pointeurs et v les valeurs
typedef struct s_data
{
	unsigned u0;	//0
	unsigned u4;	//1
	unsigned u8;	//2
	unsigned p12; 	//3
	unsigned p16; 	//4
	unsigned u20; 	//5
	unsigned u24; 	//6
	unsigned u28; 	//7
	unsigned u32;	//8
	unsigned u36;	//9
	unsigned u40;	//10
	unsigned p44;	//11, *
	unsigned p48;	//12
	unsigned u52;	//13
	unsigned p56;	//14
	unsigned v60;	//15
} t_data;
int sceVideocodecStop(t_data * data, int flag)
{
	//on veut que cela retourne 0, on lui assigne donc les bonnes valeurs
	int check = sub_00000C38(data); 
	
	if(!check)
	{
		//les deux lignes ci-dessous se chargent d'écrire certaines données depuis la structure vers la mémoire,  mais on ne s'en soucie pas
		sub_00000D2C(data, flag);
		sub_00000B8C(data, flag);
		
		//c'est cet endroit qui nous intéresse, les valeurs de la structure doivent normalement déjà être échangées pour que tout fonctionne
		int val = sceMeVideo_driver_4D78330C(flag, data);
		
		//etc.
		//..
	};
	//etc.
	//..
};
//filtres des adresses du kernel
int sub_00000C38(const t_data * data, int flag)
{
	//ce morceau de code va simplement vérifier certaines données, à savoir les valeurs : data->p12, data->p16, data->p44 et data->p56
	if((0x80000000 & ((data + 96) | data) >= 0) && (0x80000000 & data->p12 >= 0))
	{
		int size = 256;
		
		if(flag == 0)
			size = 40;
		else if(flag >= 3)
			return 0x806201FE;
		if(0x80000000 & ((data->p16 + size) | data->p16) >= 0)
		{		
			if(flag)
				return 0; //malheureusement, on ne l'obtient pas ici, mais continuez de lire
			if(0x80000000 & ((((data->p44 + (data->v60 * 44))) | data->p44) | (data->v60 * 44)) >= 0)
			{		
				if(0x80000000 & ((data->p48 + 100) | data->p48) >= 0)
				{
					if(0x80000000 & (((data->p56 + data->v60 * 328) | data->p56) | (data->v60 * 328)) >= 0)
						return 0; //youpi
				};
			};
		};
	};
	//on ne veut pas arriver ici
	return 0x80000023;
};
int sceMeWrapper_driver_4D78330C(int flag, t_data * data)
{
	if(data->v0 > 0x05100601) // il est nécessaire de faire ce data->v0 = 0x05100601 pour s'amuser
		return -2;
		
	data->v8 = 0;
	if(flag == 0)
	{
		if(data->v60 - 1 >= 4)
			return -1;
		
		//Si data->v60 est égal à 1 alors le compteur sera à 0
		int count = data->v60 - 1;
		if(data->p56)
		{
			//c'est affreux ici, mieux vaut voir du côté de la condition "else" (d'ailleurs, ou pourrait aussi faire un kernel exploit ici)
			void * address = count * 44 + data->p44;
			unsigned value = count * 328 + data->p56;
			
			for(int i = count; i > 0; i--)
			{
				*(address + 36) = value;
				*(address + 40) = value + 164;
				
				value -= 328;
				address -= 44;
			};
		}
		else //cela signifie que si data->p56 est nul
		{
			//si le compteur est à 0 alors l'adresse sera data->p44
			void * address = count * 44 + data->p44;
			
			for(int i = count; i > 0; i--)
			{
				*(address + 36) = 0; 
				*(address + 40) = 0; 
				address -= 44;
			};
			
			//nous avons sauté 2 instructions ici, ce afin de ne pas "casser" le code et d'assigner 0 au compteur
			//le pointillage data->p44 à (ADDRESS - 36) va nous permettre de sauter ADDRESS et (ADDRESS + 4)
		};
		
		int result2 = sceMeWrapper_driver_635397BB(3, data->p12, data->p16, data->p44);
		
		if(result2 >= 0)
			return 0;
			
		return sub_00001194(data, result2);
	}
	else if(flag != 1)
		return -1;
	int result = sceMeWrapper_driver_635397BB(33, data->v12);
	
	if(result)
		return sub_000011C4(data, result);
	
	return 0;
};

 

Wirus

Avez-vous déjà vu un gentil virus ? Maintenant, oui.

2 commentaires

  • Des questions que je me pose :
    - SONY peut-il bloquer le chemin utilisé par les chercheurs de faille ?
    - Si c'est pas SONY, les constructeurs de jeu peuvent-ils le faire ?
    - Chaque faille trouver est chercher de la même manière ou est différent de chaque jeu utilisé ?

    Merci !

    • Je ne saurai te répondre avec exactitude, mais en tout cas oui c'est clair que Sony peut boucher cette faille, et c'est d'ailleurs probablement ce qu'il fera pour les prochains firmwares. ^^

Covid-19 bannière

Sujets récents du forum

Aucun sujet récent

Catégories

Archives

Covid-19 bannière
Bannière Hypsoma
Covid-19 bannière

Catégories

Archives