optiv / ScareCrow

ScareCrow - Payload creation framework designed around EDR bypass.
2.71k stars 503 forks source link

DLL Refresher detection #25

Closed 0xElessar closed 2 years ago

0xElessar commented 3 years ago

Hello,

thank you for providing such a great framework! Amazing work.

Unfortunately, the DLL Refresher code is detected by some AV, for example: NOD32. Example command:

../ScareCrow/ScareCrow -I beacon-sourcepoint-test1.bin -Loader dll -etw -domain www.microsoft.com

When I disabled refreshing and ETW, the DLL bypasses NOD32 though. I tried modifying the Struct.go, but editing is pretty hard due to "variable set and unused" compilation error.

Any chance that you can implement ETW and Refresher functionality as reflected (encrypted) DLL files? My Goland skills cannot do that in this language :(

thanks Rafal

GetRektBoy724 commented 3 years ago

Might wanna try my program,SharpUnhooker. Not only unhooks the whole API DLL, but it also disables AMSI (if loaded) and ETW. And also, usually "variable set and unused" is only a warning (in most programming languages).

0xElessar commented 3 years ago

Thank you, @GetRektBoy724 . Thank you for Csharp code. Very useful! Another one in C code is https://github.com/rsmudge/unhook-bof

But it would be great to integrate this code safely in this project. As it simplifies the pipeline very nicely :)

Indeed, "variable set and unused" is usually a warning, but in Goland seems to be a hard error :(

GetRektBoy724 commented 3 years ago

Thank you, @GetRektBoy724 . Thank you for Csharp code. Very useful! Another one in C code is https://github.com/rsmudge/unhook-bof

But it would be great to integrate this code safely in this project. As it simplifies the pipeline very nicely :)

image

Tylous commented 3 years ago

Hello,

thank you for providing such a great framework! Amazing work.

Unfortunately, the DLL Refresher code is detected by some AV, for example: NOD32. Example command:

../ScareCrow/ScareCrow -I beacon-sourcepoint-test1.bin -Loader dll -etw -domain www.microsoft.com

When I disabled refreshing and ETW, the DLL bypasses NOD32 though. I tried modifying the Struct.go, but editing is pretty hard due to "variable set and unused" compilation error.

Any chance that you can implement ETW and Refresher functionality as reflected (encrypted) DLL files? My Goland skills cannot do that in this language :(

thanks Rafal

I could look to make it a encrypted DLL in the next update however I do not think would stop the detection. What happens if you use the refresh with say wscript or control loaders? Does the same issue occur?

0xElessar commented 3 years ago

Hello @Tylous,

thank you again for the tool. I tried binary, DLL and wscript. NOD32 detected all of them with the same signature Kryptik.E or something similar. It was a static AV file check, no execution was required.

I checked deeper with DLL function. I found that this function triggers the detection:

func {{.Variables.Reloading}}(name string) error {
        {{.Variables.dll}}, {{.Variables.error}} := ioutil.ReadFile(name)
        if {{.Variables.error}} != nil {
            return {{.Variables.error}}
        }
[...] 

When I removed the content of this function detection stopped. The same happened when I used 'unmodified' flag. I attempted to check what exactly triggers detection, but modification of this code is pretty hard and time-consuming due to the error message ("declared but unused"). I changed "PAGE_EXECUTE_READWRITE" memory flag too, but this did not impact the detection.

I thought if this functionality is encrypted and loaded as reflective DLL, no signature can match it, especially as your tool will make the encryption unique every time it runs. Anyway, this is just an idea. If I am wrong, apologies!

thanks

Tylous commented 3 years ago

hmmm interesting. If it is this, try changing the variable name to adsfa and replace if {{.Variables.error}} != nil { return {{.Variables.error}} } with if {{.Variables.error}} != nil { }

0xElessar commented 3 years ago

I am sorry, @Tylous . I think you misunderstood me.

I meant the whole function starting with func {{.Variables.Reloading}}(name string) error {

The function contains the reference to:

{{.Variables.dll}}, {{.Variables.error}} := ioutil.ReadFile(name)
[...]
{{.Variables.x}} := {{.Variables.file}}.Section(".text")
[...]
{{.Variables.loaddll}}, {{.Variables.error}} := windows.LoadDLL(name)
[...]
{{.Variables.runfunc}}, _ := NtProtectVirtualMemory(
[...]

Apologies if I did not make myself clear.

Tylous commented 3 years ago

All good, I think I have an idea of what to do. Gonna start building and testing this week.

0xElessar commented 3 years ago

All good, I think I have an idea of what to do. Gonna start building and testing this week.

Great stuff. Much appreciated, @Tylous !

Tylous commented 3 years ago

Update: I am working on an updated version to address this and some other things. Please bare with me, while I test it all.

Tylous commented 2 years ago

Should be addressed in Patch 3.0

0xElessar commented 2 years ago

Thank you very much, @Tylous !

Tylous commented 2 years ago

Closing this issue if there are further issues related to this feel free to re-open.