Giter Club home page Giter Club logo

utls's Introduction

uTLS

Low-level access to handshake

  • Read/write access to all bits of client hello message.
  • Read access to fields of ClientHandshakeState, which, among other things, includes ServerHello and MasterSecret.

ClientHello fingerprinting resistance

Golang's ClientHello has a very unique fingerprint, which especially sticks out on mobile clients, where Golang is not too popular yet. Some members of anti-censorship community are concerned that their tools could be trivially blocked based on ClientHello with relatively small collateral damage. There are multiple solutions to this issue.

Randomized handshake

This package can be used to generate randomized ClientHello. Provides a moving target without any compatibility or parrot-is-dead attack risks.
Feedback about implementation details of randomized handshake is extremely appreciated.

Parroting

This package can be used to parrot ClientHello of popular browsers. There are some caveats to this parroting:

  • We are forced to offer ciphersuites and tls extensions that are not supported by crypto/tls. This is not a problem, if you fully control the server and turn unsupported things off on server side.
  • Parroting could be imperfect, and there is no parroting beyond ClientHello.

Compatibility risks of available parrots

This package allows ClientHello messages to parrot popular browsers. There are few caveats to this parroting:

  • We are forced to offer ciphersuites and tls extensions setups that are not supported by crypto/tls. This is not a problem, if you fully control the server.
  • Parroting could be imperfect, and there is no parroting beyond ClientHello.\
Parrot Ciphers* Signature* Unsupported extensions
Android 5.1 low very low None
Android 6.0 low very low None
Chrome 58 no low ChannelID
Firefox 55 very low low None

* Denotes very rough guesstimate of likelihood that unsupported things will get echoed back by the server in the wild, visibly breaking the connection.

Parrots FAQ

Does it really look like, say, Google Chrome with all the GREASE and stuff?

It LGTM, but please open up Wireshark and check. If you see something โ€” say something.

Aren't there side channels? Everybody knows that the bird is a wordparrot is dead

There sure are. If you found one that approaches practicality at line speed โ€” please tell us.

Things to implement in Golang to make parrots better

  • Extended ChannelID extensions
  • Enable sha512 and sha224 hashes by default
  • Implement RSA PSS signature algorithms
  • In general, any modern crypto is likely to be useful going forward.

Custom Handshake

It is possible to create custom handshake by

  1. Use HelloCustom as an argument for UClient() to get empty config
  2. Fill tls header fields: UConn.Hello.{Random, CipherSuites, CompressionMethods}, if needed, or stick to defaults.
  3. Configure and add various TLS Extensions to UConn.Extensions: they will be marshaled in order.
  4. Set Session and SessionCache, as needed.

If you need to manually control all the bytes on the wire(certainly not recommended!), you can set UConn.HandshakeStateBuilt = true, and marshal clientHello into UConn.HandshakeState.Hello.raw yourself. In this case you will be responsible for modifying other parts of Config and ClientHelloMsg to reflect your setup.

Fake Session Tickets

Set of provided functions is likely to change, as use-cases aren't fully worked out yet. Currently, there is a simple function to set session ticket to any desired state:

func (c *ExtendedConfig) SetSessionState(session *ClientSessionState)

Note that session tickets (fake ones or otherwise) are not reused.
To reuse tickets, create a shared cache and set it on current and further configs:

func (c *ExtendedConfig) SetSessionCache(cache ClientSessionCache)

Usage

Find other examples here.

For a reference, here's how default "crypto/tls" is used:

    config := tls.Config{ServerName: "www.google.com"}
    dialConn, err := net.Dial("tcp", "172.217.11.46:443")
    if err != nil {
        fmt.Printf("net.Dial() failed: %+v\n", err)
        return
    }
    tlsConn := tls.Client(dialConn, &config)
    err = tlsConn.Handshake()
    if err != nil {
    fmt.Printf("tlsConn.Handshake() error: %+v", err)
        return
    }

Now, if you want to use uTLS, simply substitute tlsConn := tls.Client(dialConn, &config) with tlsConn := utls.UClient(dialConn, &config, clientHelloID) where clientHelloID is one of the following:

  1. utls.HelloRandomized adds/reorders extensions, ciphersuites, etc. randomly.
    HelloRandomized adds ALPN in 50% of cases, you may want to use HelloRandomizedALPN or HelloRandomizedNoALPN to choose specific behavior explicitly, as ALPN might affect application layer.
  2. utls.HelloGolang HelloGolang will use default "crypto/tls" handshake marshaling codepath, which WILL overwrite your changes to Hello(Config, Session are fine). You might want to call BuildHandshakeState() before applying any changes. UConn.Extensions will be completely ignored.
  3. utls.HelloCustom will prepare ClientHello with empty uconn.Extensions so you can fill it with TLSExtension's manually.
  4. The rest will will parrot given browser.
    • utls.HelloChrome_Auto- parrots recommended(latest) Google Chrome version
    • utls.HelloChrome_58 - parrots Google Chrome 58
    • utls.HelloFirefox_Auto - parrots recommended(latest) Firefox version
    • utls.HelloFirefox_5 - parrots Firefox 55
    • utls.HelloAndroid_Auto
    • utls.HelloAndroid_6_0_Browser
    • utls.HelloAndroid_5_1_Browser

Note: it is mandatory to manually call tlsConn.Handshake() afterwards. Otherwise, eventual tls.Write() is going to call non-overridden version of handshake.

Customizing handshake

Before doing Handshake() you can also set fake session ticket, set clientHello or change uconn in other ways:

    cRandom := []byte{100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
        110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
        120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
        130, 131}
    tlsConn.SetClientRandom(cRandom)
    masterSecret := make([]byte, 48)
    copy(masterSecret, []byte("masterSecret is NOT sent over the wire")) // you may use it for real security

    // Create a session ticket that wasn't actually issued by the server.
    sessionState := utls.MakeClientSessionState(sessionTicket, uint16(tls.VersionTLS12),
        tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
        masterSecret,
        nil, nil)
    tlsConn.SetSessionState(sessionState)

This is not an official Google product.

utls's People

Contributors

aclements avatar adg avatar agl avatar ainar-g avatar amalaviy avatar bemasc avatar benburkert avatar bradfitz avatar cespare avatar cixtor avatar coruus avatar d1str0 avatar danp avatar davidben avatar dmitshur avatar dominikh avatar filosottile avatar ianlancetaylor avatar joneskoo avatar josharian avatar jstemmer avatar kevinburke avatar mvdan avatar nhooyr avatar ralphcorderoy avatar rsc avatar sergeyfrolov avatar tamird avatar titanous avatar tombergan avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.