Skip to content

Commit 24be85b

Browse files
committed
🔥 Add main function
1 parent e60b9ad commit 24be85b

File tree

1 file changed

+279
-0
lines changed

1 file changed

+279
-0
lines changed

main.go

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"crypto/tls"
6+
"errors"
7+
"flag"
8+
"fmt"
9+
"io/ioutil"
10+
"net"
11+
"net/http"
12+
"net/url"
13+
"os"
14+
"regexp"
15+
"strconv"
16+
"strings"
17+
"time"
18+
19+
"github.com/fatih/color"
20+
log "github.com/projectdiscovery/gologger"
21+
)
22+
23+
func Err(e error) {
24+
if e != nil {
25+
log.Errorf("%s\n", e)
26+
os.Exit(1)
27+
}
28+
}
29+
30+
type Options struct {
31+
Query, Engine, Proxy string
32+
Page int
33+
Headers []string
34+
}
35+
36+
type Headers []string
37+
38+
const banner = `
39+
__ __
40+
___ ____ ______/ /__ ____/ /__
41+
/ _ '/ _ \/__/ _ / _ \/ __/ '_/
42+
\_, /\___/ \_,_/\___/_/ /_/\_\
43+
/___/
44+
v0.0.1 - @dwisiswant0
45+
`
46+
47+
var query, engine, proxy string
48+
var headers Headers
49+
var page int
50+
var noColor, silent bool
51+
52+
func (h Headers) String() string {
53+
return strings.Join(h, ", ")
54+
}
55+
56+
func (h *Headers) Set(val string) error {
57+
*h = append(*h, val)
58+
return nil
59+
}
60+
61+
func init() {
62+
flag.StringVar(&query, "q", "", "")
63+
flag.StringVar(&query, "query", "", "")
64+
65+
flag.StringVar(&engine, "e", "", "")
66+
flag.StringVar(&engine, "engine", "google", "")
67+
68+
flag.IntVar(&page, "p", 1, "")
69+
flag.IntVar(&page, "page", 1, "")
70+
71+
flag.Var(&headers, "header", "")
72+
flag.Var(&headers, "H", "")
73+
74+
flag.StringVar(&proxy, "x", "", "")
75+
flag.StringVar(&proxy, "proxy", "", "")
76+
77+
flag.BoolVar(&noColor, "nc", false, "")
78+
flag.BoolVar(&noColor, "no-color", false, "")
79+
80+
flag.BoolVar(&silent, "s", false, "")
81+
flag.BoolVar(&silent, "silent", false, "")
82+
83+
flag.Usage = func() {
84+
c := color.New(color.FgCyan, color.Bold).FprintfFunc()
85+
h := []string{
86+
banner,
87+
"Options:",
88+
" -q, --query <query> Search query",
89+
" -e, --engine <engine> Provide search engine (default: Google)",
90+
" (options: Google, Shodan, Bing, Duck, Yahoo, Ask)",
91+
" -p, --page <i> Specify number of pages (default: 1)",
92+
" -H, --header <header> Pass custom header to search engine",
93+
" -x, --proxy <proxy_url> Use proxy to surfing",
94+
" -s, --silent Silent mode",
95+
" -nc, --no-color Disable colored output results",
96+
"",
97+
}
98+
99+
c(os.Stderr, strings.Join(h, "\n"))
100+
}
101+
}
102+
103+
func main() {
104+
flag.Parse()
105+
106+
engine = strings.ToLower(engine)
107+
108+
if !silent {
109+
c := color.New(color.FgCyan, color.Bold)
110+
c.Println(banner)
111+
log.Labelf("Use at your own risk! Developers assume no responsibility")
112+
log.Labelf("If your IP address has been blocked by search engine providers or other reason.")
113+
log.Infof("Query : %s", query)
114+
log.Infof("Page : %s", strconv.Itoa(page))
115+
if proxy != "" {
116+
log.Infof("Proxy : %s", proxy)
117+
}
118+
if len(headers) > 0 {
119+
for _, h := range headers {
120+
log.Infof("Header: %s", h)
121+
}
122+
}
123+
log.Infof("Engine: %s\n\n", strings.Title(engine))
124+
}
125+
126+
stat, _ := os.Stdin.Stat()
127+
if (stat.Mode() & os.ModeCharDevice) == 0 {
128+
sc := bufio.NewScanner(os.Stdin)
129+
for sc.Scan() {
130+
query = sc.Text()
131+
opts := Options{
132+
Query: query,
133+
Engine: engine,
134+
Page: page,
135+
Proxy: proxy,
136+
Headers: headers,
137+
}
138+
139+
err := opts.Search(noColor)
140+
Err(err)
141+
}
142+
} else {
143+
if query == "" {
144+
log.Fatalf("Missing required -q flag!")
145+
os.Exit(2)
146+
}
147+
148+
opts := Options{
149+
Query: query,
150+
Engine: engine,
151+
Page: page,
152+
Proxy: proxy,
153+
Headers: headers,
154+
}
155+
156+
err := opts.Search(noColor)
157+
Err(err)
158+
}
159+
}
160+
161+
func Parser(html string, pattern string) [][]string {
162+
regex := regexp.MustCompile(pattern)
163+
match := regex.FindAllStringSubmatch(html, -1)[0:]
164+
return match
165+
}
166+
167+
func (opt *Options) Get(url string) string {
168+
client := Client(opt.Proxy)
169+
req, err := http.NewRequest("GET", url, nil)
170+
for _, h := range opt.Headers {
171+
parts := strings.SplitN(h, ":", 2)
172+
173+
if len(parts) != 2 {
174+
continue
175+
}
176+
req.Header.Set(parts[0], parts[1])
177+
}
178+
Err(err)
179+
180+
resp, err := client.Do(req)
181+
Err(err)
182+
defer resp.Body.Close()
183+
184+
data, _ := ioutil.ReadAll(resp.Body)
185+
body := string(data)
186+
return body
187+
}
188+
189+
func (opt *Options) Search(noColor bool) error {
190+
queryEsc := url.QueryEscape(opt.Query)
191+
var regexes, baseURL, params string
192+
var o = color.New(color.FgGreen)
193+
194+
switch opt.Engine {
195+
case "google":
196+
regexes = `"><a href="\/url\?q=(.*?)&amp;sa=U&amp;`
197+
baseURL = "https://www.google.com/search"
198+
params = ("q=" + queryEsc + "&gws_rd=cr,ssl&client=ubuntu&ie=UTF-8&start=")
199+
case "shodan":
200+
regexes = `\"><a href=\"/host/(.*?)\">`
201+
baseURL = "https://www.shodan.io/search"
202+
params = ("query=" + queryEsc + "&page=")
203+
case "bing":
204+
regexes = `</li><li class=\"b_algo\"><h2><a href=\"(.*?)\" h=\"ID=SERP,`
205+
baseURL = "https://www.bing.com/search"
206+
params = ("q=" + queryEsc + "&first=")
207+
case "duck":
208+
regexes = `<a rel=\"nofollow\" href=\"//duckduckgo.com/l/\?kh=-1&amp;uddg=(.*?)\">`
209+
baseURL = "https://html.duckduckgo.com/html/"
210+
params = ("q=" + queryEsc + "&_=")
211+
case "yahoo":
212+
regexes = `\" ac-algo fz-l ac-21th lh-24\" href=\"(.*?)\" referrerpolicy=\"origin`
213+
baseURL = "https://search.yahoo.com/search"
214+
params = ("q=" + queryEsc + "&b=")
215+
case "ask":
216+
regexes = `target=\"_blank\" href='(.*?)' data-unified=`
217+
baseURL = "https://www.ask.com/web"
218+
params = ("q=" + queryEsc + "&page=")
219+
default:
220+
return errors.New("Engine not found! Please choose one available.")
221+
}
222+
223+
for p := 1; p <= opt.Page; p++ {
224+
page := strconv.Itoa(p)
225+
226+
switch opt.Engine {
227+
case "google":
228+
page += "0"
229+
case "yahoo", "bing":
230+
page += "1"
231+
}
232+
233+
html := opt.Get(baseURL + "?" + params + page)
234+
result := Parser(html, regexes)
235+
for i := range result {
236+
url, err := url.QueryUnescape(result[i][1])
237+
Err(err)
238+
if noColor {
239+
fmt.Println(url)
240+
} else {
241+
o.Println(url)
242+
}
243+
}
244+
245+
if opt.Engine == "duck" && p == 1 {
246+
break
247+
}
248+
}
249+
250+
return nil
251+
}
252+
253+
func Client(proxy string) *http.Client {
254+
tr := &http.Transport{
255+
MaxIdleConns: 30,
256+
IdleConnTimeout: time.Second,
257+
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
258+
DialContext: (&net.Dialer{
259+
Timeout: time.Second * 10,
260+
KeepAlive: time.Second,
261+
}).DialContext,
262+
}
263+
264+
if proxy != "" {
265+
if p, err := url.Parse(proxy); err == nil {
266+
tr.Proxy = http.ProxyURL(p)
267+
}
268+
}
269+
270+
re := func(req *http.Request, via []*http.Request) error {
271+
return http.ErrUseLastResponse
272+
}
273+
274+
return &http.Client{
275+
Transport: tr,
276+
CheckRedirect: re,
277+
Timeout: time.Second * 10,
278+
}
279+
}

0 commit comments

Comments
 (0)