Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Insecure deserialization audit plugin #16280

Open
9 of 11 tasks
andresriancho opened this issue Dec 6, 2017 · 10 comments
Open
9 of 11 tasks

Insecure deserialization audit plugin #16280

andresriancho opened this issue Dec 6, 2017 · 10 comments

Comments

@andresriancho
Copy link
Owner

andresriancho commented Dec 6, 2017

Task

Write a plugin to test for insecure serialization issues

Research

  • How is ZAP / arachni doing this?
  • Detect these issues with time delays?
  • Use smart fuzzing: Don't send payloads to every input that w3af finds. Identify potential inputs where payloads should be sent based on the contents of the input. If no content is defined for the input, then we can send the payload "just to be sure". If the input comes from an HTML form where the user should type something, don't send payloads to it.
  • Detect deserialization issues for rails, java, php and django.

Development

  • Initial PoC for python pickle deserialization with unittest
  • Advanced detection for cases in which a parameter should be injected
  • Add long description to vulndb
  • Add Java payloads
  • Add .NET payloads
  • Add NodeJS payloads

These languages don't seem to have generic payloads which we can send and get our code to execute:

  • PHP

For the later, we need to create a grep plugin that will let the w3af user know that the parameter contains serialized objects and that it might be possible to exploit them.

Time estimate

16h

@andresriancho
Copy link
Owner Author

andresriancho commented Feb 15, 2018

Arachni doesn't implement detection for this vulnerability https://github.com/Arachni/arachni/tree/master/components/checks

@andresriancho
Copy link
Owner Author

These are good sources of inspiration:

https://github.com/federicodotta/Java-Deserialization-Scanner
https://github.com/federicodotta/Java-Deserialization-Scanner/blob/master/src/burp/BurpExtender.java#L197

Where I can generate my payloads:

I believe the best way to detect these vulnerabilities is to use time delays.

The payloads I generate should call the operating system sleep command. I should identify where in the payload the number of seconds is stored, replace that with __SLEEP_TIME__.

@andresriancho
Copy link
Owner Author

andresriancho commented Feb 15, 2018

All payloads should be stored in files, base64 encoded.

The commands used to create the payloads should be un README.md files next to the payload files, so that I can re-generate them if needed.

