Skip to content

Commit c311129

Browse files
committed
feat: begin migration from python to go
1 parent 96c22a7 commit c311129

File tree

13 files changed

+450
-50
lines changed

13 files changed

+450
-50
lines changed

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@ db.sqlite3-journal
6666
instance/
6767
.webassets-cache
6868

69-
# Scrapy stuff:
70-
.scrapy
71-
7269
# Sphinx documentation
7370
docs/_build/
7471

cmd/root.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
tui "github.com/RoseSecurity/ScrapPY/internal/tui/utils"
8+
"github.com/RoseSecurity/ScrapPY/pkg/utils"
9+
"github.com/spf13/cobra"
10+
)
11+
12+
var (
13+
blue = "\033[34m"
14+
red = "\033[91m"
15+
green = "\033[92m"
16+
norm = "\x1b[0m"
17+
tag = "@RoseSecurity"
18+
)
19+
20+
var rootCmd = &cobra.Command{
21+
Use: "scrapPY",
22+
Short: "ScrapPY enumerates documents, manuals, and sensitive PDFs for key phrases and words that can be utilized in dictionary and brute force attacks.",
23+
Long: `ScrapPY enumerates documents, manuals, and sensitive PDFs for key phrases and words
24+
that can be utilized in dictionary and brute force attacks. These keywords are outputted
25+
to a text file (ScrapPY.txt in the directory which the tool was run from) that can be read
26+
by tools such as Hydra, Dirb, and other offensive security tools for initial access and
27+
lateral movement.`,
28+
Run: func(cmd *cobra.Command, args []string) {
29+
file, _ := cmd.Flags().GetString("file")
30+
mode, _ := cmd.Flags().GetString("mode")
31+
outputFile, _ := cmd.Flags().GetString("output-file")
32+
33+
// Print help if no file is provided
34+
if file == "" {
35+
tui.PrintStyledText("SCRAPPY")
36+
fmt.Println(red + "Enter PDF file to scrape or use -h for help menu\n" + norm)
37+
return
38+
}
39+
40+
// Extract text from PDF
41+
fileContent, err := utils.ExtractTextFromPDF(file)
42+
if err != nil {
43+
utils.LogErrorAndExit(err)
44+
}
45+
46+
wordList := utils.RemoveCommonWords(fileContent)
47+
48+
if len(fileContent) == 0 {
49+
log.Fatalf("No content found in the PDF file: %s", file)
50+
}
51+
52+
// Process PDF content based on mode
53+
var keywords []string
54+
switch mode {
55+
case "word-frequency":
56+
keywords = utils.WordFrequency(wordList, 100)
57+
case "metadata":
58+
utils.PrintMetadata(file)
59+
if err != nil {
60+
utils.LogErrorAndExit(err)
61+
}
62+
return
63+
case "entropy":
64+
// keywords = utils.CalculateEntropy(wordList, 100)
65+
// default:
66+
// keywords = utils.ExtractKeywords(fileContent)
67+
}
68+
69+
// Write output to file
70+
if err := utils.WriteToFile(outputFile, keywords); err != nil {
71+
utils.LogErrorAndExit(err)
72+
}
73+
74+
fmt.Printf("%s has been created!\n", outputFile)
75+
},
76+
}
77+
78+
func init() {
79+
rootCmd.Flags().StringP("file", "f", "", "PDF input file")
80+
rootCmd.Flags().StringP("mode", "m", "full", "Modes of operation: full, word-frequency, metadata, entropy")
81+
rootCmd.Flags().StringP("output-file", "o", "ScrapPY.txt", "Output file name")
82+
}
83+
84+
func Execute() {
85+
if err := rootCmd.Execute(); err != nil {
86+
utils.LogErrorAndExit(err)
87+
}
88+
}

cmd/version.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package cmd
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"io"
7+
"net/http"
8+
"strings"
9+
10+
"github.com/fatih/color"
11+
"github.com/spf13/cobra"
12+
"golang.org/x/mod/semver"
13+
)
14+
15+
// Placeholder for builds
16+
var Version = "1.0.0"
17+
18+
type Release struct {
19+
TagName string `json:"tag_name"`
20+
}
21+
22+
var versionCmd = &cobra.Command{
23+
Use: "version",
24+
Short: "Print the CLI version",
25+
Long: `This command prints the CLI version`,
26+
Example: "scrapPY version",
27+
Run: func(cmd *cobra.Command, args []string) {
28+
fmt.Println("scrapPY: " + Version)
29+
latestReleaseTag, err := latestRelease()
30+
if err == nil && latestReleaseTag != "" {
31+
latestRelease := strings.TrimPrefix(latestReleaseTag, "v")
32+
currentRelease := strings.TrimPrefix(Version, "v")
33+
if semver.Compare(latestRelease, currentRelease) > 0 {
34+
updateScrapPY(latestRelease)
35+
}
36+
}
37+
},
38+
}
39+
40+
// Fetch latest release for comparison to current version
41+
func latestRelease() (string, error) {
42+
resp, err := http.Get("https://api.github.com/repos/RoseSecurity/ScrapPY/releases/latest")
43+
if err != nil {
44+
return "", fmt.Errorf("failed to fetch version: %w", err)
45+
}
46+
defer resp.Body.Close()
47+
48+
body, err := io.ReadAll(resp.Body)
49+
if err != nil {
50+
return "", fmt.Errorf("failed to read response body: %w", err)
51+
}
52+
53+
var release Release
54+
if err := json.Unmarshal(body, &release); err != nil {
55+
return "", fmt.Errorf("failed to parse version: %w", err)
56+
}
57+
58+
return release.TagName, nil
59+
}
60+
61+
// Display out of date warning
62+
func updateScrapPY(latestVersion string) {
63+
c1 := color.New(color.FgCyan)
64+
65+
c1.Println(fmt.Sprintf("\nYour version of ScrapPY is out of date. The latest version is %s\n\n", latestVersion))
66+
}

go.mod

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module github.com/RoseSecurity/ScrapPY
2+
3+
go 1.23.4
4+
5+
require (
6+
github.com/arsham/figurine v1.3.0
7+
github.com/barasher/go-exiftool v1.10.0
8+
github.com/fatih/color v1.18.0
9+
github.com/jwalton/go-supportscolor v1.2.0
10+
github.com/ledongthuc/pdf v0.0.0-20240201131950-da5b75280b06
11+
github.com/spf13/cobra v1.6.1
12+
golang.org/x/mod v0.22.0
13+
)
14+
15+
require (
16+
github.com/arsham/rainbow v1.2.1 // indirect
17+
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect
18+
github.com/inconshreveable/mousetrap v1.1.0 // indirect
19+
github.com/mattn/go-colorable v0.1.13 // indirect
20+
github.com/mattn/go-isatty v0.0.20 // indirect
21+
github.com/pkg/errors v0.9.1 // indirect
22+
github.com/spf13/pflag v1.0.5 // indirect
23+
golang.org/x/sys v0.25.0 // indirect
24+
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
25+
)

go.sum

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
github.com/arsham/figurine v1.3.0 h1:vpGbzp460B1gkdFt9jrl95v4wDE2vP3BDcg0AKWJ7J0=
2+
github.com/arsham/figurine v1.3.0/go.mod h1:cnw6B/y/XzRObDhQoqNJnpAGuSSrkjCcqZCcMJ1ag/I=
3+
github.com/arsham/rainbow v1.2.1 h1:iS8o/1WAPVFvhtMZgdiy7zM8mD+XIWZfwzGXD6manKI=
4+
github.com/arsham/rainbow v1.2.1/go.mod h1:vERoG76FE/wN9rGJRv9H/tTfH873AX6wfQdJqNRy6fA=
5+
github.com/barasher/go-exiftool v1.10.0 h1:f5JY5jc42M7tzR6tbL9508S2IXdIcG9QyieEXNMpIhs=
6+
github.com/barasher/go-exiftool v1.10.0/go.mod h1:F9s/a3uHSM8YniVfwF+sbQUtP8Gmh9nyzigNF+8vsWo=
7+
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ=
8+
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w=
9+
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
10+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
11+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
12+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
13+
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
14+
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
15+
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
16+
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
17+
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
18+
github.com/jwalton/go-supportscolor v1.2.0 h1:g6Ha4u7Vm3LIsQ5wmeBpS4gazu0UP1DRDE8y6bre4H8=
19+
github.com/jwalton/go-supportscolor v1.2.0/go.mod h1:hFVUAZV2cWg+WFFC4v8pT2X/S2qUUBYMioBD9AINXGs=
20+
github.com/ledongthuc/pdf v0.0.0-20240201131950-da5b75280b06 h1:kacRlPN7EN++tVpGUorNGPn/4DnB7/DfTY82AOn6ccU=
21+
github.com/ledongthuc/pdf v0.0.0-20240201131950-da5b75280b06/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
22+
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
23+
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
24+
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
25+
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
26+
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
27+
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
28+
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
29+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
30+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
31+
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
32+
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
33+
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
34+
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
35+
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
36+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
37+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
38+
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
39+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
40+
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
41+
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
42+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
43+
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
44+
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
45+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
46+
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
47+
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
48+
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
49+
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
50+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
51+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
52+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

internal/tui/utils/utils.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package utils
2+
3+
import (
4+
"os"
5+
6+
"github.com/arsham/figurine/figurine"
7+
"github.com/jwalton/go-supportscolor"
8+
)
9+
10+
// PrintStyledText prints a styled text to the terminal
11+
func PrintStyledText(text string) error {
12+
// Check if the terminal supports colors
13+
if supportscolor.Stdout().SupportsColor {
14+
return figurine.Write(os.Stdout, text, "ANSI Regular.flf")
15+
}
16+
return nil
17+
}

main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package main
2+
3+
import "github.com/RoseSecurity/ScrapPY/cmd"
4+
5+
func main() {
6+
cmd.Execute()
7+
}

pkg/utils/file_utils.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package utils
2+
3+
import (
4+
"fmt"
5+
"os"
6+
)
7+
8+
// WriteToFile writes the keywords to a specified output file
9+
func WriteToFile(filename string, keywords []string) error {
10+
file, err := os.Create(filename)
11+
if err != nil {
12+
return fmt.Errorf("error creating output file: %v", err)
13+
}
14+
defer file.Close()
15+
16+
// Write keywords to file
17+
for _, keyword := range keywords {
18+
if _, err := file.WriteString(keyword + "\n"); err != nil {
19+
return fmt.Errorf("error writing to file: %v", err)
20+
}
21+
}
22+
23+
return nil
24+
}

pkg/utils/log_utils.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package utils
2+
3+
import (
4+
"errors"
5+
"os"
6+
"os/exec"
7+
8+
"github.com/fatih/color"
9+
)
10+
11+
const (
12+
LogLevelTrace = "Trace"
13+
LogLevelDebug = "Debug"
14+
LogLevelInfo = "Info"
15+
LogLevelWarning = "Warning"
16+
)
17+
18+
// LogErrorAndExit logs errors to std.Error and exits with an error code
19+
func LogErrorAndExit(err error) {
20+
if err != nil {
21+
LogError(err)
22+
23+
// Find the executed command's exit code from the error
24+
var exitError *exec.ExitError
25+
if errors.As(err, &exitError) {
26+
exitCode := exitError.ExitCode()
27+
os.Exit(exitCode)
28+
}
29+
}
30+
}
31+
32+
// LogError logs errors to std.Error
33+
func LogError(err error) {
34+
if err != nil {
35+
c := color.New(color.FgRed)
36+
_, err2 := c.Fprintln(color.Error, err.Error()+"\n")
37+
if err2 != nil {
38+
color.Red("Error logging the error:")
39+
color.Red("%s\n", err2)
40+
color.Red("Original error:")
41+
color.Red("%s\n", err)
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)