Skip to content

Commit

Permalink
Merge pull request #8 from FourCoreLabs/ransomware-generic
Browse files Browse the repository at this point in the history
Adding System Encryption Ransomware Generic Behavior and Wallpaper Restore functionality
  • Loading branch information
achilles4828 authored Jan 26, 2024
2 parents 6936ac5 + 95a964c commit 7d3ac03
Show file tree
Hide file tree
Showing 30 changed files with 489 additions and 66 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
all: ransomware discovery uac_bypass

mockransomware:
go build github.com/FourCoreLabs/firedrill/cmd/mockransomware

ransomware:
go build github.com/FourCoreLabs/firedrill/cmd/ransomware

Expand Down
29 changes: 25 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ Read more about firedrill on our [**blog**](https://fourcore.io/blogs/firedrill-

## Ransomware Simulation

The ransomware simulation consists of typical behaviour of a ransomware.
The ransomware simulations consists of typical behaviour of a ransomware.

### Mock Ransomware
This includes, in this order:
- Encryption of files on the filesystem (only test files dropped by the binary and ).
- Encryption of files on the filesystem (only test files dropped by the binary ).
- Dropping a ransom note on the desktop.
- Changing the system wallapaper through registry keys (and restoring it after some time).

Expand All @@ -26,6 +27,20 @@ Sandbox Analysis
| [Hybrid-Analysis](https://www.hybrid-analysis.com/sample/21b95de03a83883b67fe14d9d517782f73276649378fbb4fca632c89410c2ba9/61dff7ee07ae9c2e3f3842e4) |
| [Intezer Analyze](https://analyze.intezer.com/analyses/50b1305b-16f1-4f12-8df7-97cdaf468cec) |


### System Ransomware
This includes, in this order:
- Encryption of user files on the filesystem (selects 10 files each from the User Desktop and Downloads folder).
- Dropping a ransom note on the desktop.
- Changing the system wallapaper through registry keys (and restoring it after some time).

Sandbox Analysis

| Sandbox |
| ------- |
| [Hybrid-Analysis](https://www.hybrid-analysis.com/sample/f2e7fc17a7d9d1f07b34b623cf77eaaa399171fc8bf1b7f24f3002d7782964d5) |
| [Virus Total](https://www.virustotal.com/gui/file/f2e7fc17a7d9d1f07b34b623cf77eaaa399171fc8bf1b7f24f3002d7782964d5?nocache=1) |

## Discovery Simulation

The discovery simulation consists of simulation of a malware executing three techniques from the Discovery tactic in MITRE ATT&CK, performing reconnaisance of system information which is used for further exploiting the system:
Expand Down Expand Up @@ -76,7 +91,13 @@ This includes, in this order:

## Windows

Ransomware Simulation
Mock Ransomware Simulation
```
$ make mockransomware
$ mockransomware.exe
```

System Ransomware Simulation
```
$ make ransomware
$ ransomware.exe
Expand All @@ -102,5 +123,5 @@ $ runkeyregistry.exe

## Linux/bash
```
$ GOOS=windows make ransomware # and so on
$ GOOS=linux make ransomware # and so on
```
11 changes: 11 additions & 0 deletions cmd/mockransomware/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

/*
Mock Ransomware firedrill
Simulation of a ransomware
- Changes wallpapers through windows registry.
- Drops ransom note on desktop.
- Encrypts files present on filesystem (drops sample files in a temp folder and does not destroy actual files).
- Restores wallpaper after simulation
*/
31 changes: 31 additions & 0 deletions cmd/mockransomware/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package main

import (
"context"

"github.com/FourCoreLabs/firedrill/pkg/behaviours/ransom_mockencrypt"
"github.com/FourCoreLabs/firedrill/pkg/behaviours/ransom_note"
"github.com/FourCoreLabs/firedrill/pkg/behaviours/ransom_wallpaper"
"github.com/FourCoreLabs/firedrill/pkg/sergeant"
"go.uber.org/zap"
)

var (
version string = "0.1"
)

func main() {
logger, _ := zap.NewProduction()

behaviours := []sergeant.Runnable{
ransom_mockencrypt.NewRansomEncrypt(),
ransom_note.NewRansomNote(),
ransom_wallpaper.NewRansomWallpaper(),
}

sergeant := sergeant.NewSergeant(logger, behaviours...)
if err := sergeant.Start(context.Background()); err != nil {
logger.Sugar().Fatalw("execution failed", "error", err.Error())

}
}
4 changes: 2 additions & 2 deletions cmd/ransomware/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ Ransomware firedrill
Simulation of a ransomware
- Changes wallpapers through windows registry.
- Drops ransom note on desktop.
- Encrypts files present on filesystem (drops sample files in a temp folder and does not destroy actual files).
- Read credentials from Chrome (does not print or decrypt any credentials).
- Picks random files from user's desktop and downloads folder and encrypts them in a new target folder left on the user's desktop.
- Restores wallpaper after simulation
*/
4 changes: 2 additions & 2 deletions cmd/ransomware/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package main
import (
"context"

"github.com/FourCoreLabs/firedrill/pkg/behaviours/ransom_encrypt"
"github.com/FourCoreLabs/firedrill/pkg/behaviours/ransom_note"
"github.com/FourCoreLabs/firedrill/pkg/behaviours/ransom_sysencrypt"
"github.com/FourCoreLabs/firedrill/pkg/behaviours/ransom_wallpaper"
"github.com/FourCoreLabs/firedrill/pkg/sergeant"
"go.uber.org/zap"
Expand All @@ -18,7 +18,7 @@ func main() {
logger, _ := zap.NewProduction()

behaviours := []sergeant.Runnable{
ransom_encrypt.NewRansomEncrypt(),
ransom_sysencrypt.NewRansomEncrypt(),
ransom_note.NewRansomNote(),
ransom_wallpaper.NewRansomWallpaper(),
}
Expand Down
10 changes: 0 additions & 10 deletions pkg/behaviours/ransom_encrypt/testfiles/fileA.txt

This file was deleted.

Binary file removed pkg/behaviours/ransom_encrypt/testfiles/fileB.png
Binary file not shown.
Binary file removed pkg/behaviours/ransom_encrypt/testfiles/fileC.xlsx
Binary file not shown.
Binary file removed pkg/behaviours/ransom_encrypt/testfiles/fileD.pdf
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
package ransom_encrypt
package ransom_mockencrypt

import (
"context"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"embed"
"errors"
"fmt"
"io"
"os"
"path"
"path/filepath"
"time"

"github.com/FourCoreLabs/firedrill/pkg/sergeant"
"github.com/FourCoreLabs/firedrill/pkg/utils/aesutils"
"github.com/FourCoreLabs/firedrill/pkg/utils/userinfo"
"go.uber.org/zap"
)

const (
ID = "ransom_encrypt"
Name = "Ransomware Encryption"
ID = "ransom_mockencrypt"
Name = "Ransomware Mock Encryption"

ext = ".drill"
ransomDirName = "fireDrillRansomware"
embedFilesPath = "testfiles"
)

// files are test file to be dropped on the file system and encrypted as part of ransomware encryption simulation.
//
//go:embed testfiles
var files embed.FS

Expand Down Expand Up @@ -61,7 +58,7 @@ func (e *RansomEncrypt) Name() string {

func (e *RansomEncrypt) Run(ctx context.Context, logger *zap.Logger) error {
desktopPath := userinfo.UserDesktop()
logger.Sugar().Infof("User desktop path for ransomare encryption: %s", desktopPath)
logger.Sugar().Infof("User desktop path for ransomware encryption: %s", desktopPath)

testFiles, _ := files.ReadDir(embedFilesPath)

Expand Down Expand Up @@ -93,7 +90,7 @@ func (e *RansomEncrypt) Run(ctx context.Context, logger *zap.Logger) error {
}
logger.Sugar().Infof("Generated test folder for ransomware encryption: %s", targetDirPath)

aesKey := aesEncryptionKey()
aesKey := aesutils.AESEncryptionKey()

files, err := os.ReadDir(targetDirPath)
if err != nil {
Expand All @@ -112,7 +109,7 @@ func (e *RansomEncrypt) Run(ctx context.Context, logger *zap.Logger) error {
return err // everything should work.
}

encData, err := aesEncryptData(fileData, aesKey)
encData, err := aesutils.AESEncryptData(fileData, aesKey)
if err != nil {
return err // everything should work.
}
Expand All @@ -131,44 +128,13 @@ func (e *RansomEncrypt) Run(ctx context.Context, logger *zap.Logger) error {
logger.Sugar().Infof("Encrypted %d/%d files.", i+1, totalFiles)
}

logger.Sugar().Info("Waiting for 10 seconds.")
logger.Sugar().Info("Waiting for 03 seconds.")

select {
case <-time.After(10 * time.Second):
case <-time.After(3 * time.Second):
case <-ctx.Done():
return errors.New("context cancelled")
}

return nil
}

// aesEncryptData encrypts data using 256-bit AES-GCM. Output: nonce+cipherdata+tag
func aesEncryptData(data []byte, key []byte) (encryptedtext []byte, err error) {
cipherblock, err := aes.NewCipher(key)
if err != nil {
return nil, err
}

gcmpack, err := cipher.NewGCM(cipherblock)
if err != nil {
return nil, err
}

nonce := make([]byte, gcmpack.NonceSize())
_, err = io.ReadFull(rand.Reader, nonce)
if err != nil {
return nil, err
}

return gcmpack.Seal(nonce, nonce, data, nil), nil
}

// aesEncryptionKey returns random AES Encrpytion Key
func aesEncryptionKey() []byte {
ekey := make([]byte, 32)
_, err := io.ReadFull(rand.Reader, ekey)
if err != nil {
panic(fmt.Sprintf("Failed to seed key: %v", err))
}
return ekey
}
1 change: 1 addition & 0 deletions pkg/behaviours/ransom_mockencrypt/testfiles/fileA.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a FourCore Test TXT File
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions pkg/behaviours/ransom_mockencrypt/testfiles/fileG.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a FourCore Test TXT File
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit 7d3ac03

Please sign in to comment.