Detecting which parameters should be injected is difficult, but I believe these rules could apply:

  • Always inject if the parameter is base64 encoded (use a base64 decoder that doesn't care about padding to check if a string is base64 encoded!)
  • Always inject if the parameter is similar to one of our payloads (try to identify common strings / magic chars used by payloads)
  • Inject if the parameter is empty
  • If the parameter was found in an HTML form, only inject if the type is hidden

Also, if the parameter is base64 encoded, send our payload base64 encoded.

@andresriancho andresriancho self-assigned this Feb 15, 2018
andresriancho added a commit that referenced this issue Feb 16, 2018
Still a lot of work in my TODO list, but the tests PASS and the plugin structure was created
andresriancho pushed a commit that referenced this issue Mar 6, 2018
…created a new grep plugin that will

detect when the application is sending serialized objects and warn the user to perform manual analysis.

This is related with: Insecure deserialization audit plugin #16280

Created grep plugin and unittests.

Also moved the base64 functions from the audit.deserialization plugin to utils lib
and improved the regular expression it was using.
@andresriancho
Copy link
Owner Author

Asked question to the ysoserial.net guys pwntester/ysoserial.net#10

@andresriancho
Copy link
Owner Author

Since ~95% of .net applications are going to be running on Windows, and that OS doesn't have the sleep command, I'll have to use the ping localhost -n 5 trick, where the time to sleep is defined by the 5.

Remember that if I want to sleep for 1 second I have to send 2 to the command.

@andresriancho
Copy link
Owner Author

andresriancho commented Mar 7, 2018

Add the corresponding is_pickled_data for each payload type!

:shipit:

@andresriancho
Copy link
Owner Author

andresriancho commented Mar 7, 2018

        if is_pickled_data(original_value):
            return True

        if is_java_serialized_data(original_value):
            return True

        if is_nodejs_serialized_data(original_value):
            return True

        if is_net_serialized_data(original_value):
            return True

Doesn't make sense in the _should_inject method. It should be in a place where it can influence which payloads are sent.

Now we're sending pickled object when the original value matched a java object. We want to only send the right payloads!

:shipit:

@andresriancho
Copy link
Owner Author

The ysoserial output shows the following gadgets and formatters:

Missing arguments.
ysoserial.net generates deserialization payloads for a variety of .NET formatters.

Available formatters:
	ActivitySurrogateSelector (ActivitySurrogateSelector gadget by James Forshaw. This gadget ignores the command parameter and executes the constructor of ExploitClass class.)
		Formatters:
			BinaryFormatter
			ObjectStateFormatter
			SoapFormatter
			LosFormatter
	ObjectDataProvider (ObjectDataProvider Gadget by Oleksandr Mirosh and Alvaro Munoz)
		Formatters:
			Json.Net
			FastJson
			JavaScriptSerializer
			XmlSerializer
			DataContractSerializer
	PSObject (PSObject Gadget by Oleksandr Mirosh and Alvaro Munoz. Target must run a system not patched for CVE-2017-8565 (Published: 07/11/2017))
		Formatters:
			BinaryFormatter
			ObjectStateFormatter
			SoapFormatter
			NetDataContractSerializer
			LosFormatter
	TypeConfuseDelegate (TypeConfuseDelegate gadget by James Forshaw)
		Formatters:
			BinaryFormatter
			ObjectStateFormatter
			NetDataContractSerializer
			LosFormatter
	WindowsIdentity (WindowsIdentity Gadget by Levi Broderick)
		Formatters:
			Json.Net
			DataContractSerializer

Usage: ysoserial.exe [options]
Options:
  -o, --output=VALUE         the output format (raw|base64).
  -g, --gadget=VALUE         the gadget chain.
  -f, --formatter=VALUE      the formatter.
  -c, --command=VALUE        the command to be executed.
  -t, --test                 whether to run payload locally. Default: false
  -h, --help                 show this message and exit

@pwntester recommends:

In my experience, automizing the exploitation of Json.Net, XmlSerializer, LosFormatter, ObjectStateFormatter, DataContractSerializer is very difficult, so I would only try sending payloads for BinaryFormatter, FastJson and JavaScriptSerializer.

So we have the following potential combinations:

  • ActivitySurrogateSelector, BinaryFormatter
  • PSObject, BinaryFormatter
  • TypeConfuseDelegate, BinaryFormatter
  • ObjectDataProvider, FastJson
  • ObjectDataProvider, JavaScriptSerializer

@pwntester also says:

In general I would use ActivitySurrogateSelector gadget for the reasons explained above when there are different gadgets that work for a formatter.

That leaves us with:

So we have the following potential combinations:

  • ActivitySurrogateSelector, BinaryFormatter
  • ObjectDataProvider, FastJson
  • ObjectDataProvider, JavaScriptSerializer

In the ActivitySurrogateSelector gadget documentation it is mentioned that: ActivitySurrogateSelector gadget by James Forshaw. This gadget ignores the command parameter and executes the constructor of ExploitClass class. So it seems that I'll need to code that class.

@andresriancho
Copy link
Owner Author

screenshot from 2018-03-08 10-38-14

When creating the ActivitySurrogateSelector, BinaryFormatter payload I'm finding a lot of issues. The encoding used to create the payload converts any string I write in the code to unicode (or some other encoding?) thus, if I write 22 in the source code I get 32 00 32 00 in the binary (instead of the expected 32 32).

This issue is breaking the offset detection in the generator script, and even if I fix that, it won't work with the code I already created for creating the payloads.

I'm trying to find different ways to get around this, by forcing encodings on the string, writing the delay in byte arrays, etc.

@andresriancho
Copy link
Owner Author

I was unable to make this work. The closer I got was using a char as follows:

char delay = '\x3737';

When compiled that char showed 37 37 in the serialized object, which is what we need for the generator and plugin to work. BUT I was unable to find a way to translate this char instance into a string containing 77 (this is mainly because of my lack of experience with C#).

The code for the ExploitClass.cs file used in ysoserial.net that I was working with is:

using System;
using System.Text;
using System.Windows.Forms;

namespace ysoserial
{
    class ExploitClass
    {
        public ExploitClass()
        {
            try
            {
                // Payload code to be executed
                char[] delay = new char[2];
                delay[0] = '\x3737';

                string command = "'/C FOR /L %A in (0,1," + delay + ") DO ping localhost -n 2'";
                MessageBox.Show(command, command, MessageBoxButtons.OK, MessageBoxIcon.Error);

                System.Diagnostics.Process process = new System.Diagnostics.Process();
                //process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                process.StartInfo.FileName = "cmd.exe";
                process.StartInfo.Arguments = command;
                process.Start();
            }
            catch (Exception)
            {
            }
        }
        
    }
}

Since I'm only missing one of the payloads, I'll just merge this into develop and come back to this issue when I have time / interest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant