|
@@ -10,8 +10,14 @@ package domainsniff
|
|
|
*/
|
|
|
import (
|
|
|
"crypto/tls"
|
|
|
+ "encoding/json"
|
|
|
+ "fmt"
|
|
|
"net"
|
|
|
+ "net/http"
|
|
|
+ "strings"
|
|
|
"time"
|
|
|
+
|
|
|
+ "imuslab.com/zoraxy/mod/utils"
|
|
|
)
|
|
|
|
|
|
// Check if the domain is reachable and return err if not reachable
|
|
@@ -27,30 +33,114 @@ func DomainReachableWithError(domain string) error {
|
|
|
}
|
|
|
|
|
|
// Check if a domain have TLS but it is self-signed or expired
|
|
|
-func DomainIsSelfSigned(domain string) (bool, error) {
|
|
|
+// Return false if sniff error
|
|
|
+func DomainIsSelfSigned(domain string) bool {
|
|
|
+ //Extract the domain from URl in case the user input the full URL
|
|
|
+ host, port, err := net.SplitHostPort(domain)
|
|
|
+ if err != nil {
|
|
|
+ host = domain
|
|
|
+ } else {
|
|
|
+ domain = host + ":" + port
|
|
|
+ }
|
|
|
+ if !strings.Contains(domain, ":") {
|
|
|
+ domain = domain + ":443"
|
|
|
+ }
|
|
|
+
|
|
|
//Get the certificate
|
|
|
conn, err := net.Dial("tcp", domain)
|
|
|
if err != nil {
|
|
|
- return false, err
|
|
|
+ return false
|
|
|
}
|
|
|
defer conn.Close()
|
|
|
|
|
|
+ //Connect with TLS using secure verify
|
|
|
+ tlsConn := tls.Client(conn, nil)
|
|
|
+ err = tlsConn.Handshake()
|
|
|
+ if err == nil {
|
|
|
+ //This is a valid certificate
|
|
|
+ fmt.Println()
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
//Connect with TLS using insecure skip verify
|
|
|
config := &tls.Config{
|
|
|
InsecureSkipVerify: true,
|
|
|
}
|
|
|
- tlsConn := tls.Client(conn, config)
|
|
|
+ tlsConn = tls.Client(conn, config)
|
|
|
err = tlsConn.Handshake()
|
|
|
- if err != nil {
|
|
|
- return false, err
|
|
|
- }
|
|
|
-
|
|
|
- //Check if the certificate is self-signed
|
|
|
- cert := tlsConn.ConnectionState().PeerCertificates[0]
|
|
|
- return cert.Issuer.CommonName == cert.Subject.CommonName, nil
|
|
|
+ //If the handshake is successful, this is a self-signed certificate
|
|
|
+ return err == nil
|
|
|
}
|
|
|
|
|
|
// Check if domain reachable
|
|
|
func DomainReachable(domain string) bool {
|
|
|
return DomainReachableWithError(domain) == nil
|
|
|
}
|
|
|
+
|
|
|
+// Check if domain is served by a web server using HTTPS
|
|
|
+func DomainUsesTLS(targetURL string) bool {
|
|
|
+ //Check if the site support https
|
|
|
+ httpsUrl := fmt.Sprintf("https://%s", targetURL)
|
|
|
+ httpUrl := fmt.Sprintf("http://%s", targetURL)
|
|
|
+
|
|
|
+ client := http.Client{Timeout: 5 * time.Second}
|
|
|
+
|
|
|
+ resp, err := client.Head(httpsUrl)
|
|
|
+ if err == nil && resp.StatusCode == http.StatusOK {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ resp, err = client.Head(httpUrl)
|
|
|
+ if err == nil && resp.StatusCode == http.StatusOK {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ //If the site is not reachable, return false
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ Request Handlers
|
|
|
+*/
|
|
|
+//Check if site support TLS
|
|
|
+//Pass in ?selfsignchk=true to also check for self-signed certificate
|
|
|
+func HandleCheckSiteSupportTLS(w http.ResponseWriter, r *http.Request) {
|
|
|
+ targetURL, err := utils.PostPara(r, "url")
|
|
|
+ if err != nil {
|
|
|
+ utils.SendErrorResponse(w, "invalid url given")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //If the selfsign flag is set, also chec for self-signed certificate
|
|
|
+ _, err = utils.PostBool(r, "selfsignchk")
|
|
|
+ if err == nil {
|
|
|
+ //Return the https and selfsign status
|
|
|
+ type result struct {
|
|
|
+ Protocol string `json:"protocol"`
|
|
|
+ SelfSign bool `json:"selfsign"`
|
|
|
+ }
|
|
|
+
|
|
|
+ scanResult := result{Protocol: "http", SelfSign: false}
|
|
|
+
|
|
|
+ if DomainUsesTLS(targetURL) {
|
|
|
+ scanResult.Protocol = "https"
|
|
|
+ if DomainIsSelfSigned(targetURL) {
|
|
|
+ scanResult.SelfSign = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ js, _ := json.Marshal(scanResult)
|
|
|
+ utils.SendJSONResponse(w, string(js))
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if DomainUsesTLS(targetURL) {
|
|
|
+ js, _ := json.Marshal("https")
|
|
|
+ utils.SendJSONResponse(w, string(js))
|
|
|
+ return
|
|
|
+ } else {
|
|
|
+ js, _ := json.Marshal("http")
|
|
|
+ utils.SendJSONResponse(w, string(js))
|
|
|
+ return
|
|
|
+ }
|
|
|
+}
|