ASN1 parsing denial-of-service

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

ASN1 parsing denial-of-service

Guido Vranken
Dear list,

The following code takes about 2-3 seconds to process.

            byte[] data = {
                (byte)0xff, (byte)0xbf, (byte)0x30, (byte)0x80,
                (byte)0x28, (byte)0x80, (byte)0xa2, (byte)0x80,
                (byte)0x31, (byte)0x80, (byte)0xa4, (byte)0x00,
                (byte)0x31, (byte)0x80, (byte)0xac, (byte)0x00,
                (byte)0x31, (byte)0x80, (byte)0xb3, (byte)0x00,
                (byte)0xb3, (byte)0x00, (byte)0x31, (byte)0x80,
                (byte)0x8f, (byte)0x00, (byte)0xb3, (byte)0x00,
                (byte)0x31, (byte)0x80, (byte)0xaf, (byte)0x00,
                (byte)0x31, (byte)0x80, (byte)0x82, (byte)0x01,
                (byte)0x80, (byte)0xac, (byte)0x00, (byte)0x31,
                (byte)0x80, (byte)0xb3, (byte)0x00, (byte)0xb3,
                (byte)0x00, (byte)0xc6, (byte)0x00, (byte)0x31,
                (byte)0x80, (byte)0xaf, (byte)0x00, (byte)0x31,
                (byte)0x80, (byte)0x82, (byte)0x01, (byte)0x2b,
                (byte)0x82, (byte)0x02, (byte)0xf3, (byte)0x28,
                (byte)0xb5, (byte)0x00, (byte)0x31, (byte)0x80,
                (byte)0xaf, (byte)0x00, (byte)0x9a, (byte)0x01,
                (byte)0x00, (byte)0x93, (byte)0x00, (byte)0x00,
                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xcb,
                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
            };
            ASN1InputStream asn1 = new ASN1InputStream(data);
            ASN1Primitive result = asn1.readObject();

A lot of cycles are spent in ASN1Set sort(). This payload can possibly
be modified to reach an execution duration of much more than 2
seconds. This could be viewed as a security problem in any application
that consumes and processes untrusted ASN1 data.

This was found with my Java fuzzer [1].

Guido

[1] https://github.com/guidovranken/libfuzzer-java

Reply | Threaded
Open this post in threaded view
|

Re: ASN1 parsing denial-of-service

David Hook-3

Thanks for the report, yes, this has all the hallmarks of something
which could easily turn into a bigger problem.

I think I have identified the issue that is causing this. I'll get
161b03 up on https://www.bouncycastle.org/betas as soon as we think
we've fixed it. In the meanwhile, keep working on the fuzzer! Things
like this really help.

Regards,

David

On 16/07/18 00:58, Guido Vranken wrote:

> Dear list,
>
> The following code takes about 2-3 seconds to process.
>
>             byte[] data = {
>                 (byte)0xff, (byte)0xbf, (byte)0x30, (byte)0x80,
>                 (byte)0x28, (byte)0x80, (byte)0xa2, (byte)0x80,
>                 (byte)0x31, (byte)0x80, (byte)0xa4, (byte)0x00,
>                 (byte)0x31, (byte)0x80, (byte)0xac, (byte)0x00,
>                 (byte)0x31, (byte)0x80, (byte)0xb3, (byte)0x00,
>                 (byte)0xb3, (byte)0x00, (byte)0x31, (byte)0x80,
>                 (byte)0x8f, (byte)0x00, (byte)0xb3, (byte)0x00,
>                 (byte)0x31, (byte)0x80, (byte)0xaf, (byte)0x00,
>                 (byte)0x31, (byte)0x80, (byte)0x82, (byte)0x01,
>                 (byte)0x80, (byte)0xac, (byte)0x00, (byte)0x31,
>                 (byte)0x80, (byte)0xb3, (byte)0x00, (byte)0xb3,
>                 (byte)0x00, (byte)0xc6, (byte)0x00, (byte)0x31,
>                 (byte)0x80, (byte)0xaf, (byte)0x00, (byte)0x31,
>                 (byte)0x80, (byte)0x82, (byte)0x01, (byte)0x2b,
>                 (byte)0x82, (byte)0x02, (byte)0xf3, (byte)0x28,
>                 (byte)0xb5, (byte)0x00, (byte)0x31, (byte)0x80,
>                 (byte)0xaf, (byte)0x00, (byte)0x9a, (byte)0x01,
>                 (byte)0x00, (byte)0x93, (byte)0x00, (byte)0x00,
>                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
>                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
>                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
>                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xcb,
>                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
>                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
>                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
>             };
>             ASN1InputStream asn1 = new ASN1InputStream(data);
>             ASN1Primitive result = asn1.readObject();
>
> A lot of cycles are spent in ASN1Set sort(). This payload can possibly
> be modified to reach an execution duration of much more than 2
> seconds. This could be viewed as a security problem in any application
> that consumes and processes untrusted ASN1 data.
>
> This was found with my Java fuzzer [1].
>
> Guido
>
> [1] https://github.com/guidovranken/libfuzzer-java
>
>


