-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfofa.nim
149 lines (127 loc) Β· 5.58 KB
/
fofa.nim
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
import argparse, terminal, random, os
import strformat, httpclient, base64, json, re
import nimlibxlsxwriter/xlsxwriter, strutils, times
# Worksheet name cannot contain invalid characters: '[ ] : * ? / \'
proc cleansn(sheetname: string): string =
result = sheetname.replace(re"[\[\]:\*\?/\\]+", "-")
result = result.replace(re"[']+", "\"")
const AllChars = {'\x20'..'\x7e'}
if result.len > 30:
result = result[0..29]
if result[^1] notin AllChars:
var last = result.len - 1
while result[last] notin AllChars:
last -= 1
var lenx = result.len-1 - last
var remainder = lenx mod 3
return result[0..result.len-1-remainder]
return result
if result.len == 0:
return "nil"
return result
proc savedata(mail: string, key: string, query: string, rules: string, size: string, output: string): void =
var fields: string = "host,ip,port,domain,title,country,province,city"
var client = newHttpClient()
if query.len != 0:
var b64_query: string = base64.encode(query)
var api_query: string = "https://fofa.so/api/v1/search/all?email={mail}&key={key}&qbase64={b64_query}&size={size}&fields={fields}".fmt
var result = parseJson(client.getContent(api_query))["results"]
var workbook: ptr lxw_workbook = workbook_new(output)
var worksheet: ptr lxw_worksheet = workbook_add_worksheet(workbook, "data")
var format: ptr lxw_format = workbook_add_format(workbook)
format_set_bold(format)
var title = fields.split(",")
for i in low(title)..high(title):
discard worksheet_write_string(worksheet, 0, lxw_col_t(i), title[i], nil)
for i in 0..<len(result):
for j in 0..<len(result[i]):
discard worksheet_write_string(worksheet, lxw_col_t(i + 1), lxw_col_t(j), result[i][j].getStr(), nil)
discard workbook_close(workbook)
echo "[*] query {query} done! ({len(result)})".fmt
if rules.len != 0:
echo "[+] rules: {rules}".fmt
var rfile: File
rfile = open(rules, fmRead)
var workbook: ptr lxw_workbook = workbook_new(output)
var format: ptr lxw_format = workbook_add_format(workbook)
format_set_bold(format)
for query in rfile.lines:
try:
var b64_query: string = base64.encode(query)
var api_query: string = "https://fofa.so/api/v1/search/all?email={mail}&key={key}&qbase64={b64_query}&size={size}&fields={fields}".fmt
var result = parseJson(client.getContent(api_query))["results"]
var worksheet: ptr lxw_worksheet = workbook_add_worksheet(workbook, cleansn(query))
var title = fields.split(",")
for i in low(title)..high(title):
discard worksheet_write_string(worksheet, 0, lxw_col_t(i), title[i], nil)
for i in 0..<len(result):
for j in 0..<len(result[i]):
discard worksheet_write_string(worksheet, lxw_col_t(i + 1), lxw_col_t(j), result[i][j].getStr(), nil)
echo "[*] query {query} done! ({len(result)})".fmt
except:
echo "Unknown exception!"
raise
discard workbook_close(workbook)
proc auth(mail: string, key: string, query: string, rules: string, size: string, output: string): void =
var authurl: string = "https://fofa.so/api/v1/info/my?email={mail}&key={key}".fmt
var client = newHttpClient()
for i in 1..3:
if not contains(client.request(authurl).body, "401 Unauthorized"):
savedata(mail, key, query, rules, size, output)
break
elif i < 3:
continue
else:
echo "[-] 401 Unauthorized, make sure email and apikey is correct."
quit()
proc color_banner(): void =
let color = [fgRed, fgGreen, fgYellow, fgBlue, fgMagenta, fgCyan, fgWhite]
let ascii_banner = """
βββββββββ dMMMMMP .aMMMb dMMMMMP .aMMMb
β ββββββββββ dMP dMP"dMP dMP dMP"dMP
βββββββββββ dMMMP dMP dMP dMMMP dMMMMMP
ββββββββββ dMP dMP.aMP dMP dMP dMP
ββββββββββ dMP VMMMP" dMP dMP dMP
https://github.com/inspiringz/nim-practice
"""
randomize()
stdout.styledWrite(sample(color), "\n{ascii_banner}\n".fmt)
when isMainModule:
let begin_time = times.cpuTime()
color_banner()
let p = newParser:
help("\neg: ./fofa -m <fofa_email_account> -k <fofa_api_key> -q '/login.rsp' -s 10000")
option("-m", "--mail", default=some(""), help="fofa email account")
option("-k", "--key", default=some(""), help="fofa api key")
option("-q", "--query", default=some(""), help="query string")
option("-f", "--file", default=some(""), help="batch query rules file")
option("-s", "--size", default=some("10000"), help="export data volume")
option("-o", "--output", default=some("data.xlsx"), help="output filename / absolute path")
let cmdline = os.commandLineParams()
if cmdline.len <= 1:
echo p.help
quit()
var
args = p.parse(cmdline)
mail: string = args.mail
key: string = args.key
query: string = args.query
size: string = args.size
rules: string
output: string
let current_dir = os.getCurrentDir()
if args.file.len != 0:
if contains(args.file, '\\') or contains(args.file, '/'):
rules = args.file
else:
rules = os.joinPath(current_dir, args.file)
if contains(args.output, '\\') or contains(args.output, '/'):
output = args.output
else:
output = os.joinPath(current_dir, args.output)
echo &"[+] email: {mail}"
echo &"[+] key: {key}"
auth(mail, key, query, rules, size, output)
echo &"[+] output: {output}"
let cost_time: float = times.cpuTime() - begin_time
echo "[+] cost: ", cost_time.formatFloat(ffDecimal, 4), " seconds"