├── .gitignore ├── go.mod ├── README.md └── main.go /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .idea -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/thecyberworld/reflector 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # reflector 2 | 3 | Reflector is a tool to check for reflected query parameter values. 4 | 5 | #### Usage 6 | Reflector is a command line tool that takes a single argument, which is the name of a file containing a list of URLs to check. The file should contain one URL per line. 7 | 8 | ```shell 9 | reflector urls.txt 10 | ``` 11 | 12 | #### Output 13 | Reflector will write the URLs for which query parameter values are reflected in the response body to a file named "reflected_urls.txt" in the current working directory. It will also print the URLs to the console. 14 | 15 | #### Install 16 | 17 | ```shell 18 | go install github.com/thecyberworld/reflector@latest 19 | ``` 20 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "net/http" 7 | "net/url" 8 | "os" 9 | "strings" 10 | ) 11 | 12 | func main() { 13 | // Check if a file name was passed as an argument 14 | if len(os.Args) < 2 { 15 | fmt.Println("Please provide a file name as an argument") 16 | return 17 | } 18 | // Open the file 19 | fileName := os.Args[1] 20 | file, err := os.Open(fileName) 21 | if err != nil { 22 | fmt.Printf("Error opening file %s: %v\n", fileName, err) 23 | return 24 | } 25 | defer file.Close() 26 | // Read the file contents 27 | 28 | fileBytes, err := ioutil.ReadAll(file) 29 | if err != nil { 30 | fmt.Printf("Error reading file %s: %v\n", fileName, err) 31 | return 32 | } 33 | // Split the file contents into URLS 34 | URLS := strings.Split(string(fileBytes), "\n") 35 | 36 | // Open the file for writing 37 | outputFile, err := os.OpenFile("reflected_urls.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 38 | 39 | if err != nil { 40 | fmt.Printf("Error opening output file: %v\n", err) 41 | return 42 | } 43 | defer outputFile.Close() 44 | 45 | // Iterate over the URLS in the file 46 | for _, URL := range URLS { 47 | URL = strings.TrimSpace(URL) 48 | if URL == "" { 49 | continue 50 | } 51 | // Send a GET request to the target URL 52 | response, err := http.Get(URL) 53 | if err != nil { 54 | fmt.Println(err) 55 | continue 56 | } 57 | defer response.Body.Close() 58 | // Read the response body 59 | body, err := ioutil.ReadAll(response.Body) 60 | if err != nil { 61 | fmt.Println(err) 62 | continue 63 | } 64 | // Parse the target URL 65 | parsedURL, err := url.Parse(URL) 66 | if err != nil { 67 | fmt.Println(err) 68 | continue 69 | } 70 | // Get the query parameters from the parsed URL 71 | queryParams := parsedURL.Query() 72 | 73 | // Iterate over the query parameters and check if the value is reflected in the response body 74 | isReflected := false 75 | for _, values := range queryParams { 76 | for _, value := range values { 77 | if strings.Index(string(body), value) != -1 { 78 | isReflected = true 79 | break 80 | } 81 | } 82 | if isReflected { 83 | // Append the URL to the output file 84 | if _, err := outputFile.WriteString(URL + "\n"); err != nil { 85 | fmt.Printf("Error writing to output file: %v\n", err) 86 | continue 87 | } 88 | fmt.Println("Reflected: " + URL) 89 | } 90 | } 91 | } 92 | } 93 | --------------------------------------------------------------------------------