Reply | Threaded
Open this post in threaded view
|

Re: ASN1 parsing denial-of-service

Guido Vranken
Sure, in fact, we can run a fuzzer continuously on Google's oss-fuzz
project [1], and you'll be automatically notified when it finds a bug.
It would be the first Java project running on oss-fuzz.

I think I can do most of this autonomously. Some questions though:

- What constitutes a bug, apart from long execution time or complete
hang? Are there any exceptions that shouldn't be thrown for example?
- What other modules shall I focus on other than ASN1/X509? Anything
that has particular importance?
- Are you OK with running a BouncyCastle fuzzer on oss-fuzz and
receiving automatic e-mail notifications of new bugs, and are there
any other people (e-mail addresses) that should be notified?

[1] https://github.com/google/oss-fuzz

Thanks

Guido

On Mon, Jul 16, 2018 at 10:25 AM, David Hook <[hidden email]> wrote:

>
> Thanks for the report, yes, this has all the hallmarks of something
> which could easily turn into a bigger problem.
>
> I think I have identified the issue that is causing this. I'll get
> 161b03 up on https://www.bouncycastle.org/betas as soon as we think
> we've fixed it. In the meanwhile, keep working on the fuzzer! Things
> like this really help.
>
> Regards,
>
> David
>
> On 16/07/18 00:58, Guido Vranken wrote:
>> Dear list,
>>
>> The following code takes about 2-3 seconds to process.
>>
>>             byte[] data = {
>>                 (byte)0xff, (byte)0xbf, (byte)0x30, (byte)0x80,
>>                 (byte)0x28, (byte)0x80, (byte)0xa2, (byte)0x80,
>>                 (byte)0x31, (byte)0x80, (byte)0xa4, (byte)0x00,
>>                 (byte)0x31, (byte)0x80, (byte)0xac, (byte)0x00,
>>                 (byte)0x31, (byte)0x80, (byte)0xb3, (byte)0x00,
>>                 (byte)0xb3, (byte)0x00, (byte)0x31, (byte)0x80,
>>                 (byte)0x8f, (byte)0x00, (byte)0xb3, (byte)0x00,
>>                 (byte)0x31, (byte)0x80, (byte)0xaf, (byte)0x00,
>>                 (byte)0x31, (byte)0x80, (byte)0x82, (byte)0x01,
>>                 (byte)0x80, (byte)0xac, (byte)0x00, (byte)0x31,
>>                 (byte)0x80, (byte)0xb3, (byte)0x00, (byte)0xb3,
>>                 (byte)0x00, (byte)0xc6, (byte)0x00, (byte)0x31,
>>                 (byte)0x80, (byte)0xaf, (byte)0x00, (byte)0x31,
>>                 (byte)0x80, (byte)0x82, (byte)0x01, (byte)0x2b,
>>                 (byte)0x82, (byte)0x02, (byte)0xf3, (byte)0x28,
>>                 (byte)0xb5, (byte)0x00, (byte)0x31, (byte)0x80,
>>                 (byte)0xaf, (byte)0x00, (byte)0x9a, (byte)0x01,
>>                 (byte)0x00, (byte)0x93, (byte)0x00, (byte)0x00,
>>                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
>>                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
>>                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
>>                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xcb,
>>                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
>>                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
>>                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
>>             };
>>             ASN1InputStream asn1 = new ASN1InputStream(data);
>>             ASN1Primitive result = asn1.readObject();
>>
>> A lot of cycles are spent in ASN1Set sort(). This payload can possibly
>> be modified to reach an execution duration of much more than 2
>> seconds. This could be viewed as a security problem in any application
>> that consumes and processes untrusted ASN1 data.
>>
>> This was found with my Java fuzzer [1].
>>
>> Guido
>>
>> [1] https://github.com/guidovranken/libfuzzer-java
>>
>>
>
>