@@ -12,25 +12,36 @@ import (
1212 "path/filepath"
1313 "strconv"
1414 "strings"
15+ "time"
1516)
1617
1718var justsuccess bool = false
18- var successlist []string
19+ var successlist map [ string ] []string
1920var httpcc http.Client
21+ var formatType string
22+ var outputDir string
23+
24+ func init () {
25+ successlist = make (map [string ][]string )
26+ }
2027
2128func main () {
2229
2330 http .DefaultTransport .(* http.Transport ).TLSClientConfig = & tls.Config {InsecureSkipVerify : true }
2431
25- address := flag .String ("url" , "" , "url address https://google.com" )
26- configfile := flag .String ("config" , "" , "config json file path " )
27- gitfile := flag .Bool ("git" , false , "try git lists" )
32+ address := flag .String ("url" , "" , "URL to scan (e.g., https://example.com)" )
33+ configfile := flag .String ("config" , "" , "custom config JSON file path" )
34+ format := flag .String ("f" , "" , "output format: json or csv" )
35+ outDir := flag .String ("o" , "" , "output directory path" )
36+ gitfile := flag .Bool ("git" , false , "scan git-related files" )
2837 Sensfile := flag .Bool ("sens" , false , "try sens lists" )
2938 Envfile := flag .Bool ("env" , false , "try env lists" )
3039 Shellfile := flag .Bool ("shell" , false , "try shellfile lists" )
3140 Allfile := flag .Bool ("all" , false , "try all lists" )
3241 success := flag .Bool ("v" , false , "show success result only" )
3342 flag .Parse ()
43+ formatType = * format
44+ outputDir = * outDir
3445 if ! * gitfile && ! * Sensfile && ! * Envfile && ! * Shellfile {
3546
3647 * Allfile = true
@@ -48,13 +59,13 @@ func main() {
4859 println ("please set url with --url or -h for help" )
4960 return
5061 }
51- ex , err := os .Executable ()
52- if err != nil {
53- panic (err )
54- }
55- exPath := filepath .Dir (ex )
62+ // ex, err := os.Executable()
63+ // if err != nil {
64+ // panic(err)
65+ // }
66+ // exPath := filepath.Dir(ex)
5667
57- configfilepath := exPath + " /SensitiveList.json"
68+ configfilepath := ". /SensitiveList.json"
5869 if * configfile != "" {
5970 configfilepath = * configfile
6071 }
@@ -79,51 +90,65 @@ func main() {
7990 httpcc = http.Client {Jar : jar }
8091 if * gitfile {
8192 for i := 0 ; i < len (paths .Git ); i ++ {
82- checkurl (* address + paths .Git [i ].Path , paths .Git [i ].Content , paths .Git [i ].Lentgh )
93+ checkurl (* address + paths .Git [i ].Path , paths .Git [i ].Content , paths .Git [i ].Lentgh , "Git" )
8394 }
8495 }
8596 if * Sensfile {
8697 for i := 0 ; i < len (paths .Sensitive ); i ++ {
87- checkurl (* address + paths .Sensitive [i ].Path , paths .Sensitive [i ].Content , paths .Sensitive [i ].Lentgh )
98+ checkurl (* address + paths .Sensitive [i ].Path , paths .Sensitive [i ].Content , paths .Sensitive [i ].Lentgh , "Sensitive" )
8899 }
89100 }
90101 if * Envfile {
91102 for i := 0 ; i < len (paths .Env ); i ++ {
92- checkurl (* address + paths .Env [i ].Path , paths .Env [i ].Content , paths .Env [i ].Lentgh )
103+ checkurl (* address + paths .Env [i ].Path , paths .Env [i ].Content , paths .Env [i ].Lentgh , "Env" )
93104 }
94105 }
95106 if * Shellfile {
96107 for i := 0 ; i < len (paths .Shell ); i ++ {
97- checkurl (* address + paths .Shell [i ].Path , paths .Shell [i ].Content , paths .Shell [i ].Lentgh )
108+ checkurl (* address + paths .Shell [i ].Path , paths .Shell [i ].Content , paths .Shell [i ].Lentgh , "Shell" )
98109 }
99110 }
100- fmt .Printf ("%d %s" , len (successlist ), " Found" )
101111
102- if len (successlist ) > 0 {
112+ totalFiles := 0
113+ for _ , files := range successlist {
114+ totalFiles += len (files )
115+ }
103116
104- for _ , v := range successlist {
105- println (v )
117+ if totalFiles > 0 {
118+ switch formatType {
119+ case "json" :
120+ writeJSONOutput (successlist , outputDir )
121+ case "csv" :
122+ writeCSVOutput (successlist , outputDir )
123+ default :
124+ printResults (successlist )
106125 }
126+ } else {
127+ fmt .Println ("\n 🔍 No sensitive files found." )
107128 }
108-
109129}
110130
111- func checkurl (url string , content string , len string ) {
131+ func checkurl (url string , content string , len string , category string ) {
132+ // Set timeout of 20 seconds
133+ httpcc .Timeout = 20 * time .Second
112134
113135 resp , err := httpcc .Head (url )
114136
115137 if err != nil {
138+ println (err .Error ())
116139 if strings .Contains (err .Error (), "http: server gave HTTP response to HTTPS clien" ) {
117140 os .Exit (3 )
118141 }
119- println (err .Error ())
142+ if strings .Contains (err .Error (), "timeout" ) {
143+ fmt .Printf ("Timeout occurred while checking '%s'\n " , url )
144+ return
145+ }
120146
121147 resp , err = httpcc .Get (url )
122148
123149 }
124150 if err == nil {
125151 if ! justsuccess {
126-
127152 fmt .Printf ("Checking '%s', '%s',\n " , url , resp .Status )
128153 }
129154 if resp .StatusCode == 200 {
@@ -136,34 +161,33 @@ func checkurl(url string, content string, len string) {
136161 if i != "" {
137162 ignore = append (ignore , i )
138163 }
139-
140164 }
141165 }
142166
143167 if respcontetnt == content || content == "*" || checkifinarry (ignore , respcontetnt ) {
144168 if len == "*" {
145-
146169 fmt .Printf ("Success '%s', '%s', '%s',\n " , url , resp .Status , resp .Header .Get ("Content-Type" ))
147- successlist = append (successlist , url )
170+ if _ , exists := successlist [category ]; ! exists {
171+ successlist [category ] = []string {}
172+ }
173+ successlist [category ] = append (successlist [category ], url )
148174 } else {
149175 lennumber , err := strconv .ParseInt (len , 0 , 64 )
150176 if err == nil {
151177 if lennumber >= resp .ContentLength {
152178 fmt .Printf ("Success '%s', '%s', '%s',\n " , url , resp .Status , resp .Header .Get ("Content-Type" ))
153- successlist = append (successlist , url )
179+ if _ , exists := successlist [category ]; ! exists {
180+ successlist [category ] = []string {}
181+ }
182+ successlist [category ] = append (successlist [category ], url )
154183 }
155184 }
156-
157185 }
158-
159186 }
160-
161187 }
162-
163188 } else {
164189 //fmt.Printf("'%s', '%s',\n", url, resp.Status)
165190 }
166-
167191 }
168192}
169193func checkifinarry (array []string , check string ) bool {
@@ -189,3 +213,75 @@ type SensitiveList struct {
189213 Env []Sensitive `json:Env`
190214 Shell []Sensitive `json:shell`
191215}
216+
217+ func writeJSONOutput (results map [string ][]string , outputDir string ) {
218+ output := struct {
219+ TotalCount int `json:"total_count"`
220+ Categories map [string ][]string `json:"categories"`
221+ Summary map [string ]int `json:"summary"`
222+ }{
223+ Categories : results ,
224+ Summary : make (map [string ]int ),
225+ }
226+
227+ for category , files := range results {
228+ output .Summary [category ] = len (files )
229+ output .TotalCount += len (files )
230+ }
231+
232+ jsonData , err := json .MarshalIndent (output , "" , " " )
233+ if err != nil {
234+ fmt .Printf ("Error creating JSON output: %v\n " , err )
235+ return
236+ }
237+
238+ if outputDir != "" {
239+ filename := filepath .Join (outputDir , "scan_results.json" )
240+ if err := os .WriteFile (filename , jsonData , 0644 ); err != nil {
241+ fmt .Printf ("Error writing JSON file: %v\n " , err )
242+ return
243+ }
244+ fmt .Printf ("📝 Results saved to: %s\n " , filename )
245+ } else {
246+ fmt .Println (string (jsonData ))
247+ }
248+ }
249+
250+ func writeCSVOutput (results map [string ][]string , outputDir string ) {
251+ var output strings.Builder
252+ output .WriteString ("Category,URL\n " )
253+
254+ for category , urls := range results {
255+ for _ , url := range urls {
256+ output .WriteString (fmt .Sprintf ("%s,%s\n " , category , url ))
257+ }
258+ }
259+
260+ if outputDir != "" {
261+ filename := filepath .Join (outputDir , "scan_results.csv" )
262+ if err := os .WriteFile (filename , []byte (output .String ()), 0644 ); err != nil {
263+ fmt .Printf ("Error writing CSV file: %v\n " , err )
264+ return
265+ }
266+ fmt .Printf ("📝 Results saved to: %s\n " , filename )
267+ } else {
268+ fmt .Print (output .String ())
269+ }
270+ }
271+
272+ func printResults (results map [string ][]string ) {
273+ totalFiles := 0
274+ for _ , files := range results {
275+ totalFiles += len (files )
276+ }
277+
278+ fmt .Printf ("\n 🎯 Found %d sensitive files:\n \n " , totalFiles )
279+
280+ for category , urls := range results {
281+ fmt .Printf ("📁 %s (%d files):\n " , category , len (urls ))
282+ for _ , url := range urls {
283+ fmt .Printf (" └─ %s\n " , url )
284+ }
285+ fmt .Println ()
286+ }
287+ }
0 commit comments