-
Notifications
You must be signed in to change notification settings - Fork 11
/
pastego.go
162 lines (145 loc) · 4.88 KB
/
pastego.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package main
import (
// import standard libraries
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"strings"
"time"
"github.com/notdodo/pastego/filesupport"
"github.com/notdodo/pastego/gui"
"github.com/notdodo/pastego/pegmatch"
// import third party libraries
"github.com/PuerkitoBio/goquery"
"gopkg.in/alecthomas/kingpin.v2"
)
// Command line args
var (
searchFor = kingpin.Flag("search", "Strings to search with optional bool operator(&&, ||, ~), i.e: \"password,some || (thing && ~maybenot), \"").Short('s').Default("pass").String()
outputTo = kingpin.Flag("output", "Folder to save the bins. Default : './results'").Short('o').Default("results").String()
caseInsens = kingpin.Flag("insensitive", "Search for case-insensitive strings").Default("false").Short('i').Bool()
)
// Using PEG check if the bin contains the searched word/s
func contains(link string, matches []string) (bool, string) {
var origMtch = make([]string, len(matches))
copy(origMtch, matches)
if *caseInsens {
link = strings.ToUpper(link)
for i, v := range matches {
matches[i] = strings.ToUpper(v)
}
}
pegmatch.PasteContentString = link
for i, mtch := range matches {
mtch = strings.TrimSpace(mtch)
got, err := pegmatch.ParseReader("", bytes.NewBufferString(mtch))
if err == nil && got.(bool) {
return true, strings.Split(origMtch[i], " ")[0]
}
}
return false, ""
}
// Parse the page and read the content of the bin
func pasteSearcher(link *filesupport.PasteJSON) {
client := &http.Client{Timeout: 10 * time.Second}
response, err := client.Get(link.ScrapeURL)
if err != nil {
logToFile(err.Error())
return
}
defer response.Body.Close()
doc, err := goquery.NewDocumentFromReader(response.Body)
if err != nil {
log.Fatalln(err)
}
doc.Find("body").Each(func(index int, item *goquery.Selection) {
bodyResult, bodyMatch := contains(item.Text(), strings.Split(*searchFor, ","))
titleResult, titleMatch := contains(link.Title, strings.Split(*searchFor, ","))
match := bodyMatch
if bodyResult || titleResult {
if titleResult {
match = titleMatch
}
if filesupport.SaveToFile(link, item.Text(), match, *outputTo) {
var s string
if link.Title != "" {
s = fmt.Sprintf("%s - %s - %s", match, link.FullURL, link.Title)
} else {
s = fmt.Sprintf("%s - %s", match, link.FullURL)
}
// Show recent pastes
gui.PrintTo("log", s)
logToFile(s)
// Triggers a reload
gui.ListDir()
}
}
})
}
// Fetch the bins
func getBins(bins int) []filesupport.PasteJSON {
url := "https://scrape.pastebin.com/api_scraping.php?limit=" + fmt.Sprint(bins)
slowDown := "Please slow down"
client := &http.Client{Timeout: 10 * time.Second}
var out []filesupport.PasteJSON
r, err := client.Get(url)
if err != nil {
logToFile(err.Error())
return out
}
defer r.Body.Close()
if r != nil {
// read []byte{}
b, _ := ioutil.ReadAll(r.Body)
// Due to some presence of unicode chars convert raw JSON to string than parse it
// GO strings works with utf-8
if err = json.NewDecoder(strings.NewReader(string(b))).Decode(&out); err != nil {
if strings.Contains(string(b), slowDown) || string(b) == "" {
logToFile("Slow down!\n")
} else {
// Error on marshalling JSON
s := fmt.Sprintf("\n%s\n", string(b))
logToFile(s)
}
}
}
return out
}
// Set the program to fetch `bins` bins every `interval` seconds
func run(interval int, bins int) {
parseBins := func() {
for _, v := range getBins(bins) {
pasteSearcher(&v)
}
}
// First run
parseBins()
logToFile("Done!\n")
// Run every 'interval' seconds
for range time.NewTicker(time.Duration(interval) * time.Second).C {
logToFile("Restarting...")
parseBins()
logToFile("Done!\n")
}
}
// Wrapper to avoid writing log function calls :)
func logToFile(s string) {
filesupport.LogToFile(s)
}
func main() {
kingpin.Parse()
logToFile(`
██████╗ █████╗ ███████╗████████╗███████╗ ██████╗ ██████╗
██╔══██╗██╔══██╗██╔════╝╚══██╔══╝██╔════╝██╔════╝ ██╔═══██╗
██████╔╝███████║███████╗ ██║ █████╗ ██║ ███╗██║ ██║
██╔═══╝ ██╔══██║╚════██║ ██║ ██╔══╝ ██║ ██║██║ ██║
██║ ██║ ██║███████║ ██║ ███████╗╚██████╔╝╚██████╔╝
╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚══════╝ ╚═════╝ ╚═════╝
`)
// Without a PRO account try to increase the first args and decrease the second.
go run(150, 250)
gui.SetGui(*outputTo)
}