Skip to content

Instantly share code, notes, and snippets.

@sleeyax
Created May 11, 2022 20:02
Show Gist options
  • Save sleeyax/cef95480e894045d5abc41fc9b3619bd to your computer and use it in GitHub Desktop.
Save sleeyax/cef95480e894045d5abc41fc9b3619bd to your computer and use it in GitHub Desktop.
Find Origin IP
package main
import (
"fmt"
"net/http"
"sync"
)
// based on: https://github.com/hakluke/hakoriginfinder
import (
"bufio"
"crypto/tls"
"flag"
"io/ioutil"
"log"
"os"
"time"
)
// Make HTTP request, check response
func worker(ips <-chan string, resChan chan<- string, wg *sync.WaitGroup, client *http.Client, hostname string) {
defer wg.Done()
for ip := range ips {
urls := []string{"http://" + ip, "https://" + ip}
for _, url := range urls {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Println("Error creating HTTP request", err)
continue
}
req.Header.Set("Host", hostname)
req.Header.Del("User-Agent")
resp, err := client.Do(req)
if err != nil {
continue
}
body, err := ioutil.ReadAll(resp.Body)
if err == nil && string(body) != "" {
resChan <- "MATCH " + url
} else {
resChan <- "MAYBE " + url
}
}
}
}
func main() {
// Set up CLI flags
workers := flag.Int("t", 32, "numbers of threads")
hostname := flag.String("h", "", "hostname of site, e.g. www.hakluke.com")
flag.Parse()
// Sanity check, print usage if no hostname specified
if *hostname == "" {
fmt.Println("A list of IP addresses must be provided via stdin, along with a hostname of the website you are trying to find the origin of.\n\nE.g. prips 1.1.1.0/24 | hakoriginfinder -h www.hakluke.com\n\nOptions:")
flag.PrintDefaults()
os.Exit(2)
}
// IP addresses are provided via stdin
scanner := bufio.NewScanner(os.Stdin)
// this channel will contain the ip addresses from stdin
ips := make(chan string)
// this is the channel used to push a response to
resChan := make(chan string)
// this channel indicates when the jobs are done
done := make(chan struct{})
// Set up Transport (disable SSL verification)
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
// Set up HTTP client
var client = &http.Client{
Timeout: time.Second * 10,
Transport: transport,
}
// Set up waitgroup
var wg sync.WaitGroup
wg.Add(*workers)
// Wait for workers to be done, then close the "done" channel
go func() {
wg.Wait()
close(done)
}()
// Fire up workers
for i := 0; i < *workers; i++ {
go worker(ips, resChan, &wg, client, *hostname)
}
// Add ips from stdin to ips channel
go func() {
for scanner.Scan() {
ips <- scanner.Text()
}
if err := scanner.Err(); err != nil {
log.Println(err)
}
close(ips)
}()
// print responses from response channel, or finish
for {
select {
case <-done:
return
case res := <-resChan:
// print results
fmt.Println(res)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment