Exemple #1
0
// PrintActionStatus print message with action execution status
func PrintActionStatus(status int) {
	switch status {
	case 0:
		fmtc.Println("{g}OK{!}")
	case 1:
		fmtc.Println("{r}ERROR{!}")
	}
}
Exemple #2
0
// Init starts initialization rutine
func Init() {
	args, errs := arg.Parse(argMap)

	if len(errs) != 0 {
		fmtc.Println("{r}Arguments parsing errors:{!}")

		for _, err := range errs {
			fmtc.Printf("  {r}%v{!}\n", err)
		}

		os.Exit(1)
	}

	if arg.GetB(ARG_NO_COLOR) {
		fmtc.DisableColors = true
	}

	if arg.GetB(ARG_VER) {
		showAbout()
		return
	}

	if arg.GetB(ARG_HELP) || len(args) == 0 {
		showUsage()
		return
	}

	runtime.GOMAXPROCS(2)

	process(args)
}
Exemple #3
0
func readUserInput(title string, nonEmpty bool, private bool) (string, error) {
	if title != "" {
		fmtc.Printf("{c}%s{!}\n", title)
	}

	var (
		input string
		err   error
	)

	for {
		input, err = linenoise.Line(Prompt)

		if err != nil {
			return "", err
		}

		if nonEmpty && strings.TrimSpace(input) == "" {
			PrintWarnMessage("\nYou must enter non empty value\n")
			continue
		}

		if private && input != "" {
			if MaskSymbolColorTag == "" {
				fmt.Println(getPrivateHider(input))
			} else {
				fmtc.Println(MaskSymbolColorTag + getPrivateHider(input) + "{!}")
			}
		}

		break
	}

	return input, err
}
Exemple #4
0
// showServerMessage show message from SSL Labs API
func showServerMessage() {
	serverMessage := strings.Join(api.Info.Messages, " ")
	wrappedMessage := fmtutil.Wrap(serverMessage, "", 80)

	var coloredMessage string

	for _, line := range strings.Split(wrappedMessage, "\n") {
		coloredMessage += "{s-}" + line + "{!}\n"
	}

	fmtc.NewLine()
	fmtc.Println(coloredMessage)
}
Exemple #5
0
// Separator print separator to output
func Separator(tiny bool, args ...string) {
	sep := SeparatorColorTag + _SEPARATOR + "{!}"

	if len(args) != 0 {
		name := args[0]
		sep = SeparatorColorTag + "-- {!}" + SeparatorTitleColorTag + name + "{!} " + SeparatorColorTag + _SEPARATOR[:(84-len(name))] + "{!}"
	}

	if !tiny {
		sep = "\n" + sep + "\n"
	}

	fmtc.Println(sep)
}
Exemple #6
0
// printProtocolsInfo print info about supported protocols
func printProtocolsInfo(details *sslscan.EndpointDetails) {
	printCategoryHeader("Protocols")

	supportedProtocols := getProtocols(details.Protocols)

	for _, protocol := range protocolList {
		fmtc.Printf(" %-24s {s}|{!} ", protocol)

		switch {
		case protocol == "TLS 1.2":
			if supportedProtocols[protocol] {
				fmtc.Println("{g}Yes{!}")
			} else {
				fmtc.Println("{y}No{!}")
			}
		case protocol == "SSL 3.0" && supportedProtocols[protocol]:
			fmtc.Printf("{r}%s{!}\n", getBool(supportedProtocols[protocol]))
		case protocol == "SSL 2.0" && supportedProtocols[protocol]:
			fmtc.Printf("{r}%s{!}\n", getBool(supportedProtocols[protocol]))
		default:
			fmtc.Printf("%s\n", getBool(supportedProtocols[protocol]))
		}
	}
}
Exemple #7
0
// Render print usage info to console
func (info *Info) Render() {
	usageMessage := "\n{*}Usage:{!} " + info.name

	if len(info.commands) != 0 {
		usageMessage += " " + CommandsColorTag + "{command}{!}"
	}

	if len(info.options) != 0 {
		usageMessage += " " + OptionsColorTag + "{options}{!}"
	}

	if info.args != "" {
		usageMessage += " " + info.args
	}

	fmtc.Println(usageMessage)

	if info.spoiler != "" {
		fmtc.NewLine()
		fmtc.Println(info.spoiler)
	}

	if len(info.commands) != 0 {
		renderOptions(info.commands, CommandsColorTag)
	}

	if len(info.options) != 0 {
		renderOptions(info.options, OptionsColorTag)
	}

	if len(info.examples) != 0 {
		renderExamples(info)
	}

	fmtc.NewLine()
}
Exemple #8
0
// printCertificationPathsInfo print info about certificates in chain
func printCertificationPathsInfo(details *sslscan.EndpointDetails) {
	printCategoryHeader("Certification Paths")

	fmtc.Printf(" %-24s {s}|{!} %d\n", "Certificates provided", len(details.Chain.Certs))

	fmtc.Printf(" %-24s {s}|{!} ", "Chain issues")

	if details.Chain.Issues == 0 {
		fmtc.Println("None")
	} else {
		fmtc.Printf("{y}%s{!}\n", getChainIssuesDesc(details.Chain.Issues))
	}

	if len(details.Chain.Certs) > 1 {
		fmtutil.Separator(true)

		lastCertIndex := len(details.Chain.Certs) - 2

		for index, cert := range details.Chain.Certs[1:] {
			validUntilDate := time.Unix(cert.NotAfter/1000, 0)

			fmtc.Printf(" %-24s {s}|{!} %s\n", "Subject", cert.Label)
			fmtc.Printf(" %-24s {s}|{!} %s\n", "Valid until", timeutil.Format(validUntilDate, "%Y/%m/%d %H:%M:%S"))

			fmtc.Printf(" %-24s {s}|{!} ", "Key")

			if cert.KeyAlg == "RSA" && cert.KeyStrength < 2048 {
				fmtc.Printf("{y}%s %d bits (WEAK){!}\n", cert.KeyAlg, cert.KeySize)
			} else {
				fmtc.Printf("%s %d bits\n", cert.KeyAlg, cert.KeySize)
			}

			fmtc.Printf(" %-24s {s}|{!} %s\n", "Issuer", cert.IssuerLabel)

			fmtc.Printf(" %-24s {s}|{!} ", "Signature algorithm")

			if weakAlgorithms[cert.SigAlg] {
				fmtc.Printf("{y}%s (WEAK){!}\n", cert.SigAlg)
			} else {
				fmtc.Printf("%s\n", cert.SigAlg)
			}

			if index < lastCertIndex {
				fmtutil.Separator(true)
			}
		}
	}
}
Exemple #9
0
// renderMethod print method info to console
func renderMethod(m *Method, showExamples bool) {
	fmtc.Printf("{s-}%4d:{!} {b*}%s{!} {s}-{!} %s\n", m.Line, m.Name, m.UnitedDesc())

	if len(m.Arguments) != 0 {
		fmtc.NewLine()

		for _, a := range m.Arguments {
			switch {
			case a.IsOptional:
				fmtc.Printf("  {s-}%2s.{!} %s "+getVarTypeDesc(a.Type)+" {s-}[Optional]{!}\n", a.Index, a.Desc)
			case a.IsWildcard:
				fmtc.Printf("  {s-}%2s.{!} %s\n", a.Index, a.Desc)
			default:
				fmtc.Printf("  {s-}%2s.{!} %s "+getVarTypeDesc(a.Type)+"\n", a.Index, a.Desc)
			}
		}
	}

	if m.ResultCode {
		fmtc.NewLine()
		fmtc.Printf("  {*}Code:{!} 0 - ok, 1 - not ok\n")
	}

	if m.ResultEcho != nil {
		fmtc.NewLine()
		fmtc.Printf("  {*}Echo:{!} %s "+getVarTypeDesc(m.ResultEcho.Type)+"\n", strings.Join(m.ResultEcho.Desc, " "))
	}

	if m.Example != nil && showExamples {
		fmtc.NewLine()
		fmtc.Println("  {*}Example:{!}")
		fmtc.NewLine()

		for _, l := range m.Example {
			fmtc.Printf("    %s\n", l)
		}
	}
}
Exemple #10
0
// printCipherSuitesInfo print info about supported cipher suites
func printCipherSuitesInfo(details *sslscan.EndpointDetails) map[int]int {
	printCategoryHeader("Cipher Suites")

	suiteIndex := make(map[int]int)

	for index, suite := range details.Suites.List {
		suiteIndex[suite.ID] = index

		tag := ""
		insecure := strings.Contains(suite.Name, "_RC4_")

		switch {
		case suite.Q != nil:
			tag = "{y}(WEAK){!}"
		case suite.DHStrength != 0 && suite.DHStrength < 2048:
			tag = "{y}(WEAK){!}"
		}

		if insecure {
			fmtc.Printf(" {r}%-42s{!} {s}|{!} {r}%d (INSECURE){!} ", suite.Name, suite.CipherStrength)
		} else {
			fmtc.Printf(" %-42s {s}|{!} %d ", suite.Name, suite.CipherStrength)
		}

		switch {
		case suite.DHStrength != 0:
			fmtc.Printf("{s-}(DH %d bits){!} "+tag+"\n",
				suite.DHStrength)
		case suite.ECDHBits != 0:
			fmtc.Printf("{s-}(ECDH %d bits ~ %d bits RSA){!} "+tag+"\n",
				suite.ECDHBits, suite.ECDHStrength)
		default:
			fmtc.Println(tag)
		}
	}

	return suiteIndex
}
Exemple #11
0
func main() {
	args, errs := arg.Parse(argMap)

	if len(errs) != 0 {
		fmtc.Println("Arguments parsing errors:")

		for _, err := range errs {
			fmtc.Printf("  %s\n", err.Error())
		}

		os.Exit(1)
	}

	if arg.GetB(ARG_NO_COLOR) {
		fmtc.DisableColors = true
	}

	if arg.GetB(ARG_VER) {
		showAbout()
		return
	}

	if arg.GetB(ARG_HELP) || len(args) == 0 {
		showUsage()
		return
	}

	switch len(args) {
	case 1:
		process(args[0], "")
	case 2:
		process(args[0], args[1])
	default:
		showUsage()
	}
}
Exemple #12
0
// printCertificateInfo print basic info about server key and certificate
func printCertificateInfo(details *sslscan.EndpointDetails) {
	printCategoryHeader("Server Key and Certificate")

	validFromDate := time.Unix(details.Cert.NotBefore/1000, 0)
	validUntilDate := time.Unix(details.Cert.NotAfter/1000, 0)

	// ---

	fmtc.Printf(" %-24s {s}|{!} %s\n", "Common names", strings.Join(details.Cert.CommonNames, " "))

	if len(details.Cert.AltNames) > 0 {
		if len(details.Cert.AltNames) > 5 {
			fmtc.Printf(
				" %-24s {s}|{!} %s {s-}(+%d more){!}\n",
				"Alternative names",
				strings.Join(details.Cert.AltNames[:4], " "),
				len(details.Cert.AltNames)-4,
			)
		} else {
			fmtc.Printf(" %-24s {s}|{!} %s\n", "Alternative names", strings.Join(details.Cert.AltNames, " "))
		}
	}

	// ---

	fmtc.Printf(" %-24s {s}|{!} %s\n", "Valid from", timeutil.Format(validFromDate, "%Y/%m/%d %H:%M:%S"))

	// ---

	fmtc.Printf(" %-24s {s}|{!} ", "Valid until")

	if time.Now().Unix() >= validUntilDate.Unix() {
		fmtc.Printf("{r}%s (EXPIRED){!}\n", timeutil.Format(validUntilDate, "%Y/%m/%d %H:%M:%S"))
	} else {
		fmtc.Printf("%s\n", timeutil.Format(validUntilDate, "%Y/%m/%d %H:%M:%S"))
	}

	// ---

	fmtc.Printf(" %-24s {s}|{!} %s %d bits\n", "Key", details.Key.Alg, details.Key.Size)
	fmtc.Printf(" %-24s {s}|{!} %s\n", "Weak Key (Debian)", getBool(details.Key.DebianFlaw))

	// ---

	fmtc.Printf(" %-24s {s}|{!} ", "Issuer")

	if details.Cert.Issues&64 == 64 {
		fmtc.Printf("%s {s-}(Self-signed){!}\n", details.Cert.IssuerLabel)
	} else {
		fmtc.Printf("%s\n", details.Cert.IssuerLabel)
	}

	// ---

	fmtc.Printf(" %-24s {s}|{!} ", "Signature algorithm")

	if weakAlgorithms[details.Cert.SigAlg] {
		fmtc.Printf("{y}%s (WEAK){!}\n", details.Cert.SigAlg)
	} else {
		fmtc.Printf("%s\n", details.Cert.SigAlg)
	}

	// ---

	fmtc.Printf(" %-24s {s}|{!} ", "Extended Validation")

	if details.Cert.ValidationType == "E" {
		fmtc.Println("{g}Yes{!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-24s {s}|{!} ", "Certificate Transparency")

	if details.Cert.SCT {
		fmtc.Println("{g}Yes{!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	if details.Cert.RevocationInfo != 0 {
		fmtc.Printf(" %-24s {s}|{!} %s\n", "Revocation information", getRevocationInfo(details.Cert.RevocationInfo))
	}

	// ---

	fmtc.Printf(" %-24s {s}|{!} ", "Revocation status")

	if details.Cert.RevocationStatus&1 == 1 {
		fmtc.Printf("{r}%s{!}\n", getRevocationStatus(details.Cert.RevocationStatus))
	} else {
		fmtc.Printf("%s\n", getRevocationStatus(details.Cert.RevocationStatus))
	}

	// ---

	fmtc.Printf(" %-24s {s}|{!} ", "Trusted")

	if details.Cert.Issues == 0 {
		fmtc.Println("{g}Yes{!}")
	} else {
		fmtc.Printf("{r}No (%s){!}\n", getCertIssuesDesc(details.Cert.Issues))
	}
}
Exemple #13
0
// printProtocolDetailsInfo print endpoint protocol details
func printProtocolDetailsInfo(details *sslscan.EndpointDetails) {
	printCategoryHeader("Protocol Details")

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Secure Renegotiation")

	if details.RenegSupport&1 == 1 {
		fmtc.Println("{y}Not supported{!}")
	} else {
		fmtc.Println("{g}Supported{!}")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Secure Client-Initiated Renegotiation")

	if details.RenegSupport&4 == 4 {
		fmtc.Println("{y}Supported (DoS DANGER){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Insecure Client-Initiated Renegotiation")

	if details.RenegSupport&1 == 1 {
		fmtc.Println("{r}Supported (INSECURE){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "POODLE (SSLv3)")

	if details.Poodle {
		fmtc.Println("{r}Vulnerable (INSECURE){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "POODLE (TLS)")

	if details.PoodleTLS == 2 {
		fmtc.Println("{r}Vulnerable (INSECURE){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "DROWN")

	if details.DrownVulnerable {
		fmtc.Println("{r}Vulnerable{!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	if details.Logjam {
		fmtc.Printf(" %-40s {s}|{!} {r}Vulnerable{!}\n", "Logjam")
	}

	// ---

	if details.Freak {
		fmtc.Printf(" %-40s {s}|{!} {r}Vulnerable{!}\n", "Freak")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Downgrade attack prevention")

	if !details.FallbackSCSV {
		fmtc.Println("{y}No, TLS_FALLBACK_SCSV not supported{!}")
	} else {
		fmtc.Println("{g}Yes, TLS_FALLBACK_SCSV supported{!}")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "SSL/TLS compression")

	if details.CompressionMethods != 0 {
		fmtc.Println("{r}Vulnerable (INSECURE){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "RC4")

	if details.SupportsRC4 {
		fmtc.Println("{r}Yes (INSECURE){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} %s\n", "Heartbeat (extension)", getBool(details.Heartbeat))

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Heartbleed (vulnerability)")

	if details.Heartbleed {
		fmtc.Println("{r}Vulnerable (INSECURE){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "OpenSSL CCS vuln.")

	switch details.OpenSslCCS {
	case -1:
		fmtc.Println("{y}Test failed{!}")
	case 0:
		fmtc.Println("{y}Unknown{!}")
	case 1:
		fmtc.Println("No")
	case 2:
		fmtc.Println("{y}Possibly vulnerable, but not exploitable{!}")
	case 3:
		fmtc.Println("{r}Vulnerable and exploitable{!}")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "OpenSSL Padding Oracle vuln.")

	switch details.OpenSSLLuckyMinus20 {
	case -1:
		fmtc.Println("{y}Test failed{!}")
	case 0:
		fmtc.Println("{y}Unknown{!}")
	case 1:
		fmtc.Println("No")
	case 2:
		fmtc.Println("{r}Vulnerable and insecure{!}")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Forward Secrecy")

	switch {
	case details.ForwardSecrecy == 0:
		fmtc.Println("{y}No (WEAK){!}")
	case details.ForwardSecrecy&1 == 1:
		fmtc.Println("{y}With some browsers{!}")
	case details.ForwardSecrecy&2 == 2:
		fmtc.Println("With modern browsers")
	case details.ForwardSecrecy&4 == 4:
		fmtc.Println("{g}Yes (with most browsers) (ROBUST){!}")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Application-Layer Protocol Negotiation")

	if strings.Contains(details.NPNProtocols, "h2") {
		fmtc.Println("Yes")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Next Protocol Negotiation")

	if details.SupportsNPN {
		fmtc.Printf("Yes {s-}(%s){!}\n", details.NPNProtocols)
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Session resumption (caching)")

	switch details.SessionResumption {
	case 0:
		fmtc.Println("{y}No (Session resumption is not enabled){!}")
	case 1:
		fmtc.Println("{y}No (IDs assigned but not accepted){!}")
	case 2:
		fmtc.Println("Yes")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} %s\n", "Session resumption (tickets)", getBool(details.SessionTickets&1 == 1))

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "OCSP stapling")

	if details.OCSPStapling {
		fmtc.Println("{g}Yes{!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Strict Transport Security (HSTS)")

	if details.HSTSPolicy != nil && details.HSTSPolicy.Status == sslscan.HSTS_STATUS_PRESENT {
		fmtc.Printf("{g}Yes{!} {s-}(%s){!}\n", details.HSTSPolicy.Header)

		if len(details.HSTSPreloads) != 0 {
			fmtc.Printf(" %-40s {s}|{!} ", "HSTS Preloading")
			fmtc.Println(getHSTSPreloadingMarkers(details.HSTSPreloads))
		}
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Public Key Pinning (HPKP)")

	if details.HPKPPolicy != nil {
		switch details.HPKPPolicy.Status {
		case sslscan.HPKP_STATUS_INVALID:
			fmtc.Println("{r}Invalid{!}")
		case sslscan.HPKP_STATUS_DISABLED:
			fmtc.Println("{y}Disabled{!}")
		case sslscan.HPKP_STATUS_INCOMPLETE:
			fmtc.Println("{y}Incomplete{!}")
		case sslscan.HPKP_STATUS_VALID:
			fmtc.Printf("{g}Yes{!} ")

			if details.HPKPPolicy.IncludeSubDomains {
				fmtc.Printf(
					"{s-}(max-age=%d; includeSubdomains){!}\n",
					details.HPKPPolicy.MaxAge,
				)
			} else {
				fmtc.Printf(
					"{s-}(max-age=%d){!}\n",
					details.HPKPPolicy.MaxAge,
				)
			}

			for _, pin := range getPinsFromPolicy(details.HPKPPolicy) {
				fmtc.Printf(" %-40s {s}|{!} {s-}%s{!}\n", "", pin)
			}
		default:
			fmtc.Println("No")
		}
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Long handshake intolerance")

	if details.MiscIntolerance&2 == 2 {
		fmtc.Println("{y}Yes{!}")
	} else if details.MiscIntolerance&4 == 4 {
		fmtc.Println("{y}Yes{!} {s-}(workaround success){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "TLS extension intolerance")

	if details.MiscIntolerance&1 == 1 {
		fmtc.Println("{y}Yes{!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "TLS version intolerance")

	if details.ProtocolIntolerance != 0 {
		fmtc.Printf("{y}%s{!}\n", getProtocolIntolerance(details.ProtocolIntolerance))
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Uses common DH primes")

	if details.DHUsesKnownPrimes != 0 {
		fmtc.Println("{y}Yes (Replace with custom DH parameters if possible){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "DH public server param (Ys) reuse")

	if details.DHYsReuse {
		fmtc.Println("{y}Yes{!}")
	} else {
		fmtc.Println("No")
	}
}