goshod/GoShod.go
2022-05-17 22:06:56 +05:30

161 lines
4.7 KiB
Go

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)
}