Skip to content

Commit

Permalink
Initial commit of go-scamalytics application
Browse files Browse the repository at this point in the history
This commit includes the initial version of the go-scamalytics command-line application, which allows users to check the fraud score of a list of IP addresses using scamalytics.com. The application is designed for security professionals and developers who need to quickly check the fraud score of multiple IP addresses and generate a report in CSV format. The app is written in Go and can be compiled for multiple platforms, including Windows, Linux, and macOS. This commit also includes a makefile for easy compilation of the application, and a README.md file with instructions on how to use and install the application.
  • Loading branch information
Onion Wizard authored and Onion Wizard committed Apr 15, 2023
1 parent 0e653fc commit 95c2c21
Show file tree
Hide file tree
Showing 9 changed files with 267 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@

# Dependency directories (remove the comment below to include it)
# vendor/
.DS_Store
go.mod
build/go-scamalytics_macos_intel
33 changes: 33 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
APP_NAME=go-scamalytics
BUILD_DIR=build
SRC_FILES=*.go

# Windows x86-64
build_win64:
GOOS=windows GOARCH=amd64 go build -o $(BUILD_DIR)/$(APP_NAME)_win64.exe $(SRC_FILES)

# Windows x86
build_win32:
GOOS=windows GOARCH=386 go build -o $(BUILD_DIR)/$(APP_NAME)_win32.exe $(SRC_FILES)

# Linux x86-64
build_linux64:
GOOS=linux GOARCH=amd64 go build -o $(BUILD_DIR)/$(APP_NAME)_linux64 $(SRC_FILES)

# Linux x86
build_linux32:
GOOS=linux GOARCH=386 go build -o $(BUILD_DIR)/$(APP_NAME)_linux32 $(SRC_FILES)

# macOS Intel
build_macos_intel:
GOOS=darwin GOARCH=amd64 go build -o $(BUILD_DIR)/$(APP_NAME)_macos_intel $(SRC_FILES)

# macOS M1
build_macos_arm:
GOOS=darwin GOARCH=arm64 go build -o $(BUILD_DIR)/$(APP_NAME)_macos_m1 $(SRC_FILES)


build_all: build_win64 build_win32 build_linux64 build_linux32 build_macos_intel build_macos_arm

clean:
rm -rf $(BUILD_DIR)
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,33 @@
# go-scamalytics
Check IP list on scamalytics.com exlude official API

