diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dd1ae90 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +*.txt +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work diff --git a/GoShod.gif b/GoShod.gif new file mode 100644 index 0000000..a9558aa Binary files /dev/null and b/GoShod.gif differ diff --git a/GoShod.go b/GoShod.go new file mode 100644 index 0000000..f15e9df --- /dev/null +++ b/GoShod.go @@ -0,0 +1,161 @@ +package main + +import ( + "bytes" + "flag" + "fmt" + "io" + "io/ioutil" + "log" + "mime" + "net" + "net/http" + "path/filepath" + "strconv" + "strings" + "sync" + + "github.com/jayateertha043/goshod/pkg/shodan_utils" + "github.com/pkg/browser" +) + +var ApiKey string = "" + +func main() { + + printbanner() + apiKey := flag.String("api", "", "Your Shodan API Key, One time Configure.") + flag.Parse() + if strings.TrimSpace(*apiKey) != "" { + ApiKey = strings.TrimSpace(*apiKey) + b_api := []byte(ApiKey) + err := ioutil.WriteFile("./shodan_config.txt", b_api, 0666) + if err != nil { + log.Fatalln("[*] Error writing api to configuration file at ./shodan_config.txt") + } + log.Println("[*] Api Key Configured at ./shodan_config.txt") + } + + var server_wg = new(sync.WaitGroup) + log.Println("[*] Looking for shodan_config.txt at current directory") + b, err := ioutil.ReadFile("./shodan_config.txt") + if err != nil { + log.Fatalln("[*] Shodan_config.txt not found, Kindly configure Shodan api key.") + } + + ApiKey = strings.TrimSpace(string(b)) + uri := startServer(server_wg) + log.Println("[*] Server started at: " + uri) + browser.OpenURL(uri) + server_wg.Wait() +} +func startServer(wg *sync.WaitGroup) string { + wg.Add(1) + ln, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + log.Fatal(err) + } + go func() { + defer ln.Close() + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + path := r.URL.Path + w.Header().Add("Access-Control-Allow-Origin", "*") + if path == "" || path == "/" { + path = "./html/index.html" + w.Header().Add("Content-Type", mime.TypeByExtension(filepath.Ext(path))) + bs, err := ioutil.ReadFile(path) + if err != nil { + log.Println(err) + } + io.Copy(w, bytes.NewBuffer(bs)) + } else if path == "/shodanpagecount" && r.Method == "POST" { + err := r.ParseForm() + if err != nil { + log.Println(err) + } + apikey := ApiKey + //apikey := r.FormValue("apikey") + search := r.FormValue("search") + + if strings.TrimSpace(apikey) == "" || strings.TrimSpace(search) == "" { + w.WriteHeader(401) + w.Write([]byte("missing necessary params !")) + + } else { + params := make(map[string]string, 0) + params["key"] = apikey + params["query"] = search + status_code, page_count, response_body := shodan_utils.ShodanSearchHostCount(params) + if status_code == 200 && page_count > 0 && response_body != "" { + w.WriteHeader(status_code) + p_str := strconv.Itoa(page_count) + w.Write([]byte(p_str)) + } else if page_count == -101 { + w.WriteHeader(status_code) + w.Write([]byte(response_body)) + } else { + w.WriteHeader(status_code) + w.Write([]byte(response_body)) + } + } + } else if path == "/shodansearch" && r.Method == "POST" { + err := r.ParseForm() + if err != nil { + log.Println(err) + } + apikey := ApiKey + //apikey := r.FormValue("apikey") + search := r.FormValue("search") + page := r.FormValue("page") + _, err = strconv.Atoi(page) + if err != nil || page == "" { + page = "1" + } + + if strings.TrimSpace(apikey) == "" || strings.TrimSpace(search) == "" || strings.TrimSpace(page) == "" { + w.WriteHeader(401) + w.Write([]byte("missing necessary params !")) + + } else { + params := make(map[string]string, 0) + params["key"] = apikey + params["query"] = search + params["page"] = page + if params["page"] < "0" { + params["page"] = "1" + } + + status_code, response_body := shodan_utils.GetShodanResultForPage(params) + w.WriteHeader(status_code) + w.Write([]byte(response_body)) + + } + } else { + path = "./html/" + path[1:] + w.Header().Add("Content-Type", mime.TypeByExtension(filepath.Ext(path))) + bs, err := ioutil.ReadFile(path) + if err != nil { + fmt.Println(err) + } + io.Copy(w, bytes.NewBuffer(bs)) + } + }) + log.Fatal(http.Serve(ln, nil)) + }() + return "http://" + ln.Addr().String() +} + +func printbanner() { + banner := + ` + +██████╗ ██████╗ ███████╗██╗ ██╗ ██████╗ ██████╗ +██╔════╝ ██╔═══██╗██╔════╝██║ ██║██╔═══██╗██╔══██╗ +██║ ███╗██║ ██║███████╗███████║██║ ██║██║ ██║ +██║ ██║██║ ██║╚════██║██╔══██║██║ ██║██║ ██║ +╚██████╔╝╚██████╔╝███████║██║ ██║╚██████╔╝██████╔╝ + ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ + +` + fmt.Println(banner) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..a7c15f0 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/jayateertha043/goshod + +go 1.16 + +require ( + github.com/Jeffail/gabs v1.4.0 + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..2ea259c --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo= +github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71 h1:X/2sJAybVknnUnV7AD2HdT6rm2p5BP6eH2j+igduWgk= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/html/css/style.css b/html/css/style.css new file mode 100644 index 0000000..346b065 --- /dev/null +++ b/html/css/style.css @@ -0,0 +1,3 @@ +#app { + background-color: var(--v-background-base); +} \ No newline at end of file diff --git a/html/index.html b/html/index.html new file mode 100644 index 0000000..7ecd0e8 --- /dev/null +++ b/html/index.html @@ -0,0 +1,106 @@ + + + + + + + + + + + + +
+GoShoD
+