-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdumpsniffer.go
142 lines (117 loc) · 3.65 KB
/
dumpsniffer.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
package main
import (
"fmt"
"os"
"path/filepath"
"strings"
"log"
"bufio"
"time"
"runtime"
"sync"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("Not a valid path.")
return
}
startTime := time.Now()
var memStats runtime.MemStats
filesInspected := 0
path := os.Args[1]
if isFile(path) {
if (!isPHPFile(path)) {
fmt.Println("Not a php file.")
return
}
occurences := checkDumpDieOccurences(path)
runtime.ReadMemStats(&memStats)
displayTimeAndFiles(startTime, 1, occurences, memStats.Alloc)
return
}
if isDir(path) {
// Get all files in directory, and subdirectory and subsubdirectory .. you got it
// We assign the response of the recursive function to two different error variables, one for the directory being iterated and one for the file.
// If no error occurs, check for dump occurrences; otherwise, display the error.
occurences := 0
// WaitGroup and Mutex are used to synchronize the goroutines
var wg sync.WaitGroup
dirError := filepath.Walk(path, func(filePath string, fileInfo os.FileInfo, fileError error) error {
// file error is not null, stop the script and display the error
if fileError != nil {
fmt.Printf("Error accessing %s: %s\n", filePath, fileError)
return fileError
}
if isPHPFile(filePath) {
filesInspected++
wg.Add(1)
go func(filePath string) {
defer wg.Done()
occurences += checkDumpDieOccurences(filePath)
}(filePath)
}
return nil
})
if dirError != nil {
fmt.Printf("Cannot read the directory %s: %s\n", path, dirError)
return
}
wg.Wait()
runtime.ReadMemStats(&memStats)
displayTimeAndFiles(startTime, filesInspected, occurences, memStats.Alloc)
return
}
}
func isFile(path string) bool {
fileInfo, err := os.Stat(path)
if err != nil {
return false
}
return fileInfo.Mode().IsRegular()
}
func isDir(path string) bool {
fileInfo, err := os.Stat(path)
if err != nil {
return false
}
return fileInfo.Mode().IsDir()
}
func isPHPFile(path string) bool {
ext := filepath.Ext(path)
ext = strings.ToLower(ext)
return ext == ".php"
}
func checkDumpDieOccurences(filePath string) int {
file, err := os.Open(filePath)
if err != nil {
log.Fatalf("Cannot open the file %s : %v", filePath, err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
occurencesFound := 0
lineNumber := 1
for scanner.Scan() {
// Get the line then lowercase it to be case insensitive
line := scanner.Text()
lowerLine := strings.ToLower(line)
// Check occurences
if strings.Contains(lowerLine, "dump(") {
fmt.Printf("%s: dump/var_dump found on line %d \n", filePath, lineNumber)
occurencesFound++
}
if strings.Contains(lowerLine, "die(") || strings.Contains(lowerLine, "die;") {
fmt.Printf("%s: die found on line %d \n", filePath, lineNumber)
occurencesFound++
}
lineNumber++
}
return occurencesFound
}
func displayTimeAndFiles(startTime time.Time, filesInspected int, occurences int, memoryAllocated uint64) {
memoryInKo := float64(memoryAllocated) / float64(1024)
elapsedTime := time.Since(startTime)
fmt.Printf("Elapsed time: %s\n", elapsedTime)
fmt.Printf("Number of files inspected: %d\n", filesInspected)
fmt.Printf("%d occurences found\n", occurences)
fmt.Printf("%.2fko memory allocated\n", memoryInKo)
}