Go Pentester – HTTP CLIENTS(2)

Building an HTTP Client That Interacts with Shodan

Shadon(URL:https://www.shodan.io/)  is the world‘s first search engine for Internet-connected devices.

Register and get the API key from Shadon, then set it as an environment variable.

 

 

 

 Here is a high-level overview of the typical steps for preparing and building an API client:

1. Review the service‘s API documentation.

  https://developer.shodan.io/api

2. Design a logical structure for the code in order to reduce complexity and repetition.

Project Structure

 

 main.go: Use primarily to interact with your client implementation.

3. Define request or response types, as necessary, in GO.

Cleaning Up API Calls in shodan.go.

package shodanconst BaseURL = "https://api.shodan.io"type Client struct { apiKey string}func New(apiKey string) *Client { return &Client{apiKey: apiKey}}

 

4. Create helper functions and types to facilitate simple initialization, authentication, and communication to reduce verbose or repetitive logic.

 Querying your Shodan Subscription

       api.go

package shodanimport ( "encoding/json" "fmt" "net/http")// Ref to shadon API doc: Sample Response//{//"query_credits": 56,//"scan_credits": 0,//"telnet": true,//"plan": "edu",//"https": true,//"unlocked": true,//}type APIInfo struct { QueryCredits int `json:"query_credits"` ScanCredits int `json:"scan_credits"` Telnet bool `json:"telnet"` Plan string `json:"plan"` HTTPS bool `json:"https"` Unlocked bool `json:"unlocked"`}// Making an HTTP GET request and decoding the responsefunc (s *Client) APIInfo()(*APIInfo, error) { // Ref to shodan API Doc: https://api.shodan.io/api-info?key={YOUR_API_KEY} res, err := http.Get(fmt.Sprintf("%s/api-info?key=%s", BaseURL, s.apiKey)) if err != nil { return nil, err } defer res.Body.Close() var ret APIInfo if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { return nil, err } return &ret, nil}

  host.go

package shodanimport ( "encoding/json" "fmt" "net/http")// Represents the location element within the hosttype HostLocation struct { City string `json:"city"` RegionCode string `json:"region_code"` AreaCode int `json:"area_code"` Longitude float32 `json:"longitude"` CountryCode3 string `json:"country_code3"` CountryName string `json:"country_name"` PostalCode string `json:"postal_code"` DMACode int `json:"dma_code"` CountryCode string `json:"country_code"` Latitude float32 `json:"latitude"`}// Represents a single matches elementtype Host struct { OS string `json:"os"` Timestamp string `json:"timestamp"` ISP string `json:"isp"` ASN string `json:"asn"` Hostnames []string `json:"hostnames"` Location HostLocation `json:"location"` IP int64 `json:"ip"` Domains []string `json:"domains"` Org string `json:"org"` Data string `json:"data"` Port int `json:"port"` IPString string `json:"ip_str"`}// Used for parsing the matches arraytype HostSearch struct { Matches []Host `json:"matches"`}// Ref to shodan API Doc: https://api.shodan.io/shodan/host/search?key={YOUR_API_KEY}&query={query}&facets={facets}func (s *Client) HostSearch(q string) (*HostSearch, error) { res, err := http.Get( fmt.Sprintf("%s/shodan/host/search?key=%s&query=%s", BaseURL, s.apiKey, q), ) if err != nil { return nil, err } defer res.Body.Close() var ret HostSearch if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { return nil, err } return &ret, nil}

  

5. Build the client that interacts with the API consumer functions and types.

 Create a Client- main.go

package mainimport ( "Shodan/src/shodan/shodan" "fmt" "log" "os")func main() { if len(os.Args) != 2 { log.Fatalln("Usage: shodan searchterm") } apiKey := os.Getenv("SHODAN_API_KEY") s := shodan.New(apiKey) info, err := s.APIInfo() if err != nil { log.Panicln(err) } fmt.Printf( "Query Credits: %d\nScan Credits: %d\n\n", info.QueryCredits, info.ScanCredits) hostSearch, err := s.HostSearch(os.Args[1]) if err != nil { log.Panicln(err) } for _, host := range hostSearch.Matches { fmt.Printf("%18s%8d\n", host.IPString, host.Port) }}

Run the Shodan search program.

SHODAN_API_KEY=XXXX go run main.go tomcat

 

相关文章