Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 0 additions & 24 deletions apiclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,30 +80,6 @@ func (apiclient *ApiClient) sendNetConnection(correlationId, repo, ipAddress, po

}

func (apiclient *ApiClient) sendFileEvent(correlationId, repo, fileType string, timestamp time.Time, tool Tool) error {

if !apiclient.DisableTelemetry || apiclient.EgressPolicy == EgressPolicyAudit {
fileEvent := &FileEvent{}

fileEvent.FileType = fileType
fileEvent.TimeStamp = timestamp
fileEvent.Tool = tool

url := fmt.Sprintf("%s/github/%s/actions/jobs/%s/fileevent", apiclient.APIURL, repo, correlationId)

return apiclient.sendApiRequest("POST", url, fileEvent)
}
return nil

}

/*func (apiclient *ApiClient) sendArtifact(correlationId, repo string, artifact artifact.Artifact) error {

url := fmt.Sprintf("%s/github/%s/actions/jobs/%s/artifact", apiclient.APIURL, repo, correlationId)

return apiclient.sendApiRequest("POST", url, artifact)
}*/

func (apiclient *ApiClient) sendApiRequest(method, url string, body interface{}) error {

jsonData, _ := json.Marshal(body)
Expand Down
50 changes: 12 additions & 38 deletions eventhandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,26 +60,8 @@ func (eventHandler *EventHandler) handleFileEvent(event *Event) {
// Uncomment to log file writes (only uncomment in INT env)
// WriteLog(fmt.Sprintf("file write %s, syscall %s", event.FileName, event.Syscall))

_, found := eventHandler.ProcessFileMap[event.Pid]
fileType := ""
if !found {
// TODO: Improve this logic to monitor dependencies across languages
if strings.Contains(event.FileName, "/node_modules/") && strings.HasSuffix(event.FileName, ".js") {
fileType = "Dependencies"

} else if strings.Contains(event.FileName, ".git/objects") {
fileType = "Source Code"
}

if fileType != "" {
tool := *eventHandler.GetToolChain(event.PPid, event.Exe)
eventHandler.ApiClient.sendFileEvent(eventHandler.CorrelationId, eventHandler.Repo, fileType, event.Timestamp, tool)
eventHandler.ProcessFileMap[event.Pid] = true
}
}

if isSourceCodeFile(event.FileName) {
_, found = eventHandler.SourceCodeMap[event.FileName]
_, found := eventHandler.SourceCodeMap[event.FileName]
if !found {
eventHandler.SourceCodeMap[event.FileName] = append(eventHandler.SourceCodeMap[event.FileName], event)
}
Expand All @@ -93,17 +75,15 @@ func (eventHandler *EventHandler) handleFileEvent(event *Event) {

if isFromDifferentProcess {
eventHandler.SourceCodeMap[event.FileName] = append(eventHandler.SourceCodeMap[event.FileName], event)
if !strings.Contains(event.FileName, "node_modules/") { // node_modules folder has overwrites by design, even has .cs files in some cases. Need a better way to handle that
counter, found := eventHandler.FileOverwriteCounterMap[event.Exe]
if !found || counter < 3 {
checksum, err := getProgramChecksum(event.Exe)
if err == nil {
WriteLog(fmt.Sprintf("[Source code overwritten] file: %s syscall: %s by exe: %s [%s] Timestamp: %s", event.FileName, event.Syscall, event.Exe, checksum, event.Timestamp.Format("2006-01-02T15:04:05.999999999Z")))
WriteAnnotation(fmt.Sprintf("StepSecurity Harden Runner: Source code overwritten file: %s syscall: %s by exe: %s", event.FileName, event.Syscall, event.Exe))
}

eventHandler.FileOverwriteCounterMap[event.Exe]++
counter, found := eventHandler.FileOverwriteCounterMap[event.Exe]
if !found || counter < 3 {
checksum, err := getProgramChecksum(event.Exe)
if err == nil {
WriteLog(fmt.Sprintf("[Source code overwritten] file: %s syscall: %s by exe: %s [%s] Timestamp: %s", event.FileName, event.Syscall, event.Exe, checksum, event.Timestamp.Format("2006-01-02T15:04:05.999999999Z")))
// WriteAnnotation(fmt.Sprintf("StepSecurity Harden Runner: Source code overwritten file: %s syscall: %s by exe: %s", event.FileName, event.Syscall, event.Exe))
}

eventHandler.FileOverwriteCounterMap[event.Exe]++
}
}
}
Expand All @@ -113,15 +93,9 @@ func (eventHandler *EventHandler) handleFileEvent(event *Event) {
}

func isSourceCodeFile(fileName string) bool {
ext := path.Ext(fileName)
// https://docs.github.com/en/get-started/learning-about-github/github-language-support
// TODO: Add js & ts back. node makes change to js files as part of downloading/ setting up dependencies
// TODO: Add more extensions
sourceCodeExtensions := []string{".c", ".cpp", ".cs", ".go", ".java"}
for _, extension := range sourceCodeExtensions {
if ext == extension {
return true
}
// If it has an extension or might be a Dockerfile
if strings.Contains(fileName, ".") || strings.Contains(fileName, "Dockerfile") {
return true
}

return false
Expand Down
8 changes: 6 additions & 2 deletions procmon_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ func (p *ProcessMonitor) MonitorProcesses(errc chan error) {
WriteLog("Rules deleted")

// files modified in working directory
r, _ := flags.Parse(fmt.Sprintf("-a exit,always -F dir=%s -F perm=wa -S open -S openat -S rename -S renameat -k %s", "/home/runner", fileMonitorTag))
workingDirectory := p.WorkingDirectory
if len(workingDirectory) == 0 {
workingDirectory = "/home/runner"
}
r, _ := flags.Parse(fmt.Sprintf("-a exit,always -F dir=%s -F perm=wa -S open -S openat -S rename -S renameat -k %s", workingDirectory, fileMonitorTag))

actualBytes, _ := rule.Build(r)

Expand All @@ -58,7 +62,7 @@ func (p *ProcessMonitor) MonitorProcesses(errc chan error) {
errc <- errors.Wrap(err, "failed to add audit rule")
}

WriteLog("File monitor added")
WriteLog(fmt.Sprintf("File monitor added for %s", workingDirectory))

r, _ = flags.Parse(fmt.Sprintf("-w %s -p w -k %s", "/home/agent", fileMonitorTag))
actualBytes, _ = rule.Build(r)
Expand Down