func main() { if flag.NArg() == 0 { fmt.Fprintf(os.Stderr, "Usage: %s {HOST} [{OPTIONS}]\n", os.Args[0]) flag.PrintDefaults() os.Exit(1) } host := flag.Arg(0) fmt.Printf("Server: %s\n", tc.Bblue(fmt.Sprintf("%s:%d", host, *port))) c, err := ssltvd.Dial("tcp", fmt.Sprintf("%s:%d", host, *port), &ssltvd.Config{ InsecureSkipVerify: true, }) if err != nil { panic(err) } pl, err := c.Heartbeat(6, []byte("potato")) if err != nil { panic(err) } hex.Dump(pl) pl, err = c.Heartbeat(4, []byte("bird")) if err != nil { panic(err) } hex.Dump(pl) pl, err = c.Heartbeat(1000, []byte("hat")) if err != nil { panic(err) } hex.Dump(pl) }
func (p *Probe) v2HalfHandshake(version TLSVersion, ciphers []CipherInfo, curves []CurveInfo) (serverHello, serverCertificate, serverKeyExchange []byte, err error) { var c net.Conn c, err = net.Dial("tcp", fmt.Sprintf("%s:%d", p.Host, p.Port)) if err != nil { return } // Be polite - send a fatal alert before hanging up defer func() { c.Write([]byte{21, byte(uint(version) >> 8), byte(uint(version)), 0, 2, 2, 0}) c.Close() }() clienthello_length := 9 + 32 + 3*len(ciphers) // HACK: the total clienthello length is dependent on clienthello_length fitting in a 2-byte length field. clientHello := make([]byte, clienthello_length+2, clienthello_length+3) rawHello := clientHello l := writeSSL2Length(clientHello, clienthello_length) if l == 3 { rawHello = rawHello[0 : clienthello_length+3] clientHello = rawHello[1 : clienthello_length+3] } clientHello[2] = 1 // hello pint2(clientHello[3:], int(version)) pint2(clientHello[5:], 3*len(ciphers)) pint2(clientHello[7:], 0) // session_id length pint2(clientHello[9:], 32) // random length for i, c := range ciphers { pint3(clientHello[11+3*i:], int(c.ID)) } idx := 11 + 3*len(ciphers) // rand.Read(clientHello[idx : idx+32]) copy(clientHello[idx:idx+32], []byte("THIRTY-TWO INSANELY RANDOM BYTES")) if false { hex.Dump(clientHello) return } _, err = c.Write(clientHello) if err != nil { return } serverHello, err = readSSL2Capsule(c) if err != nil { return } if serverHello[0] != 0x04 { serverHello = nil err = fmt.Errorf("Was expecting a ServerHello.") } return }
func (p *Probe) halfHandshake(version TLSVersion, ciphers []CipherInfo, curves []CurveInfo, CompressionMethods []compressionMethod) (serverHello, serverCertificate, serverKeyExchange []byte, err error) { if version <= SSL_2_0 { return p.v2HalfHandshake(version, ciphers, curves) } var c net.Conn c, err = net.Dial("tcp", fmt.Sprintf("%s:%d", p.Host, p.Port)) if err != nil { return } // Be polite - send a fatal alert before hanging up defer func() { c.Write([]byte{21, byte(uint(version) >> 8), byte(uint(version)), 0, 2, 2, 0}) c.Close() }() if CompressionMethods == nil { CompressionMethods = []compressionMethod{compressionNone} } extensions := make(TLSExtensionList, 0, 2) if version >= TLS_1_0 { extensions = append(extensions, HelloECPointFormats()) extensions = append(extensions, ServerNameIndication(p.Host)) extensions = append(extensions, HelloSupportedCurves(curves)) extensions = append(extensions, HelloSignatureAlgorithms()) } extension_length := extensions.Len() clienthello_length := 46 + 2*len(ciphers) + 1 + len(CompressionMethods) if extension_length > 0 { clienthello_length += extension_length } clientHello := make([]byte, clienthello_length) clientHello[0] = 22 // handshake pint2(clientHello[1:], int(version)) pint2(clientHello[3:], clienthello_length-5) clientHello[5] = 1 // client_hello pint3(clientHello[6:], clienthello_length-9) pint2(clientHello[9:], int(version)) rand.Read(clientHello[11:42]) for j := 0; j < 32; j++ { clientHello[11+j] = byte((j%8 + 1) * 17) } clientHello[43] = 0 // Session ID length // Cipher List pint2(clientHello[44:], 2*len(ciphers)) for i, c := range ciphers { pint2(clientHello[46+2*i:], int(c.ID)) } idx := 46 + 2*len(ciphers) clientHello[idx+0] = byte(len(CompressionMethods)) for i, c := range CompressionMethods { clientHello[idx+1+i] = byte(c) } idx += 1 + len(CompressionMethods) // Extensions if extension_length > 0 { pint2(clientHello[idx:], extension_length-2) idx += 2 for _, x := range extensions { x.Copy(clientHello[idx:]) idx += x.Len() } } if false { hex.Dump(clientHello) return } _, err = c.Write(clientHello) if err != nil { return } hstype, serverHello, err := NextHandshake(c) if err != nil { serverHello = nil if alert, ok := err.(Alert); ok { // Ignore 'unrecognized name' warnings. if alert.Level == 1 && alert.Description == 112 { hstype, serverHello, err = NextHandshake(c) if err != nil { serverHello = nil return } } else { return } } else { return } } if hstype != 2 { serverHello = nil err = fmt.Errorf("Was expecting a ServerHello.") return } sess_l := int(serverHello[34]) cipher := IDCipher(uint32(serverHello[35+sess_l])<<8 | uint32(serverHello[36+sess_l])) if cipher.Auth == AU_RSA || cipher.Auth == AU_DSA || cipher.Auth == AU_ECDSA { hstype, serverCertificate, err = NextHandshake(c) if err != nil { serverCertificate = nil return } if hstype != 11 { serverCertificate = nil err = fmt.Errorf("Was expecting a Certificate") return } } if cipher.Kex == KX_ECDHE || cipher.Kex == KX_FFDHE { hstype, serverKeyExchange, err = NextHandshake(c) if err != nil { serverKeyExchange = nil return } if hstype != 12 { serverKeyExchange = nil err = fmt.Errorf("Was expecting a ServerKeyExchange") return } } return }