![Console output](https://raw.githubusercontent.com/Allespro/go-scamalytics/master/img/1.png)


![CVS output](https://raw.githubusercontent.com/Allespro/go-scamalytics/master/img/2.png)

go-scamalytics is a command-line application that allows users to check the fraud score of a list of IP addresses using scamalytics.com. The application works by scraping data from the scamalytics.com website without using the official API, which allows users to perform this check for free.

The app is designed for security professionals and developers who need to quickly check the fraud score of multiple IP addresses and generate a report in CSV format. The application is written in Go and can be compiled for multiple platforms, including Windows, Linux, and macOS.

## Build
To install go-scamalytics, you will first need to clone the repository from GitHub and build them.

```
git clone https://github.com/Allespro/go-scamalytics
cd go-scamalytics
make
```

After running the make command, you can find the compiled binary files in the `build` directory within the project directory. These binary files can be executed directly on their respective platforms.

## Usage
Once compiled, you can run the application from the command line. To see the available options, run `go-scamalytics --help`.

```
go-scamalytics -i inputFile.txt -o outputFile.csv -u useragents.txt
```

## License

This project is licensed under the MIT License - see the file [LICENSE](https://github.com/Allespro/go-scamalytics/blob/main/LICENSE) for details.
10 changes: 10 additions & 0 deletions check_ip.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
65.3.138.75
12.134.112.46
134.221.134.31
181.236.134.173
55.8.36.204
167.144.204.155
187.117.243.165
40.93.80.10
60.76.138.69
130.170.56.72
11 changes: 11 additions & 0 deletions checked_ip.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ip;score;risk
65.3.138.75;50;medium
12.134.112.46;30;medium
134.221.134.31;57;medium
181.236.134.173;29;medium
55.8.36.204;100;very high
167.144.204.155;0;low
187.117.243.165;13;low
40.93.80.10;17;low
60.76.138.69;54;medium
130.170.56.72;0;low
Binary file added img/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
146 changes: 146 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package main

import (
"bufio"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"math/rand"
"net/http"
"os"
"regexp"
"strings"
)

func checkIP(ip, useragentsFile string) map[string]interface{} {
userAgents, err := ioutil.ReadFile(useragentsFile)
if err != nil {
fmt.Printf("Failed to read useragents file: %s\n", err.Error())
os.Exit(1)
}
userAgentsList := strings.Split(string(userAgents), "\n")
userAgent := userAgentsList[rand.Intn(len(userAgentsList))]
url := fmt.Sprintf("https://scamalytics.com/ip/%s", ip)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Printf("Can`t init request: %s\n", err.Error())
os.Exit(1)
}
req.Header.Set("User-Agent", userAgent)
req.Host = "scamalytics.com"
client := &http.Client{}
response, err := client.Do(req)
if err != nil {
fmt.Printf("Failed to get response from the server: %s\n", err.Error())
os.Exit(1)
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
fmt.Printf("Can't check IP %s - Response code: %d\n", ip, response.StatusCode)
return nil
}
fmt.Printf("Checking IP %s\n", ip)
body, err := ioutil.ReadAll(response.Body)
if err != nil {
fmt.Printf("Failed to read response body: %s\n", err.Error())
os.Exit(1)
}
pattern := regexp.MustCompile(`(?s)<pre[^>]*>(.*?)<\/pre>`)
matches := pattern.FindStringSubmatch(string(body))
if len(matches) != 2 {
fmt.Printf("Failed to find pattern in the response body\n")
os.Exit(1)
}
var data map[string]interface{}
if err := json.Unmarshal([]byte(matches[1]), &data); err != nil {
fmt.Printf("Failed to parse JSON response: %s\n", err.Error())
os.Exit(1)
}
return data
}

func addToCSV(filename string, ipInfo map[string]interface{}, delimiter string) {
file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
fmt.Printf("Failed to open file %s: %s\n", filename, err.Error())
os.Exit(1)
}
defer file.Close()
_, err = fmt.Fprintf(file, "%s%s%s%s%s\n",
ipInfo["ip"].(string), delimiter,
ipInfo["score"].(string), delimiter,
ipInfo["risk"].(string))
if err != nil {
fmt.Printf("Failed to write to file %s: %s\n", filename, err.Error())
os.Exit(1)
}
}

func loadIPFile(filename string) []string {
var ipAddresses []string
file, err := os.Open(filename)
if err != nil {
fmt.Printf("Failed to open file %s: %s\n", filename, err.Error())
os.Exit(1)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
ipAddresses = append(ipAddresses, scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Printf("Failed to read file %s: %s\n", filename, err.Error())
os.Exit(1)
}
return ipAddresses
}

func main() {
banner := `::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::::::::'###::::'##:::::'##:'########::'########:::::::::::
::::::::::'## ##::: ##:'##: ##:... ##..::'##. ##. ##::::::::::
:::::::::'##:. ##:: ##: ##: ##:::: ##:::: ##: ##:..:::::::::::
::::::::'##:::. ##: ##: ##: ##:::: ##::::. ########:::::::::::
:::::::: #########: ##: ##: ##:::: ##:::::... ##. ##::::::::::
:::::::: ##.... ##: ##: ##: ##:::: ##::::'##: ##: ##::::::::::
:::::::: ##:::: ##:. ###. ###::::: ##::::. ########:::::::::::
::::::::..:::::..:::...::...::::::..::::::........::::::::::::
: :
: Base Files: check_ip.txt / checked_ip.csv / useragents.txt :
: Version 0.1 :
: Check ip list on scamalytics.com exlude official API :
: :
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
`
fmt.Println(banner)
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: %s [OPTIONS]\n\n", os.Args[0])
fmt.Fprintln(os.Stderr, "Check IP list on scamalytics.com exlude official API")
fmt.Fprintln(os.Stderr, "Base Files: check_ip.txt / checked_ip.csv / useragents.txt")
fmt.Fprintln(os.Stderr, "\nOptions:")
flag.PrintDefaults()
}

inputFile := flag.String("i", "check_ip.txt", "Input file")
outputFile := flag.String("o", "checked_ip.csv", "Output file")
useragentsFile := flag.String("u", "useragents.txt", "Useragents file (for html parsing)")
delimiter := flag.String("d", ";", "Delimiter for CSV")

flag.Parse()

if flag.NArg() > 0 {
flag.Usage()
os.Exit(1)
}
addToCSV(*outputFile, map[string]interface{}{"ip": "ip", "score": "score", "risk": "risk"}, *delimiter)
ips := loadIPFile(*inputFile)
for _, ip := range ips {
ipInfo := checkIP(ip, *useragentsFile)
if ipInfo != nil {
addToCSV(*outputFile, ipInfo, *delimiter)
} else {
return
}
}
}
33 changes: 33 additions & 0 deletions useragents.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36
Mozilla/5.0 (Windows NT 5.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.63 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.65 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36
Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36
Mozilla/5.0 (Windows NT 6.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36
Mozilla/5.0 (Windows NT 5.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36
Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.104 Safari/537.36

0 comments on commit 95c2c21

Please sign in to comment.