feat(d-eyes): init

This commit is contained in:
zitn
2023-11-06 16:31:16 +08:00
parent 804617ded3
commit 270bb18b98
117 changed files with 19222 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
package info
import (
"bufio"
"encoding/csv"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/gookit/color"
)
func CheckExchangeServerOWASSRF(path string) {
if path == "" {
path = "C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Logging\\CmdletInfra\\Powershell-Proxy\\Http"
}
_, err := os.Stat(path)
if os.IsNotExist(err) {
fmt.Println("Didn't find the directory '", path, "' on this host!")
return
}
var logs []string
var paths []string
var users []string
var successDocs []string
var failDocs []string
color.Info.Println("Checking the Rps_Http logs in '", path, "'...")
files, err := filepath.Glob(path + "/*Rps_Http_20*")
if err != nil {
fmt.Println(err)
return
}
if len(files) == 0 {
fmt.Println("Not found Rps_Http logs in the directory '", path, "'")
return
}
for _, file := range files {
csvFile, err := os.Open(file)
if err != nil {
fmt.Println(err)
return
}
defer csvFile.Close()
reader := csv.NewReader(bufio.NewReader(csvFile))
reader.Comma = ','
reader.FieldsPerRecord = -1
csvData, err := reader.ReadAll()
if err != nil {
fmt.Println(err)
return
}
for _, record := range csvData {
if len(record) < 30 {
continue
}
ua := record[29]
if ua != "ClientInfo" && ua != "Microsoft WinRM Client" && ua != "Exchange BackEnd Probes" && strings.ContainsAny(ua, "a-zA-Z0-9") {
time := record[0]
src := strings.Replace(record[15], " ", " -> ", -1)
server := record[16]
frontend := record[17]
status := record[18]
user := record[12]
if status != "200" {
failDocs = append(failDocs, time+" [FAILURE: "+status+" ] Path: "+src+" -> "+frontend+" -> "+server+" as User: [ "+user+" ]")
} else {
successDocs = append(successDocs, time+" [SUCCESS: "+status+" ] Path: "+src+" -> "+frontend+" -> "+server+" as User: [ "+user+" ]")
}
paths = append(paths, src+" -> "+frontend+" -> "+server)
if strings.ContainsAny(user, "a-zA-Z0-9") {
users = append(users, user)
}
logs = append(logs, file)
}
}
}
paths = removeDuplicates(paths)
users = removeDuplicates(users)
logs = removeDuplicates(logs)
if len(successDocs) > 0 || len(failDocs) > 0 {
fmt.Println()
color.Error.Println("Something Suspicious Found !!!")
fmt.Println()
if len(successDocs) > 0 {
color.Warn.Println(len(successDocs), "instances of possible successful proxied exploitation found using UA indicator:")
for _, s := range successDocs {
fmt.Println(" ", s)
}
}
if len(failDocs) > 0 {
color.Warn.Println(len(failDocs), "instances of failed proxied exploitation attempts found using UA indicator")
for _, f := range failDocs {
fmt.Println(" ", f)
}
}
color.Warn.Println("Network paths used for exploitation attempts:")
for _, p := range paths {
fmt.Println(" ", p)
}
color.Warn.Println("Compromised users:")
for _, u := range users {
fmt.Println(" ", u)
}
color.Warn.Println("The above information is obtained from the following files:")
for _, l := range logs {
fmt.Println(" ", l)
}
} else {
fmt.Println()
color.Info.Println("Nothing Suspicious Found !")
}
}
func removeDuplicates(elements []string) []string {
encountered := map[string]bool{}
result := []string{}
for v := range elements {
if encountered[elements[v]] == true {
} else {
encountered[elements[v]] = true
result = append(result, elements[v])
}
}
return result
}

View File

@@ -0,0 +1,59 @@
package info
import (
"os"
"github.com/olekukonko/tablewriter"
autoruns "d-eyes/basicinfo/utils"
)
type AutoRuns struct {
AutoRuns []*autoruns.Autorun
}
func GetAutoruns() *AutoRuns {
ret := autoruns.Autoruns()
return &AutoRuns{AutoRuns: ret}
}
func DisplayAutoruns(autoRuns *AutoRuns) {
data := make([][]string, 0)
for _, autorun := range autoRuns.AutoRuns {
autorunData := make([]string, 0)
path := StringNewLine(autorun.ImagePath, 25)
autorunData = append(autorunData, autorun.Type, autorun.ImageName, autorun.Arguments, path)
data = append(data, autorunData)
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Type", "ImageName", "Arguments", "Path"})
table.SetHeaderAlignment(tablewriter.ALIGN_CENTER)
table.SetBorder(true)
table.SetRowLine(true)
table.SetAutoMergeCells(true)
table.AppendBulk(data)
table.SetCaption(true, "Autoruns list")
table.Render()
}
func StringNewLine(str string, ln uint8) string {
var sub_str string
res_str := ""
for {
if len(str) < int(ln) {
res_str += str
break
}
sub_str = str[0:ln]
str = str[ln:]
res_str += sub_str + "\n"
}
return res_str
}
func CallDisplayAutoruns() {
autoruns := GetAutoruns()
DisplayAutoruns(autoruns)
}

View File

@@ -0,0 +1,59 @@
package info
import (
"os"
"github.com/olekukonko/tablewriter"
autoruns "d-eyes/basicinfo/utils"
)
type AutoRuns struct {
AutoRuns []*autoruns.Autorun
}
func GetAutoruns() *AutoRuns {
ret := autoruns.Autoruns()
return &AutoRuns{AutoRuns: ret}
}
func DisplayAutoruns(autoRuns *AutoRuns) {
data := make([][]string, 0)
for _, autorun := range autoRuns.AutoRuns {
autorunData := make([]string, 0)
path := StringNewLine(autorun.LaunchString, 25)
autorunData = append(autorunData, autorun.Type, autorun.ImageName, path)
data = append(data, autorunData)
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Type", "ImageName", "LaunchCommand"})
table.SetHeaderAlignment(tablewriter.ALIGN_CENTER)
table.SetBorder(true)
table.SetRowLine(true)
table.SetAutoMergeCells(true)
table.AppendBulk(data)
table.SetCaption(true, "Autoruns list")
table.Render()
}
func StringNewLine(str string, ln uint8) string {
var subStr string
res_str := ""
for {
if len(str) < int(ln) {
res_str += str
break
}
subStr = str[0:ln]
str = str[ln:]
res_str += subStr + "\n"
}
return res_str
}
func CallDisplayAutoruns() {
ar := GetAutoruns()
DisplayAutoruns(ar)
}

27
basicinfo/info/base.go Normal file
View File

@@ -0,0 +1,27 @@
package info
import (
"fmt"
"os/user"
"github.com/gookit/color"
"github.com/shirou/gopsutil/v3/host"
)
func DisplayBaseInfo() {
infoStat, _ := host.Info()
platform := infoStat.Platform + " " + infoStat.PlatformVersion
OsKernel := infoStat.KernelArch + " " + infoStat.KernelVersion
CurrentUser, _ := user.Current()
color.Greenp("* ")
fmt.Println("OS VERSION: ", platform)
color.Greenp("* ")
fmt.Println("KERNEL VERSION: ", OsKernel)
color.Greenp("* ")
fmt.Println("CURRENT USER: ", CurrentUser.Username)
}

View File

@@ -0,0 +1,111 @@
//go:build windows
package info
import (
"encoding/xml"
"fmt"
"io/ioutil"
"log"
"runtime"
"strings"
"github.com/gookit/color"
"github.com/axgle/mahonia"
)
type task struct {
RegistrationInfo struct {
Description string
}
Actions struct {
Exec struct {
Command string
Arguments string
}
}
Triggers struct {
CalendarTrigger struct {
StartBoundary string
}
}
Principals struct {
Principal struct {
UserId string
}
}
}
type CronTab struct {
Name string `json:"name,omitempty"`
Command string `json:"command,omitempty"`
Arg string `json:"arg,omitempty"`
User string `json:"user,omitempty"`
Rule string `json:"rule,omitempty"`
Description string `json:"description,omitempty"`
}
func DisplayPlanTask() {
crontab := GetCronTab()
DisplayCronTab(crontab)
}
// GetCronTab 获取计划任务
func GetCronTab() (resultData []CronTab) {
var taskPath string
if runtime.GOARCH == "386" {
taskPath = `C:\Windows\SysNative\Tasks\`
} else {
taskPath = `C:\Windows\System32\Tasks\`
}
dir, err := ioutil.ReadDir(taskPath)
if err != nil {
return resultData
}
for _, f := range dir {
if f.IsDir() {
continue
}
dat, err := ioutil.ReadFile(taskPath + f.Name())
if err != nil {
continue
}
v := task{}
dec := mahonia.NewDecoder("utf-16")
data := dec.ConvertString(string(dat))
err = xml.Unmarshal([]byte(strings.Replace(data, "UTF-16", "UTF-8", 1)), &v)
if err != nil {
log.Println("Windows crontab info xml Unmarshal error: ", err.Error())
continue
}
m := CronTab{}
m.Name = f.Name()
m.Command = v.Actions.Exec.Command
m.Arg = v.Actions.Exec.Arguments
m.User = v.Principals.Principal.UserId
m.Rule = v.Triggers.CalendarTrigger.StartBoundary
m.Description = v.RegistrationInfo.Description
resultData = append(resultData, m)
}
return resultData
}
func DisplayCronTab(cronTab []CronTab) {
color.Greenp("==============================================================================================\n")
for _, item := range cronTab {
color.Greenp("* ")
fmt.Println("NAME: ", item.Name)
color.Greenp("* ")
fmt.Println("COMMAND: ", item.Command)
color.Greenp("* ")
fmt.Println("ARG: ", item.Arg)
color.Greenp("* ")
fmt.Println("USER: ", item.User)
color.Greenp("* ")
fmt.Println("RULE: ", item.Rule)
color.Greenp("* ")
fmt.Println("DESCRIPTION: ", item.Description)
color.Greenp("==============================================================================================\n")
}
}

View File

@@ -0,0 +1,81 @@
package info
import (
"fmt"
"io/ioutil"
"strings"
"github.com/gookit/color"
)
var resultData []string
func DisplayPlanTask() {
Crontab_file()
Crontab_dir()
DisplayCronTab(resultData)
}
// single crontab file
func Crontab_file() {
dat, err := ioutil.ReadFile("/etc/crontab")
if err != nil {
return
}
cronList := strings.Split(string(dat), "\n")
for _, info := range cronList {
if strings.HasPrefix(info, "#") || strings.Count(info, " ") < 6 {
continue
}
resultData = append(resultData, info)
}
}
// dir crontab files
func Crontab_dir() {
dir_list := []string{"/var/spool/cron/", "/var/spool/cron/crontabs/"}
for _, dirTmp := range dir_list {
dir, err := ioutil.ReadDir(dirTmp)
if err != nil {
continue
}
for _, f := range dir {
if f.IsDir() {
continue
}
dat, err := ioutil.ReadFile(dirTmp + f.Name())
if err != nil {
continue
}
cronList := strings.Split(string(dat), "\n")
for _, info := range cronList {
if strings.HasPrefix(info, "#") || strings.Count(info, " ") < 5 {
continue
}
info = info + " (user '" + f.Name() + "' created this task.)"
resultData = append(resultData, info)
}
}
}
}
func DisplayCronTab(cronTab []string) {
color.Greenp("==============================================================================================\n")
if len(cronTab) == 0 {
fmt.Println("There is no crontab task in this host.")
return
}
taskSum := 0
for _, item := range cronTab {
taskSum++
color.Greenp("* task", taskSum)
fmt.Println()
fmt.Println(item)
color.Greenp("==============================================================================================\n")
}
}
func GetCronTab() []string {
Crontab_file()
Crontab_dir()
return resultData
}

View File

@@ -0,0 +1,109 @@
package info
import (
"encoding/csv"
"fmt"
"os"
"strings"
"github.com/olekukonko/tablewriter"
"github.com/shirou/gopsutil/v3/process"
"d-eyes/basicinfo/utils"
)
// remote connection ip
func DisplayNetStat() {
networkData := make([][]string, 0)
var remoteIp []string
ps, err := process.Processes()
if err != nil {
fmt.Println("Error:", err)
return
}
for _, p := range ps {
pid := os.Getpid()
if pid == int(p.Pid) || p.Pid == 0 {
continue
}
connList := make([]string, 0)
connection := make([]string, 0)
_pc, _ := p.Connections()
for _, conn := range _pc {
if conn.Family == 1 {
continue
}
c := fmt.Sprintf(
"%v:%v<->%v:%v(%v)\n",
conn.Laddr.IP, conn.Laddr.Port, conn.Raddr.IP, conn.Raddr.Port, conn.Status,
)
remoteIp = append(remoteIp, conn.Raddr.IP)
connection = append(connection, c)
}
_pUname, _ := p.Username()
if len(connection) > 0 && _pUname != "" {
network := strings.Join(connection, "")
_exe, _ := p.Exe()
path := utils.StringNewLine(_exe, 25)
connList = append(connList, fmt.Sprintf("%v", p.Pid), fmt.Sprintf("%v", p.Username), network, path)
networkData = append(networkData, connList)
}
}
//output the information of current netstat
tableConn := tablewriter.NewWriter(os.Stdout)
tableConn.SetHeader([]string{"pid", "user", "local/remote(TCP Status)", "program name"})
tableConn.SetBorder(true)
tableConn.SetRowLine(true)
tableConn.AppendBulk(networkData)
tableConn.Render()
remoteIpNew := RemoveRepeatedElement(remoteIp)
if len(remoteIpNew) > 0 {
f, err := os.Create("RemoteConnectionIP.csv")
if err != nil {
panic(err)
}
_, err = f.WriteString("\xEF\xBB\xBF")
if err != nil {
panic(err)
}
writer := csv.NewWriter(f)
length := len(remoteIpNew)
for i := 0; i < length; i++ {
err := writer.Write([]string{remoteIpNew[i]})
if err != nil {
panic(err)
}
}
writer.Flush()
f.Close()
fmt.Println("The IP of the local remote connection has been exported to 'RemoteConnectionIP.csv'.")
} else {
fmt.Println("\nThere is no remote connection IP on this host.")
}
}
func RemoveRepeatedElement(arr []string) (newArr []string) {
newArr = make([]string, 0)
for i := 0; i < len(arr); i++ {
if arr[i] == "127.0.0.1" || arr[i] == "0.0.0.0" || arr[i] == "::" || arr[i] == "::1" || arr[i] == "" {
continue
}
repeat := false
for j := i + 1; j < len(arr); j++ {
if arr[i] == arr[j] {
repeat = true
break
}
}
if !repeat {
newArr = append(newArr, arr[i])
}
}
return
}

View File

@@ -0,0 +1,103 @@
package info
import (
"encoding/csv"
"fmt"
"os"
"strings"
"github.com/olekukonko/tablewriter"
"github.com/shirou/gopsutil/v3/process"
"d-eyes/basicinfo/utils"
)
// remote connection ip
func DisplayNetStat(srcPath string) {
networkData := make([][]string, 0)
var remoteIp []string
ps, err := process.Processes()
if err != nil {
fmt.Println("Error:", err)
return
}
for _, p := range ps {
pid := os.Getpid()
if pid == int(p.Pid) || p.Pid == 0 {
continue
}
connList := make([]string, 0)
connection := make([]string, 0)
_pc, _ := p.Connections()
for _, conn := range _pc {
if conn.Family == 1 {
continue
}
c := fmt.Sprintf(
"%v:%v<->%v:%v(%v)\n",
conn.Laddr.IP, conn.Laddr.Port, conn.Raddr.IP, conn.Raddr.Port, conn.Status,
)
remoteIp = append(remoteIp, conn.Raddr.IP)
connection = append(connection, c)
}
_pUname, _ := p.Username()
if len(connection) > 0 && _pUname != "" {
network := strings.Join(connection, "")
_exe, _ := p.Exe()
path := utils.StringNewLine(_exe, 25)
username, _ := p.Username()
connList = append(connList, fmt.Sprintf("%v", p.Pid), fmt.Sprintf("%v", username), network, path)
networkData = append(networkData, connList)
}
}
tableConn := tablewriter.NewWriter(os.Stdout)
tableConn.SetHeader([]string{"pid", "user", "local/remote(TCP Status)", "program name"})
tableConn.SetBorder(true)
tableConn.SetRowLine(true)
tableConn.AppendBulk(networkData)
tableConn.Render()
remoteIpNew := RemoveRepeatedElement(remoteIp)
if len(remoteIpNew) > 0 {
f, err := os.Create(srcPath + "RemoteConnectionIP.csv")
if err != nil {
panic(err)
}
f.WriteString("\xEF\xBB\xBF")
writer := csv.NewWriter(f)
length := len(remoteIpNew)
for i := 0; i < length; i++ {
writer.Write([]string{remoteIpNew[i]})
}
writer.Flush()
f.Close()
fmt.Println("The IP of the local remote connection has been exported to 'RemoteConnectionIP.csv'.")
} else {
fmt.Println("\nThere is no remote connection IP on this host.")
}
}
func RemoveRepeatedElement(arr []string) (newArr []string) {
newArr = make([]string, 0)
for i := 0; i < len(arr); i++ {
if arr[i] == "127.0.0.1" || arr[i] == "0.0.0.0" || arr[i] == "::" || arr[i] == "::1" || arr[i] == "" {
continue
}
repeat := false
for j := i + 1; j < len(arr); j++ {
if arr[i] == arr[j] {
repeat = true
break
}
}
if !repeat {
newArr = append(newArr, arr[i])
}
}
return
}

View File

@@ -0,0 +1,70 @@
package info
import (
"fmt"
"os"
"os/exec"
"os/user"
"strconv"
"github.com/shirou/gopsutil/v3/host"
)
func SaveSummaryBaseInfo() {
f, err := os.Create("SummaryBaseInfo")
if err != nil {
fmt.Errorf(err.Error())
}
baseInfo := GetBaseInfo()
_, err = f.WriteString("HostInfo: \n" + baseInfo)
users := GetLinuxUser()
_, err = f.WriteString("AllUsers: \n")
for _, user := range users {
_, err = f.WriteString(" * " + user + "\n")
}
crontab := GetCronTab()
crontabString := ""
crontabString += "Os Crontab: \n==============================================================================================\n"
taskSum := 0
for _, item := range crontab {
taskSum++
crontabString += "* task " + strconv.Itoa(taskSum) + "\n" +
"" + item + "\n" +
"==============================================================================================\n"
}
_, err = f.WriteString(crontabString)
_, err = f.WriteString("InterfaceInfo: \n")
if err == nil {
path, _ := os.Getwd()
fmt.Println("Summary file to ", path+"/SummaryBaseInfo")
fmt.Println("Summary Base Info file created!")
} else {
fmt.Errorf(err.Error())
}
f.Close()
c := exec.Command("/bin/bash", "-c", "ifconfig -a>>SummaryBaseInfo")
if err := c.Run(); err != nil {
fmt.Println("Error: ", err)
}
}
func GetBaseInfo() string {
infoStat, _ := host.Info()
platform := infoStat.Platform + " " + infoStat.PlatformVersion
OsKernel := infoStat.KernelArch + " " + infoStat.KernelVersion
user, _ := user.Current()
baseInfo := ""
baseInfo += " * OS VERSION: " + platform + "\n" +
" * KERNEL VERSION: " + OsKernel + "\n" +
" * CURRENT USER: " + user.Username + "\n"
return baseInfo
}

View File

@@ -0,0 +1,74 @@
package info
import (
"fmt"
"os"
"os/exec"
"os/user"
"github.com/shirou/gopsutil/v3/host"
)
func SaveSummaryBaseInfo() {
f, err := os.Create("SummaryBaseInfo.txt")
if err != nil {
fmt.Println(err)
return
}
baseInfo := GetBaseInfo()
_, err = f.WriteString("HostInfo: \n" + baseInfo)
users := GetWindowsUser()
_, err = f.WriteString("AllUsers: \n")
for _, userInfo := range users {
_, err = f.WriteString(" * " + userInfo + "\n")
}
crontab := GetCronTab()
crontabString := ""
crontabString += "Os Crontab: \n==============================================================================================\n"
for _, item := range crontab {
crontabString += "*NAME: " + item.Name + "\n" +
"*COMMAND: " + item.Command + "\n" +
"*ARG: " + item.Arg + "\n" +
"*USER: " + item.User + "\n" +
"*RULE: " + item.Rule + "\n" +
"*DESCRIPTION: " + item.Description + "\n" +
"==============================================================================================\n"
}
_, err = f.WriteString(crontabString)
_, err = f.WriteString("InterfaceInfo: ")
if err == nil {
path, _ := os.Getwd()
fmt.Println("Summary file to ", path+"\\SummaryBaseInfo.txt")
fmt.Println("Summary Base Info file created!")
} else {
fmt.Println(err)
return
}
f.Close()
c := exec.Command("cmd", "/C", "ipconfig /all>>SummaryBaseInfo.txt")
if err := c.Run(); err != nil {
fmt.Println("Error: ", err)
}
}
func GetBaseInfo() string {
infoStat, _ := host.Info()
platform := infoStat.Platform + " " + infoStat.PlatformVersion
OsKernel := infoStat.KernelArch + " " + infoStat.KernelVersion
userInfo, _ := user.Current()
baseInfo := ""
baseInfo += " * OS VERSION: " + platform + "\n" +
" * KERNEL VERSION: " + OsKernel + "\n" +
" * CURRENT USER: " + userInfo.Username + "\n"
return baseInfo
}

77
basicinfo/info/top.go Normal file
View File

@@ -0,0 +1,77 @@
package info
import (
"fmt"
"os"
"sort"
"time"
"github.com/gookit/color"
"github.com/shirou/gopsutil/v3/process"
)
type (
Process struct {
Process []*process.Process
}
)
func Top() {
ps, err := process.Processes()
if err != nil {
fmt.Println(err)
return
}
sort.Slice(
ps, func(i, j int) bool {
pic, _ := ps[i].CPUPercent()
pjc, _ := ps[j].CPUPercent()
return pic > pjc
},
)
pss := Process{Process: ps}
CPUSum := 0
color.Greenp("==============================================================================================\n")
for _, ps := range pss.Process {
pid := os.Getpid()
if pid == int(ps.Pid) {
continue
}
CPUSum++
color.Greenp("* CPU Top ", CPUSum)
fmt.Println()
_pct, _ := ps.CreateTime()
_pPath, _ := ps.Exe()
_pCpuP, _ := ps.CPUPercent()
startDate := time.Unix(_pct, 0).Format("2006-01-02 15:04:05")
username, _ := ps.Username()
MemPer, _ := ps.MemoryPercent()
fmt.Printf(
"[User]:%s | [Pid]:%d | [Path]:%s | [CPU]:%.5f | [Memory]:%.5f | [Createdtime]:%v \n",
username, ps.Pid, _pPath, _pCpuP, MemPer, startDate,
)
//network
_ps, _ := ps.Connections()
if len(_ps) == 0 {
fmt.Println("[netstat]: null")
} else {
netSum := 0
for _, conn := range _ps {
if conn.Family == 1 {
continue
}
netSum++
fmt.Printf(
"[netstat %d]: %v:%v<->%v:%v(%v)\n",
netSum, conn.Laddr.IP, conn.Laddr.Port, conn.Raddr.IP, conn.Raddr.Port, conn.Status,
)
}
}
color.Greenp("==============================================================================================\n")
if CPUSum == 15 {
break
}
}
}

View File

@@ -0,0 +1,42 @@
package info
import (
"fmt"
"github.com/gookit/color"
"io/ioutil"
"strings"
)
func DisplayAllUsers() {
users := GetLinuxUser()
for _, user := range users {
color.Greenp("* ")
fmt.Println(user)
}
}
// GetUser
func GetLinuxUser() (resultData []string) {
dat, err := ioutil.ReadFile("/etc/passwd")
if err != nil {
return resultData
}
userList := strings.Split(string(dat), "\n")
if len(userList) < 2 {
return
}
for _, info := range userList[0 : len(userList)-1] {
if strings.Contains(info, "/nologin") {
continue
}
if strings.Contains(info, "/bin/false") {
continue
}
s := strings.SplitN(info, ":", 2)
resultData = append(resultData, s[0])
}
return resultData
}

View File

@@ -0,0 +1,38 @@
package info
import (
"fmt"
"github.com/gookit/color"
"github.com/yusufpapurcu/wmi"
)
func DisplayAllUsers() {
users := GetWindowsUser()
for _, user := range users {
color.Greenp("* ")
fmt.Println(user)
}
}
type userAccount struct {
Name string // 用户名
Description string // 用户描述
Status string // 用户状态
}
// GetUser 获取系统用户列表
func GetWindowsUser() (resultData []string) {
var dst []userAccount
err := wmi.Query("SELECT * FROM Win32_UserAccount where LocalAccount=TRUE", &dst)
if err != nil {
return resultData
}
for _, v := range dst {
resultData = append(resultData, v.Name)
}
return resultData
}

View File

@@ -0,0 +1,18 @@
package utils
type Autorun struct {
Type string `json:"type"`
Location string `json:"location"`
ImagePath string `json:"image_path"`
ImageName string `json:"image_name"`
Arguments string `json:"arguments"`
MD5 string `json:"md5"`
SHA1 string `json:"sha1"`
SHA256 string `json:"sha256"`
Entry string `json:"entry"`
LaunchString string `json:"launch_string"`
}
func Autoruns() []*Autorun {
return getAutoruns()
}

View File

@@ -0,0 +1,111 @@
package utils
import (
"bufio"
"io/ioutil"
"os"
"path"
"path/filepath"
"regexp"
"strings"
files "github.com/botherder/go-files"
)
// This function just invokes all the platform-dependant functions.
func getAutoruns() (records []*Autorun) {
records = append(records, linuxGetSystemd()...)
return
}
var regexSection = regexp.MustCompile("\\[.*\\]")
func parseShellInvocation(shellLine string, autorun *Autorun) {
autorun.LaunchString = strings.SplitAfter(shellLine, "=")[1]
// We need to make sure to drop !! from paths
autorun.ImagePath = strings.Replace(strings.Split(autorun.LaunchString, " ")[0], "!!", "", -1)
autorun.ImageName = path.Base(autorun.ImagePath)
args := strings.Split(autorun.LaunchString, " ")
if len(args) > 1 {
autorun.Arguments = strings.Join(args[1:], " ")
}
}
func stringToAutorun(fileName string) (*Autorun, error) {
reader, err := os.Open(fileName)
if err != nil {
return nil, err
}
defer reader.Close()
autorun := Autorun{
Location: fileName,
//Type: "systemd",
Type: "Autorun services",
}
inSection := ""
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
line := scanner.Text()
if regexSection.MatchString(line) {
inSection = line
}
switch inSection {
case "[Service]":
if strings.HasPrefix(line, "ExecStart=") {
parseShellInvocation(line, &autorun)
}
case "[D-BUS Service]":
if strings.HasPrefix(line, "Exec=") {
parseShellInvocation(line, &autorun)
}
}
}
autorun.MD5, _ = files.HashFile(autorun.ImagePath, "md5")
autorun.SHA1, _ = files.HashFile(autorun.ImagePath, "sha1")
autorun.SHA256, _ = files.HashFile(autorun.ImagePath, "sha256")
return &autorun, nil
}
func linuxGetSystemd() (records []*Autorun) {
folders := []string{
"/etc/systemd/system/",
"/usr/share/dbus-1/system-services/",
}
for _, folder := range folders {
// Check if the folders exists.
if _, err := os.Stat(folder); os.IsNotExist(err) {
continue
}
// Get list of files in folder.
filesList, err := ioutil.ReadDir(folder)
if err != nil {
continue
}
// Loop through all files in folder.
for _, fileEntry := range filesList {
// Skip all files that don't end with .service.
if !(strings.HasSuffix(fileEntry.Name(), ".service")) {
continue
}
filePath := filepath.Join(folder, fileEntry.Name())
record, err := stringToAutorun(filePath)
if err != nil {
continue
}
records = append(records, record)
}
}
return
}

View File

@@ -0,0 +1,276 @@
package utils
import (
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strings"
files "github.com/botherder/go-files"
"github.com/mattn/go-shellwords"
"golang.org/x/sys/windows/registry"
)
// Just return a string value for a given registry root Key.
func registryToString(reg registry.Key) string {
if reg == registry.LOCAL_MACHINE {
return "LOCAL_MACHINE"
} else if reg == registry.CURRENT_USER {
return "CURRENT_USER"
} else {
return ""
}
}
func parsePath(entryValue string) ([]string, error) {
if entryValue == "" {
return nil, errors.New("empty path")
}
if strings.HasPrefix(entryValue, `\??\`) {
entryValue = entryValue[4:]
}
// do some typical replacements
if len(entryValue) >= 11 && strings.ToLower(entryValue[:11]) == "\\systemroot" {
entryValue = strings.Replace(entryValue, entryValue[:11], os.Getenv("SystemRoot"), -1)
}
if len(entryValue) >= 8 && strings.ToLower(entryValue[:8]) == "system32" {
entryValue = strings.Replace(entryValue, entryValue[:8], fmt.Sprintf("%s\\System32", os.Getenv("SystemRoot")), -1)
}
// replace environment variables
entryValue, err := registry.ExpandString(entryValue)
if err != nil {
return []string{}, err
}
// We clean the path for proper backslashes.
entryValue = strings.Replace(entryValue, "\\", "\\\\", -1)
// Check if the whole entry is an executable and clean the file path.
if v, err := cleanPath(entryValue); err == nil {
return []string{v}, nil
}
// Otherwise we can split the entry for executable and arguments
parser := shellwords.NewParser()
args, err := parser.Parse(entryValue)
if err != nil {
return []string{}, err
}
// If the split worked, find the correct path to the executable and clean
// the file path.
if len(args) > 0 {
if v, err := cleanPath(args[0]); err == nil {
args[0] = v
}
}
return args, nil
}
func stringToAutorun(entryType string, entryLocation string, entryValue string, toParse bool, entry string) *Autorun {
var imagePath = entryValue
var launchString = entryValue
var argsString = ""
// TODO: This optional parsing is quite spaghetti. To change.
if toParse == true {
args, err := parsePath(entryValue)
if err == nil {
if len(args) > 0 {
imagePath = args[0]
if len(args) > 1 {
argsString = strings.Join(args[1:], " ")
}
}
}
}
md5, _ := files.HashFile(imagePath, "md5")
sha1, _ := files.HashFile(imagePath, "sha1")
sha256, _ := files.HashFile(imagePath, "sha256")
newAutorun := Autorun{
Type: entryType,
Location: entryLocation,
ImagePath: imagePath,
ImageName: filepath.Base(imagePath),
Arguments: argsString,
MD5: md5,
SHA1: sha1,
SHA256: sha256,
Entry: entry,
LaunchString: launchString,
}
return &newAutorun
}
// This function invokes all the platform-dependant functions.
func getAutoruns() (records []*Autorun) {
records = append(records, windowsGetCurrentVersionRun()...)
//records = append(records, windowsGetServices()...)
records = append(records, windowsGetStartupFiles()...)
// records = append(records, windowsGetTasks()...)
return
}
// This function enumerates items registered through CurrentVersion\Run.
func windowsGetCurrentVersionRun() (records []*Autorun) {
regs := []registry.Key{
registry.LOCAL_MACHINE,
registry.CURRENT_USER,
}
keyNames := []string{
"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
"Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
"Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run",
"Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
}
// We loop through HKLM and HKCU.
for _, reg := range regs {
// We loop through the keys we're interested in.
for _, keyName := range keyNames {
// Open registry key.
key, err := registry.OpenKey(reg, keyName, registry.READ)
if err != nil {
continue
}
// Enumerate value names.
names, err := key.ReadValueNames(0)
if err != nil {
key.Close()
continue
}
for _, name := range names {
// For each entry we get the string value.
value, _, err := key.GetStringValue(name)
if err != nil || value == "" {
continue
}
imageLocation := fmt.Sprintf("%s\\%s", registryToString(reg), keyName)
/*reTime,err:=key.Stat()
if err != nil {
fmt.Println(err)
continue
}
reTime.ModTime()*/
newAutorun := stringToAutorun("Autoruns", imageLocation, value, true, name)
// Add the new autorun to the records.
records = append(records, newAutorun)
}
key.Close()
}
}
return
}
// This function enumerates Windows Services.
func windowsGetServices() (records []*Autorun) {
var reg registry.Key = registry.LOCAL_MACHINE
var servicesKey string = "System\\CurrentControlSet\\Services"
// Open the registry key.
key, err := registry.OpenKey(reg, servicesKey, registry.READ)
if err != nil {
return
}
// Enumerate subkeys.
names, err := key.ReadSubKeyNames(0)
key.Close()
if err != nil {
return
}
for _, name := range names {
// We open each subkey.
subkeyPath := fmt.Sprintf("%s\\%s", servicesKey, name)
subkey, err := registry.OpenKey(reg, subkeyPath, registry.READ)
if err != nil {
continue
}
// Check if there is an ImagePath value.
imagePath, _, err := subkey.GetStringValue("ImagePath")
subkey.Close()
// If not, we skip to the next one.
if err != nil {
continue
}
imageLocation := fmt.Sprintf("%s\\%s", registryToString(reg), subkeyPath)
// We pass the value string to a function to return an Autorun.
newAutorun := stringToAutorun("service", imageLocation, imagePath, true, "")
// Add the new autorun to the records.
records = append(records, newAutorun)
}
return
}
// %ProgramData%\Microsoft\Windows\Start Menu\Programs\StartUp
// %AppData%\Microsoft\Windows\Start Menu\Programs\Startup
func windowsGetStartupFiles() (records []*Autorun) {
// We look for both global and user Startup folders.
folders := []string{
os.Getenv("ProgramData"),
os.Getenv("AppData"),
}
// The base path is the same for both.
var startupBasepath string = "Microsoft\\Windows\\Start Menu\\Programs\\StartUp"
for _, folder := range folders {
// Get the full path.
startupPath := filepath.Join(folder, startupBasepath)
// Get list of files in folder.
filesList, err := ioutil.ReadDir(startupPath)
if err != nil {
continue
}
// Loop through all files in folder.
for _, fileEntry := range filesList {
// We skip desktop.ini files.
if fileEntry.Name() == "desktop.ini" {
continue
}
filePath := filepath.Join(startupPath, fileEntry.Name())
// Instantiate new autorun record.
newAutorun := stringToAutorun("startup", startupPath, filePath, false, "")
// Add new record to list.
records = append(records, newAutorun)
}
}
return
}
// cleanPath uses lookPath to search for the correct path to
// the executable and cleans the file path.
func cleanPath(file string) (string, error) {
file, err := exec.LookPath(file)
if err != nil {
return "", err
}
return filepath.Clean(file), nil
}
// func windowsGetTasks() {
// }

View File

@@ -0,0 +1,16 @@
package utils
func StringNewLine(str string, ln uint8) string {
var sub_str string
res_str := ""
for {
if len(str) < int(ln) {
res_str += str
break
}
sub_str = str[0:ln]
str = str[ln:]
res_str += sub_str + "\n"
}
return res_str
}

View File

@@ -0,0 +1,110 @@
package check
import (
"github.com/gookit/color"
)
func Trigger() {
color.Greenp("==============================================================================================\n")
color.Greenp("空密码账户检测中··· \n")
if !Empty() {
color.Infoln("空密码账户检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("主机 Sudoer 检测中··· \n")
if !Sudo() {
color.Infoln("主机 Sudoer 检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("SSH Server wrapper 检测中··· \n")
if !SshWrapper() {
color.Infoln("SSH Server wrapper 检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("SSH用户免密证书登录检测中··· \n")
if !AuthorizedKeys() {
color.Infoln("SSH用户免密证书登录检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("SSH登录爆破检测中··· \n")
SSHLog()
color.Greenp("==============================================================================================\n")
color.Greenp("LD_PRELOAD 检测中··· \n")
if !LdPreloadCheck() {
color.Infoln("LD_PRELOAD 检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("LD_AOUT_PRELOAD 检测中··· \n")
if !LdAoutPreloadCheck() {
color.Infoln("LD_AOUT_PRELOAD 检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("LD_ELF_PRELOAD 检测中··· \n")
if !LdElfPreloadCheck() {
color.Infoln("LD_ELF_PRELOAD 检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("LD_LIBRARY_PATH 检测中··· \n")
if !LdLibraryPathCheck() {
color.Infoln("LD_LIBRARY_PATH 检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("ld.so.preload 检测中··· \n")
if !LdSoPreload() {
color.Infoln("ld.so.preload 检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("PROMPT_COMMAND 检测中··· \n")
if !PromptCommandCheck() {
color.Infoln("PROMPT_COMMAND 检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("自定义环境变量检测中··· \n")
if !ExportCheck() {
color.Infoln("自定义环境变量检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("inetd.conf 检测中··· \n")
if !IntedCheck() {
color.Infoln("inted.conf 检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("xinetd.conf 检测中··· \n")
if !XinetdCheck() {
color.Infoln("xinetd.conf 检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("系统启动服务检测中··· \n")
if !StartupCheck() {
color.Infoln("系统启动服务检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("主机计划任务检测中··· \n")
CrontabCheck()
color.Greenp("==============================================================================================\n")
color.Greenp("TCP Wrappers 检测中··· \n")
if !TcpWrappersCheck() {
color.Infoln("TCP Wrappers 检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("alias 检测中··· \n")
if !AliasConf() {
color.Infoln("alias 检测: [safe]")
}
color.Greenp("==============================================================================================\n")
color.Greenp("主机历史命令检测中··· \n")
HistoryCheck()
color.Greenp("==============================================================================================\n")
color.Greenp("主机最近成功登录信息: \n")
SuccessLoginDetail()
color.Greenp("==============================================================================================\n")
color.Greenp("主机Rootkit检测中··· \n")
RootkitCheck()
color.Greenp("==============================================================================================\n")
color.Greenp("Setuid检测中··· \n")
if !SetUid() {
color.Infoln("Setuid检测: [safe]")
}
color.Greenp("==============================================================================================\n")
}

View File

@@ -0,0 +1,89 @@
package check
import (
"fmt"
"io/ioutil"
"os"
"regexp"
"strings"
)
func AliasConf() bool {
suspicious := false
var files = []string{"/root/.bashrc", "/root/.bash_profile", "/etc/bashrc", "/etc/profile", "/etc/bash.bashrc"}
dirs, _ := ioutil.ReadDir("/home")
for _, dir := range dirs {
if !dir.IsDir() {
continue
}
suspicious2 := alias_file_analysis("/home/" + dir.Name() + "/.bashrc")
if suspicious2 {
suspicious = true
}
suspicious2 = alias_file_analysis("/home/" + dir.Name() + "/.bash_profile")
if suspicious2 {
suspicious = true
}
}
for _, file := range files {
suspicious2 := alias_file_analysis(file)
if suspicious2 {
suspicious = true
}
}
return suspicious
}
func alias_file_analysis(filepath string) bool {
suspicious := false
if !FileExist(filepath) {
return suspicious
}
syscmds := []string{
"ps", "strings", "netstat", "find", "echo", "iptables", "lastlog", "who", "ifconfig", "ssh", "top", "crontab", "adduser", "kill", "killall", "mv", "rm",
"userdel", "cp", "locate", "ls", "show", "ll",
}
dat, _ := ioutil.ReadFile(filepath)
flist := strings.Split(string(dat), "\n")
for _, line := range flist {
if len(line) > 5 && line[:5] == "alias" {
for _, syscmd := range syscmds {
reg := regexp.MustCompile("alias\\s+" + syscmd)
dataSlice := reg.FindAll([]byte(line), -1)
if dataSlice != nil {
fmt.Printf("配置文件: %s | 存在可疑的alias设置: %s \n", filepath, line)
suspicious = true
}
}
} else if len(line) > 6 && line[:6] == "source" {
fmt.Printf("配置文件: %s | 存在可疑的alias设置: %s \n", filepath, line)
suspicious = true
}
}
return suspicious
}
func FileExist(path string) bool {
_, err := os.Stat(path)
if err == nil {
return true
}
if os.IsNotExist(err) {
return false
}
return false
}

View File

@@ -0,0 +1,79 @@
package check
import (
"fmt"
"io/ioutil"
"strings"
"github.com/gookit/color"
"d-eyes/configcheck/common"
)
var suspiciousContents [][2]string
func CrontabCheck() {
CrontabFile()
CrontabDir()
if len(suspiciousContents) == 0 {
color.Infoln("主机计划任务检测: [safe]")
} else {
fmt.Println("主机计划任务存在可疑内容, 请确认:")
for _, detail := range suspiciousContents {
fmt.Printf("[*]File: %s Detail: %s\n", detail[0], detail[1])
}
}
}
// check single file
func CrontabFile() {
dat, err := ioutil.ReadFile("/etc/crontab")
if err != nil {
return
}
cronList := strings.Split(string(dat), "\n")
for _, info := range cronList {
if strings.HasPrefix(info, "#") {
continue
}
contents := common.CheckShell(info)
if contents == true {
suspiciousContents = append(suspiciousContents, [2]string{"/etc/crontab", info})
}
}
}
// check dir files
func CrontabDir() {
dirList := []string{
"/var/spool/cron/", "/var/spool/cron/crontabs/", "/etc/cron.d/", "/etc/cron.hourly/", "/etc/cron.daily/", "/etc/cron.weekly/", "/etc/cron.monthly/",
}
for _, dirTmp := range dirList {
dir, err := ioutil.ReadDir(dirTmp)
if err != nil {
continue
}
for _, f := range dir {
if f.IsDir() {
continue
}
dat, err := ioutil.ReadFile(dirTmp + f.Name())
if err != nil {
continue
}
cronList := strings.Split(string(dat), "\n")
for _, info := range cronList {
if strings.HasPrefix(info, "#") {
continue
}
contents := common.CheckShell(info)
if contents == true {
suspiciousContents = append(suspiciousContents, [2]string{dirTmp + f.Name(), info})
}
}
}
}
}

View File

@@ -0,0 +1,34 @@
package check
import (
"fmt"
"os/exec"
"strings"
)
func Empty() bool {
suspicious := false
if FileExist("/etc/shadow") {
c := exec.Command("bash", "-c", "awk -F: 'length($2)==0 {print $1}' /etc/shadow 2>/dev/null")
output, err := c.CombinedOutput()
if err != nil {
fmt.Println(err.Error())
}
shellProcess := strings.Split(string(output), "\n")
sum := 0
for _, user := range shellProcess {
if user == "" {
continue
}
sum++
if sum == 1 {
fmt.Println("")
}
fmt.Printf("存在空口令用户 %s\n", user)
suspicious = true
}
}
return suspicious
}

330
configcheck/check/env.go Normal file
View File

@@ -0,0 +1,330 @@
package check
import (
"bufio"
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"strings"
"d-eyes/configcheck/common"
)
func checkBackdoor(tag string) bool {
suspicious := false
files := []string{
"/root/.bashrc", "/root/.tcshrc", "/root/.bash_profile", "/root/.cshrc", "/root/.tcshrc",
"/etc/bashrc", "/etc/profile", "/etc/profile.d/", "/etc/csh.login", "/etc/csh.cshrc",
}
homeFiles := []string{"/.bashrc", "/.bash_profile", "/.tcshrc", "/.cshrc", "/.tcshrc"}
dirs, _ := ioutil.ReadDir("/home/")
for _, subDir := range dirs {
for _, homeFile := range homeFiles {
subFile := "/home/" + subDir.Name() + homeFile
info := checkTag(subFile, tag)
if info {
suspicious = true
}
}
}
for _, subFile := range files {
s, err := os.Stat(subFile)
if err != nil {
continue
}
if s.IsDir() {
filepath.Walk(
subFile, func(path string, info fs.FileInfo, err error) error {
if info.IsDir() {
return nil
} else {
inf := checkTag(path, tag)
if inf {
suspicious = true
}
}
return err
},
)
} else {
inf := checkTag(subFile, tag)
if inf {
suspicious = true
}
}
}
return suspicious
}
func checkTag(filename string, tag string) bool {
result := false
if !common.PathExists(filename) {
return false
}
_, err := ioutil.ReadDir(filename)
if err == nil {
return false
}
fr, _ := os.Open(filename)
defer fr.Close()
br := bufio.NewReader(fr)
for {
line, _, c := br.ReadLine()
if c == io.EOF {
break
}
if len(line) == 0 || line[0] == '#' {
continue
}
if strings.Contains(string(line), "export "+tag+"=") {
fmt.Println("[*]File:", filename, " Found:", string(line))
result = true
}
}
return result
}
func checkEnv() bool {
suspicious := false
files := []string{
"/root/.bashrc", "/root/.tcshrc", "/root/.bash_profile", "/root/.cshrc", "/root/.tcshrc",
"/etc/bashrc", "/etc/profile", "/etc/csh.login", "/etc/csh.cshrc",
}
homeFiles := []string{"/.bashrc", "/.bash_profile", "/.tcshrc", "/.cshrc", "/.tcshrc"}
dirs, _ := ioutil.ReadDir("/home/")
for _, subDir := range dirs {
for _, homeFile := range homeFiles {
subFile := "/home/" + subDir.Name() + homeFile
info1 := common.Check_file(subFile)
if info1 {
suspicious = true
}
}
}
for _, subFile := range files {
s, err := os.Stat(subFile)
if err != nil {
continue
}
if s.IsDir() {
filepath.Walk(
subFile, func(path string, info fs.FileInfo, err error) error {
if info.IsDir() {
return nil
} else {
info1 := common.Check_file(path)
if info1 {
suspicious = true
}
}
return err
},
)
} else {
info1 := common.Check_file(subFile)
if info1 {
suspicious = true
}
}
}
return suspicious
}
func LdPreloadCheck() bool {
result := checkBackdoor("LD_PRELOAD")
return result
}
func LdAoutPreloadCheck() bool {
result := checkBackdoor("LD_AOUT_PRELOAD")
return result
}
func LdElfPreloadCheck() bool {
result := checkBackdoor("LD_ELF_PRELOAD")
return result
}
func LdLibraryPathCheck() bool {
result := checkBackdoor("LD_LIBRARY_PATH")
return result
}
func PromptCommandCheck() bool {
result := checkBackdoor("PROMPT_COMMAND")
return result
}
func ExportCheck() bool {
result := false
tmp := checkBackdoor("PATH")
tmp1 := checkEnv()
if tmp {
result = tmp
} else {
result = tmp1
}
return result
}
func TcpWrappersCheck() bool {
result := common.Check_file("/etc/hosts.allow")
return result
}
func LdSoPreload() bool {
result := false
if common.PathExists("/etc/ld.so.preload") {
fr, _ := os.Open("/etc/ld.so.preload")
defer fr.Close()
buf := bufio.NewReader(fr)
for {
data, _, c := buf.ReadLine()
if c == io.EOF {
break
}
line := strings.Replace(string(data), "\n", "", -1)
if line[0] == '#' {
continue
}
if line[len(line)-3:] == ".so" {
fmt.Println("[*]File: /etc/ld.so.preload, Found:", line)
result = true
} else {
info := common.CheckShell(line)
if info {
fmt.Println("[*]File: /etc/ld.so.preload, Found:", line)
result = true
}
}
}
}
return result
}
func IntedCheck() bool {
result := false
if !common.PathExists("/etc/inetd.conf") {
return false
}
fr, _ := os.Open("/etc/inetd.conf")
defer fr.Close()
buf := bufio.NewReader(fr)
for {
data, _, c := buf.ReadLine()
if c == io.EOF {
break
}
line := string(data)
content := common.CheckShell(line)
if content {
fmt.Println("[*]File: /etc/inetd.conf, Found:", line)
result = true
}
}
return result
}
func XinetdCheck() bool {
result := false
if !common.PathExists("/etc/xinetd.conf") {
return false
}
dirs, err := ioutil.ReadDir("/etc/xinetd.conf")
if err != nil {
return true
}
for _, dir := range dirs {
subFile := "/etc/xinetd.conf" + dir.Name()
fr, _ := os.Open(subFile)
defer fr.Close()
buf := bufio.NewReader(fr)
for {
data, _, c := buf.ReadLine()
if c == io.EOF {
break
}
line := string(data)
content := common.CheckShell(line)
if content {
fmt.Println("[*]File: /etc/xinetd.conf, Found:", line)
result = true
}
}
}
return result
}
func StartupCheck() bool {
result := false
var suspicious []bool
init_path := []string{
"/etc/init.d/", "/etc/rc.d/", "/etc/rc.local", "/usr/local/etc/rc.d",
"/usr/local/etc/rc.local", "/etc/conf.d/local.start", "/etc/inittab", "/etc/systemd/system",
}
for _, path := range init_path {
if !common.PathExists(path) {
continue
}
filepath.Walk(
path, func(p string, info fs.FileInfo, err error) error {
if info.IsDir() {
return nil
}
b := common.Check_file(p)
if b {
suspicious = append(suspicious, b)
}
return err
},
)
}
end := len(suspicious)
if end != 0 {
result = true
}
return result
}
func pam_check() bool {
result := false
if common.PathExists("/etc/ssh/sshd_config") {
fr, _ := os.Open("/etc/ssh/sshd_config")
defer fr.Close()
bur := bufio.NewReader(fr)
for {
line, _, c := bur.ReadLine()
if c == io.EOF {
break
}
if len(line) == 0 || line[0] == '#' {
continue
}
if strings.Contains(string(line), "UsePAM") && strings.Contains(string(line), "yes") {
fmt.Println("[*]File: /etc/ssh/sshd_config, PAM enabled !!!")
result = true
}
}
}
return result
}

View File

@@ -0,0 +1,126 @@
package check
import (
"bufio"
"fmt"
"io"
"os"
"strings"
"github.com/gookit/color"
"d-eyes/configcheck/common"
)
var suspiciousHistory [][2]string
func HistoryCheck() {
if HistoryFiles() {
color.Infoln("主机历史命令检测: [safe]")
} else {
fmt.Println("历史存在可疑命令, 请确认:")
for _, detail := range suspiciousHistory {
fmt.Printf("[*]File: %s Detail: %s\n", detail[0], detail[1])
}
}
}
func HistoryFiles() bool {
filePath := []string{"/home/", "/root/.bash_history", "/Users/"}
for _, path := range filePath {
if !common.PathExists(path) {
continue
}
dirs, err := os.ReadDir(path)
if err != nil {
fi, _ := os.Open(path)
defer fi.Close()
br := bufio.NewReader(fi)
for {
data, _, c := br.ReadLine()
if c == io.EOF {
break
}
line := strings.Replace(string(data), "\n", "", -1)
contents := Shell(line)
if contents == true {
suspiciousHistory = append(suspiciousHistory, [2]string{path, line})
}
}
continue
}
for _, dir := range dirs {
subFile := path + dir.Name() + "/.bash_history"
if !common.PathExists(subFile) {
continue
}
fi, _ := os.Open(subFile)
defer fi.Close()
br := bufio.NewReader(fi)
for {
data, _, c := br.ReadLine()
if c == io.EOF {
break
}
line := strings.Replace(string(data), "\n", "", -1)
contents := Shell(line)
if contents {
suspiciousHistory = append(suspiciousHistory, [2]string{subFile, line})
}
}
}
}
if len(suspiciousHistory) == 0 {
return true
}
return false
}
func Shell(content string) bool {
if strings.Contains(content, "docker") {
return false
}
if (strings.Contains(content, "sh") && (strings.Contains(content, "/dev/tcp/") ||
strings.Contains(content, "telnet ") || strings.Contains(content, "nc ") ||
(strings.Contains(content, "exec ") && strings.Contains(content, "socket")) ||
strings.Contains(content, "curl ") || strings.Contains(content, "wget ") ||
strings.Contains(content, "lynx "))) || strings.Contains(content, ".decode('base64')") || strings.Contains(content, "exec(base64.b64decode") ||
(strings.Contains(content, "base64 ") && strings.Contains(content, "--decode") && strings.Contains(content, "python")) ||
(strings.Contains(content, "base64 ") && strings.Contains(content, "-d") && strings.Contains(content, "bash")) ||
(strings.Contains(content, "nc ") && strings.Contains(content, "-vv")) ||
(strings.Contains(content, "ln ") && strings.Contains(content, "-sf") && strings.Contains(content, "/usr/sbin/sshd")) {
return true
} else if strings.Contains(content, "/dev/tcp/") && (strings.Contains(content, "exec ") ||
strings.Contains(content, "ksh -c")) {
return true
} else if strings.Contains(content, "sh -i") {
return true
} else if strings.Contains(content, "exec ") && (strings.Contains(content, "socket.") ||
strings.Contains(content, ".decode('base64')")) {
return true
} else if strings.Contains(content, "socket.socket") {
return true
} else if (strings.Contains(content, "wget ") || strings.Contains(content, "curl ")) &&
(strings.Contains(content, " -O ") || strings.Contains(content, " -s ")) &&
strings.Contains(content, " http") && (strings.Contains(content, "php ") ||
strings.Contains(content, "perl ") || strings.Contains(content, "ruby ") ||
strings.Contains(content, "python ") || strings.Contains(content, "sh ") ||
strings.Contains(content, "bash ")) { // Ruby added
return true
} else {
return false
}
}

33
configcheck/check/log.go Normal file
View File

@@ -0,0 +1,33 @@
package check
import (
"fmt"
"os/exec"
"strings"
)
func SuccessLoginDetail() {
c := exec.Command("bash", "-c", "who /var/log/wtmp | awk '{print $1,$3\"-\"$4\"\",$5}'")
out, err := c.CombinedOutput()
if err != nil {
fmt.Println("读取记录失败!")
return
}
infos := strings.Split(string(out), "\n")
infos = infos[:len(infos)-1]
if len(infos) == 1 && infos[0] == "" {
fmt.Println("未找到成功的登录信息.")
return
}
sum := 0
for i := len(infos) - 1; i >= 0; i-- {
sum++
success := strings.Split(infos[i], " ")
fmt.Printf("User : %s time : %s IP : %s\n", success[0], success[1], success[2])
if sum == 5 {
return
}
}
}

1093
configcheck/check/rootkit.go Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
package check
import (
"fmt"
"os/exec"
"strings"
"github.com/toolkits/slice"
)
func SetUid() bool {
suspicious := false
whitelist := []string{
"pam_timestamp_check", "unix_chkpwd", "ping", "mount", "umount", "sudo", "su", "pt_chown", "ssh-keysign", "at", "passwd", "chsh", "crontab", "chfn",
"usernetctl", "staprun", "newgrp", "chage", "dhcp", "helper", "pkexec", "top", "Xorg", "nvidia-modprobe", "quota", "login", "security_authtrampoline",
"authopen", "traceroute6", "traceroute", "ps", "auth_pam_tool", "Xorg.wrap", "gpasswd", "mount.cifs", "mount.nfs", "ping6", "pppd", "fusermount3",
"ntfs-3g",
}
c := exec.Command(
"bash", "-c",
"find / ! -path '/proc/*' -type f -perm -4000 2>/dev/null",
)
output, err := c.CombinedOutput()
if err != nil {
fmt.Println(err.Error())
return suspicious
}
fileInfos := strings.Split(string(output), "\n")
if len(fileInfos) != 0 {
suspicious = true
fmt.Println("主机含有非常见suid程序请确认")
}
for _, info := range fileInfos {
if info == "" {
continue
}
tmp := strings.Split(info, "/")
if !slice.ContainsString(whitelist, tmp[len(tmp)-1]) {
fmt.Println(info)
}
}
return suspicious
}

51
configcheck/check/ssh.go Normal file
View File

@@ -0,0 +1,51 @@
package check
import (
"fmt"
"io/ioutil"
"os/exec"
"strings"
)
func AuthorizedKeys() bool {
suspicious := false
dirs, _ := ioutil.ReadDir("/home")
for _, dir := range dirs {
if !dir.IsDir() {
continue
}
suspicious2 := fileAnalysis("/home/"+dir.Name()+"/.ssh/authorized_keys", dir.Name())
if suspicious2 {
suspicious = true
}
}
suspicious2 := fileAnalysis("/root/.ssh/authorized_keys", "root")
if suspicious2 {
suspicious = true
}
return suspicious
}
func fileAnalysis(file string, user string) bool {
suspicious := false
if FileExist(file) {
c := exec.Command(
"bash", "-c",
"cat "+file+" 2>/dev/null |awk '{print $3}'",
)
output, _ := c.CombinedOutput()
shell_process3 := strings.Split(string(output), "\n")
if len(shell_process3) > 0 {
fmt.Printf("用户 %s 存在免密登录的证书,证书位置: %s \n", user, file)
}
suspicious = true
}
return suspicious
}

223
configcheck/check/sshlog.go Normal file
View File

@@ -0,0 +1,223 @@
package check
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/gookit/color"
"github.com/toolkits/slice"
)
type BaopoInfo struct {
User string
Ip string
Time string
}
// 爆破成功
var correct_baopo_info []BaopoInfo
// 所有爆破的信息(超过阈值)
var baopo_info []BaopoInfo
//所有C段爆破信息超过阈值
//var c_baopo_info []BaopoInfo
// ip_failed_count: 单IP错误的次数超过此错误代表发生了爆破行为
// ips_failed_count: IP C段错误的次数超过此错误代表发生了爆破行为
// correct_baopo_info: 记录爆破成功的信息
func SSH_Analysis(log string, log_dir string, ip_failed_count uint, ips_failed_count uint) {
if log == "" {
dir_file_detect(log_dir, ip_failed_count, ips_failed_count)
} else {
attack_detect(log, ip_failed_count, ips_failed_count)
}
}
func dir_file_detect(log_dir string, ip_failed_count uint, ips_failed_count uint) {
var files []string
dirs, _ := ioutil.ReadDir(log_dir)
for _, dir := range dirs {
if dir.IsDir() {
continue
}
if strings.Contains(dir.Name(), "secure") {
files = append(files, log_dir+dir.Name())
}
}
for _, file := range files {
attack_detect(file, ip_failed_count, ips_failed_count)
}
}
func reRepeat(old []BaopoInfo) []string {
var ip_sum []string
// 遍历数组
for _, item := range old {
if !slice.ContainsString(ip_sum, item.Ip) {
ip_sum = append(ip_sum, item.Ip)
}
}
return ip_sum
}
func filter(old map[string]uint, count uint) map[string]uint {
var new_dict map[string]uint
new_dict = make(map[string]uint)
for key := range old {
if old[key] > count {
new_dict[key] = old[key]
}
}
return new_dict
}
func counter(old []string) map[string]uint {
var count_dict map[string]uint
count_dict = make(map[string]uint)
for _, item := range old {
_, ok := count_dict[item]
if ok {
count_dict[item] += 1
} else {
count_dict[item] = 1
}
}
return count_dict
}
func attack_detect(log string, ip_failed_count uint, ips_failed_count uint) {
// 账户错误特征
username_error := "Invalid user"
// 账户正确密码错误特征
username_correct := "Failed password for"
// 成功登陆
username_password_correct := "Accepted password for"
// 所有错误登陆日志ip
var failed_ips []string
// 登陆成功日志
var correct_infos []BaopoInfo
// 登录日志
var login_infos []BaopoInfo
// C段ip登陆错误日志
//var failed_c_ips []string
_, filename := filepath.Split(log)
year := ""
if strings.Contains(filename, "secure-") && len(filename) == 15 {
year = filename[7:11]
}
dat, err := ioutil.ReadFile(log)
if err != nil {
fmt.Println(err.Error())
}
lines := strings.Split(string(dat), "\n")
for _, line := range lines {
if strings.Contains(line, username_error) && strings.Contains(line, "from") && strings.Contains(line, "sshd") {
ip := strings.Split(strings.Split(line, ": ")[1], " ")[4]
failed_ips = append(failed_ips, ip)
time := strings.Join(strings.Split(strings.Replace(line, " ", " ", -1), " ")[:3], " ") + " " + year
login_infos = append(login_infos, BaopoInfo{User: "", Ip: ip, Time: time})
} else if strings.Contains(line, username_correct) && strings.Contains(line, "from") && strings.Contains(line, "sshd") {
strs := strings.Split(strings.TrimSpace(strings.Split(line, ": ")[1]), " ")
ip := strs[len(strs)-4]
failed_ips = append(failed_ips, ip)
time := strings.Join(strings.Split(strings.Replace(line, " ", " ", -1), " ")[:3], " ") + " " + year
login_infos = append(login_infos, BaopoInfo{User: "", Ip: ip, Time: time})
} else if strings.Contains(line, username_password_correct) && strings.Contains(line, "sshd") {
ip := strings.Split(strings.Split(line, ": ")[1], " ")[5]
user := strings.Split(strings.Split(line, ": ")[1], " ")[3]
time := strings.Join(strings.Split(strings.Replace(line, " ", " ", -1), " ")[:3], " ") + " " + year
correct_infos = append(correct_infos, BaopoInfo{User: user, Ip: ip, Time: time})
}
}
// 记录登陆失败攻击源IP地址和尝试次数
failed_ip_dict := filter(counter(failed_ips), ip_failed_count)
// 获取所有未爆破成功的ip信息
for _, login_info := range login_infos {
for failed := range failed_ip_dict {
if login_info.Ip == failed {
baopo_info = append(baopo_info, login_info)
}
}
}
// 判断爆破行为是否成功:
for _, correct_info := range correct_infos {
for failed := range failed_ip_dict {
if correct_info.Ip == failed {
correct_baopo_info = append(correct_baopo_info, correct_info)
}
}
}
}
func SSHLog() {
_, err := os.Lstat("/var/log/auth.log")
if os.IsNotExist(err) {
_, err := os.Lstat("/var/log/secure")
if os.IsNotExist(err) {
fmt.Println("Could't find SSH log !!!")
} else {
if !sshLogNotSafe("/var/log/secure", "") {
color.Infoln("主机SSH登录爆破检测: [safe]")
}
}
} else {
if !sshLogNotSafe("/var/log/auth.log", "") {
color.Infoln("主机SSH登录爆破检测: [safe]")
}
}
}
func sshLogNotSafe(log string, log_dir string) bool {
malice := false
SSH_Analysis(log, log_dir, 10, 10)
for _, info := range correct_baopo_info {
user := info.User
time := info.Time
ip := info.Ip
fmt.Printf("主机SSH被外部爆破且成功登录时间: %s, ip: %s, 用户: %s\n", time, ip, user)
malice = true
}
ip_sum := reRepeat(baopo_info)
if len(ip_sum) != 0 {
malice = true
fmt.Println("以下", len(ip_sum), "个IP尝试SSH登录爆破建议封禁:")
for _, ip := range ip_sum {
fmt.Print(ip + "、")
}
if len(ip_sum) != 0 {
fmt.Println("")
}
}
return malice
}

View File

@@ -0,0 +1,27 @@
package check
import (
"fmt"
"os/exec"
"strings"
)
func SshWrapper() bool {
suspicious := false
c := exec.Command("bash", "-c", "file /usr/sbin/sshd 2>/dev/null")
output, err := c.CombinedOutput()
if err != nil {
fmt.Println(err.Error())
}
infos := strings.Split(string(output), "\n")
if len(infos) == 0 {
return suspicious
}
if !strings.Contains(infos[0], "ELF") && !strings.Contains(infos[0], "executable") {
fmt.Println("/usr/sbin/sshd被篡改,文件非可执行文件")
suspicious = true
}
return suspicious
}

33
configcheck/check/sudo.go Normal file
View File

@@ -0,0 +1,33 @@
package check
import (
"fmt"
"os/exec"
"strings"
)
func Sudo() bool {
suspicious := false
if FileExist("/etc/sudoers") {
c := exec.Command(
"bash", "-c",
"cat /etc/sudoers 2>/dev/null |grep -v '#'|grep -v '%'|grep '(ALL\\|(root'|awk '{print $1}'",
)
output, err := c.CombinedOutput()
if err != nil {
fmt.Println(err.Error())
return suspicious
}
shell_process3 := strings.Split(string(output), "\n")
for _, user := range shell_process3 {
if len(user) < 1 {
continue
}
if user != "root" && user[0] != '%' {
fmt.Printf("用户 %s 可通过sudo命令获取特权\n", user)
suspicious = true
}
}
}
return suspicious
}

View File

@@ -0,0 +1,117 @@
package common
import (
"bufio"
"fmt"
"io"
"os"
"strings"
)
func Printf(f func() bool) string {
b := f()
if b {
return "\033[1;32m[ OK ]\033[0m"
}
return "\033[1;31m[Warn]\033[0m"
}
func PathExists(path string) bool {
_, err := os.Stat(path)
if err == nil {
return true
}
if os.IsNotExist(err) {
return false
}
return false
}
func Align(str string, width int) string {
if len(str) < width {
end := " "
i := 1
for {
if i >= (width - len(str)) {
break
}
end += " "
i++
}
return str + end
}
return str
}
func CheckShell(content string) bool {
if strings.Contains(content, "docker") {
return false
}
if (strings.Contains(content, "sh") && (strings.Contains(content, "/dev/tcp/") ||
strings.Contains(content, "telnet ") || strings.Contains(content, "nc ") ||
(strings.Contains(content, "exec ") && strings.Contains(content, "socket")) ||
strings.Contains(content, "curl ") || strings.Contains(content, "wget ") ||
strings.Contains(content, "lynx "))) || strings.Contains(content, ".decode('base64')") || strings.Contains(content, "exec(base64.b64decode") ||
(strings.Contains(content, "base64 ") && strings.Contains(content, "--decode") && strings.Contains(content, "python")) ||
(strings.Contains(content, "base64 ") && strings.Contains(content, "-d") && strings.Contains(content, "bash")) ||
(strings.Contains(content, "nc ") && strings.Contains(content, "-vv")) ||
(strings.Contains(content, "ln ") && strings.Contains(content, "-sf") && strings.Contains(content, "/usr/sbin/sshd")) {
return true
} else if strings.Contains(content, "/dev/tcp/") && (strings.Contains(content, "exec ") ||
strings.Contains(content, "ksh -c")) {
return true
} else if strings.Contains(content, "sh -i") {
return true
} else if strings.Contains(content, "exec ") && (strings.Contains(content, "socket.") ||
strings.Contains(content, ".decode('base64')")) {
return true
} else if strings.Contains(content, "socket.socket") {
return true
} else if (strings.Contains(content, "wget ") || strings.Contains(content, "curl ")) &&
(strings.Contains(content, " -O ") || strings.Contains(content, " -s ")) &&
strings.Contains(content, " http") && (strings.Contains(content, "php ") ||
strings.Contains(content, "perl ") || strings.Contains(content, "ruby ") ||
strings.Contains(content, "python ") || strings.Contains(content, "sh ") ||
strings.Contains(content, "bash ")) { // Ruby added
return true
} else {
return false
}
}
func Check_file(path string) bool {
result := false
_, err := os.Stat(path)
if err != nil {
return false
}
fr, _ := os.Open(path)
buf := bufio.NewReader(fr)
for {
line, _, e := buf.ReadLine()
if e == io.EOF {
break
}
if len(string(line)) < 3 {
continue
}
if string(line)[0] == '#' {
continue
}
c := CheckShell(string(line))
if c {
fmt.Println("[*]File:", path, "Found:", string(line))
result = true
}
}
return result
}

291
deyes_linux.go Normal file
View File

@@ -0,0 +1,291 @@
package main
import (
"fmt"
"log"
"os"
"strconv"
"strings"
"time"
"github.com/gookit/color"
"github.com/urfave/cli/v2"
"github.com/xuri/excelize/v2"
"d-eyes/basicinfo/info"
"d-eyes/configcheck/check"
"d-eyes/filedetection"
"d-eyes/logo"
"d-eyes/output"
"d-eyes/process/controller"
"d-eyes/yaraobj"
)
var path string
var rule string
var thread int
var pid int
func main() {
logo.ShowLogo()
app := &cli.App{
Name: "D-Eyes",
Usage: "The Eyes of Darkness from Nsfocus spy on everything.",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "path",
Aliases: []string{"P"},
Value: "/",
Usage: "--path / or -P / (Only For Filescan)",
Destination: &path,
},
&cli.IntFlag{
Name: "pid",
Aliases: []string{"p"},
Value: -1,
Usage: "--pid 666 or -p 666 (Only For processcan.'-1' means all processes.)",
Destination: &pid,
},
&cli.StringFlag{
Name: "rule",
Aliases: []string{"r"},
//Value: 5,
Usage: "--rule Ransom.Wannacrypt or -r Ransom.Wannacrypt",
Destination: &rule,
},
&cli.IntFlag{
Name: "thread",
Aliases: []string{"t"},
Value: 5,
Usage: "--thread 1 or -t 1 (Only For Filescan)",
Destination: &thread,
},
},
Commands: []*cli.Command{
{
Name: "filescan",
Aliases: []string{"fs"},
Usage: "Command for scanning filesystem",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "path",
Aliases: []string{"P"},
Value: "/",
Usage: "--path / or -P / (Only For Filescan)",
Destination: &path,
},
&cli.StringFlag{
Name: "rule",
Aliases: []string{"r"},
//Value: 5,
Usage: "--rule Ransom.Wannacrypt or -r Ransom.Wannacrypt",
Destination: &rule,
},
&cli.IntFlag{
Name: "thread",
Aliases: []string{"t"},
Value: 5,
Usage: "--thread 1 or -t 1",
Destination: &thread,
},
},
Action: func(c *cli.Context) error {
// fmt.Println("added task: ", c.Args().First())
//
//
var paths []string
r := []output.Result{}
paths = strings.Split(path, ",")
var start = time.Now()
var sum = 0
if rule == "" {
yaraRule := "./yaraRules"
rules, err := yaraobj.LoadAllYaraRules(yaraRule)
if err != nil {
color.Redln("LoadCompiledRules goes error !!!")
color.Redln("GetRules err: ", err)
os.Exit(1)
}
for _, path := range paths {
files := filedetection.StartFileScan(path, rules, thread, &r)
sum += files
}
} else {
yaraRule := "./yaraRules/" + rule + ".yar"
_, err := os.Lstat(yaraRule)
if err != nil {
color.Redln("There is no such rule yet !!!")
os.Exit(1)
}
rules, err := yaraobj.LoadSingleYaraRule(yaraRule)
if err != nil {
color.Redln("GetRules err: ", err)
os.Exit(1)
}
for _, path := range paths {
files := filedetection.StartFileScan(path, rules, thread, &r)
sum += files
}
}
if len(r) > 0 {
length := len(r)
categories := map[string]string{
"A1": "Risk Description", "B1": "Risk File Path",
}
var values = make(map[string]string)
vulsumTmp := 0
for i := 0; i < length; i++ {
vulsumTmp++
color.Error.Println("[ Risk ", vulsumTmp, " ]")
fmt.Print("Risk Description: ")
color.Warn.Println(r[i].Risk)
fmt.Println("Risk File Path: ")
color.Warn.Println(r[i].RiskPath)
//set excel values
excelValuetmpA := "A" + strconv.Itoa(vulsumTmp+1)
excelValuetmpB := "B" + strconv.Itoa(vulsumTmp+1)
values[excelValuetmpA] = r[i].Risk
values[excelValuetmpB] = r[i].RiskPath
}
//output to a excel
f := excelize.NewFile()
f.SetColWidth("Sheet1", "A", "B", 50)
for k, v := range categories {
f.SetCellValue("Sheet1", k, v)
}
for k, v := range values {
f.SetCellValue("Sheet1", k, v)
}
style, err := f.NewStyle(
&excelize.Style{
Font: &excelize.Font{
Bold: true,
Size: 11,
Color: "e83723",
},
},
)
if err != nil {
fmt.Println(err)
}
f.SetCellStyle("Sheet1", "A1", "A1", style)
f.SetCellStyle("Sheet1", "B1", "B1", style)
// save the result to Deyes.xlsx
if err := f.SaveAs("D-Eyes.xlsx"); err != nil {
fmt.Println(err)
}
} else {
fmt.Println("\nNo suspicious files found. Your computer is safe with the rules you choose.")
}
var end = time.Now().Sub(start)
fmt.Println("Consuming Time: ", end, " Number of scanned files: ", sum)
return nil
},
},
{
Name: "processcan",
Aliases: []string{"ps"},
Usage: "Command for scanning processes",
Flags: []cli.Flag{
&cli.IntFlag{
Name: "pid",
Aliases: []string{"p"},
Value: -1,
Usage: "--pid 666 or -p 666 ('-1' means all processes.)",
Destination: &pid,
},
&cli.StringFlag{
Name: "rule",
Aliases: []string{"r"},
Usage: "--rule Ransom.Wannacrypt or -r Ransom.Wannacrypt",
Destination: &rule,
},
},
Action: func(c *cli.Context) error {
var start = time.Now()
controller.ScanProcess(pid, rule)
var end = time.Now().Sub(start)
fmt.Println("Consuming Time: ", end)
return nil
},
},
{
Name: "selfcheck",
Aliases: []string{"sc"},
Usage: "Command for checking some files which may have backdoors",
Action: func(c *cli.Context) error {
check.Trigger()
return nil
},
},
{
Name: "host",
Usage: "Command for displaying basic host information",
Action: func(c *cli.Context) error {
color.Infoln("Host Info:")
info.DisplayBaseInfo()
return nil
},
},
{
Name: "users",
Usage: "Command for displaying all the users on the host",
Action: func(c *cli.Context) error {
color.Infoln("AllUsers:")
info.DisplayAllUsers()
return nil
},
},
{
Name: "top",
Usage: "Command for displaying the top 15 processes in CPU usage",
Action: func(c *cli.Context) error {
info.Top()
return nil
},
},
{
Name: "netstat",
Usage: "Command for displaying host network information",
Action: func(c *cli.Context) error {
color.Infoln("Network Info:")
info.DisplayNetStat()
return nil
},
},
{
Name: "task",
Usage: "Command for displaying all the tasks on the host",
Action: func(c *cli.Context) error {
color.Infoln("Task:")
info.DisplayPlanTask()
return nil
},
},
{
Name: "autoruns",
Usage: "Command for displaying all the autoruns on the host",
Action: func(c *cli.Context) error {
color.Infoln("Autoruns:")
info.CallDisplayAutoruns()
return nil
},
},
{
Name: "export",
Usage: "Command for exporting basic host information",
Action: func(c *cli.Context) error {
info.SaveSummaryBaseInfo()
return nil
},
},
},
}
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}

337
deyes_windows.go Normal file
View File

@@ -0,0 +1,337 @@
package main
import (
"fmt"
"log"
"os"
"strconv"
"strings"
"time"
"github.com/gookit/color"
"github.com/urfave/cli/v2"
"github.com/xuri/excelize/v2"
"d-eyes/basicinfo/info"
"d-eyes/filedetection"
"d-eyes/logo"
"d-eyes/output"
"d-eyes/yaraobj"
)
var path string
var rule string
var thread int
var pid int
var vulnerability int
func main() {
srcPath := SrcPath()
logo.ShowLogo()
app := &cli.App{
Name: "D-Eyes",
Usage: "The Eyes of Darkness from Nsfocus spy on everything.",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "path",
Aliases: []string{"P"},
Value: "C://",
Usage: "-P C:// (Only For Filescan)",
Destination: &path,
},
&cli.IntFlag{
Name: "pid",
Aliases: []string{"p"},
Value: -1,
Usage: "-p 666 (Only For processcan.'-1' means all processes.)",
Destination: &pid,
},
&cli.StringFlag{
Name: "rule",
Aliases: []string{"r"},
Usage: "-r Ransom.Wannacrypt",
Destination: &rule,
},
&cli.IntFlag{
Name: "thread",
Aliases: []string{"t"},
Value: 5,
Usage: "-t 1 (Only For Filescan)",
Destination: &thread,
},
&cli.IntFlag{
Name: "vul",
Aliases: []string{"v"},
Usage: "-v 1 (1 is to check Exchange Server OWASSRF exploitation)",
Destination: &vulnerability,
},
},
Commands: []*cli.Command{
{
Name: "filescan",
Aliases: []string{"fs"},
Usage: "Command for scanning filesystem",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "path",
Aliases: []string{"P"},
Value: "C://",
Usage: "--path C:// or -P C:// (Only For Filescan)",
Destination: &path,
},
&cli.StringFlag{
Name: "rule",
Aliases: []string{"r"},
Usage: "--rule Ransom.Wannacrypt or -r Ransom.Wannacrypt",
Destination: &rule,
},
&cli.IntFlag{
Name: "thread",
Aliases: []string{"t"},
Value: 5,
Usage: "--thread 1 or -t 1",
Destination: &thread,
},
},
Action: func(c *cli.Context) error {
var paths []string
var r []output.Result
paths = strings.Split(path, ",")
var start = time.Now()
var sum = 0
if rule == "" {
yaraRule := srcPath + "yaraRules"
rules, err := yaraobj.LoadAllYaraRules(yaraRule)
if err != nil {
color.Redln("LoadCompiledRules goes error !!!")
color.Redln("GetRules err: ", err)
os.Exit(1)
}
for _, path := range paths {
files := filedetection.StartFileScan(path, rules, thread, &r)
sum += files
}
} else {
yaraRule := srcPath + "yaraRules\\" + rule + ".yar"
_, err := os.Lstat(yaraRule)
if err != nil {
color.Redln("There is no such rule yet !!!")
os.Exit(1)
}
rules, err := yaraobj.LoadSingleYaraRule(yaraRule)
if err != nil {
color.Redln("GetRules err: ", err)
os.Exit(1)
}
for _, path := range paths {
files := filedetection.StartFileScan(path, rules, thread, &r)
sum += files
}
}
if len(r) > 0 {
length := len(r)
categories := map[string]string{
"A1": "Risk Description", "B1": "Risk File Path",
}
var values = make(map[string]string)
vulsumTmp := 0
for i := 0; i < length; i++ {
vulsumTmp++
color.Error.Println("[ Risk ", vulsumTmp, " ]")
fmt.Print("Risk Description: ")
color.Warn.Println(r[i].Risk)
fmt.Println("Risk File Path: ")
color.Warn.Println(r[i].RiskPath)
//set excel values
excelValuetmpA := "A" + strconv.Itoa(vulsumTmp+1)
excelValuetmpB := "B" + strconv.Itoa(vulsumTmp+1)
values[excelValuetmpA] = r[i].Risk
values[excelValuetmpB] = r[i].RiskPath
}
//output to a excel
f := excelize.NewFile()
f.SetColWidth("Sheet1", "A", "B", 50)
for k, v := range categories {
f.SetCellValue("Sheet1", k, v)
}
for k, v := range values {
f.SetCellValue("Sheet1", k, v)
}
style, err := f.NewStyle(
&excelize.Style{
Font: &excelize.Font{
Bold: true,
Size: 11,
Color: "e83723",
},
},
)
if err != nil {
fmt.Println(err)
}
f.SetCellStyle("Sheet1", "A1", "A1", style)
f.SetCellStyle("Sheet1", "B1", "B1", style)
// save the result to Deyes.xlsx
if err := f.SaveAs(srcPath + "D-Eyes_FileResult.xlsx"); err != nil {
fmt.Println(err)
}
} else {
fmt.Println("\nNo suspicious files found. Your computer is safe with the rules you choose.")
}
var end = time.Now().Sub(start)
fmt.Println("Consuming Time: ", end, " Number of scanned files: ", sum)
return nil
},
},
{
Name: "processcan",
Aliases: []string{"ps"},
Usage: "Command for scanning processes",
Flags: []cli.Flag{
&cli.IntFlag{
Name: "pid",
Aliases: []string{"p"},
Value: -1,
Usage: "--pid 666 or -p 666 ('-1' means all processes.)",
Destination: &pid,
},
&cli.StringFlag{
Name: "rule",
Aliases: []string{"r"},
Usage: "--rule Ransom.Wannacrypt or -r Ransom.Wannacrypt",
Destination: &rule,
},
},
Action: func(c *cli.Context) error {
var start = time.Now()
// todo
//controller.ScanProcess(pid, rule, src_path)
var end = time.Now().Sub(start)
fmt.Println("Consuming Time: ", end)
return nil
},
},
{
Name: "host",
Usage: "Command for displaying basic host information",
Action: func(c *cli.Context) error {
color.Infoln("Host Info:")
info.DisplayBaseInfo()
return nil
},
},
{
Name: "users",
Usage: "Command for displaying all the users on the host",
Action: func(c *cli.Context) error {
color.Infoln("AllUsers:")
info.DisplayAllUsers()
return nil
},
},
{
Name: "top",
Usage: "Command for displaying the top 15 processes in CPU usage",
Action: func(c *cli.Context) error {
info.Top()
return nil
},
},
{
Name: "netstat",
Usage: "Command for displaying host network information",
Action: func(c *cli.Context) error {
color.Infoln("Network Info:")
info.DisplayNetStat(srcPath)
return nil
},
},
{
Name: "task",
Usage: "Command for displaying all the tasks on the host",
Action: func(c *cli.Context) error {
color.Infoln("Task:")
info.DisplayPlanTask()
return nil
},
},
{
Name: "autoruns",
Usage: "Command for displaying all the autoruns on the host",
Action: func(c *cli.Context) error {
color.Infoln("Autoruns:")
info.CallDisplayAutoruns()
return nil
},
},
{
Name: "export",
Usage: "Command for exporting basic host information",
Action: func(c *cli.Context) error {
info.SaveSummaryBaseInfo()
return nil
},
},
{
Name: "check",
Usage: "Command for checking vulnerability exploitation",
Flags: []cli.Flag{
&cli.IntFlag{
Name: "vulnerability",
Aliases: []string{"v"},
Usage: "-v 1 (1 is to check Exchange Server OWASSRF exploitation)",
Destination: &vulnerability,
},
},
Action: func(c *cli.Context) error {
switch vulnerability {
case 1:
var path string
if len(os.Args) > 4 {
path = os.Args[4]
}
info.CheckExchangeServerOWASSRF(path)
default:
fmt.Println("Please enter the number of vulnerability exploitation you want to check.")
fmt.Println()
color.Warn.Println("Currently supported vulnerability exploitation list:")
fmt.Println(" 1: Exchange Server OWASSRF")
fmt.Println()
fmt.Print("Like this, if you want to check 'Exchange Server OWASSRF' exploitation, just input ")
color.Warn.Println("'D-Eyes check -v 1'")
}
return nil
},
},
},
}
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}
func SrcPath() string {
args := os.Args
lastIndex := strings.LastIndex(args[0], "\\")
cmdPath := args[0][0 : lastIndex+1]
currentDir, _ := os.Getwd()
dir, _ := os.ReadDir(currentDir)
for _, f := range dir {
if f.IsDir() {
if f.Name() == "yaraRules" {
return currentDir + "\\"
}
}
}
return cmdPath
}

56
filedetection/file.go Normal file
View File

@@ -0,0 +1,56 @@
package filedetection
import (
"os"
)
type File interface {
Path() string
Stat() (os.FileInfo, error)
Hashes() (md5sum, sha256sum string, err error)
EnableHashMarshalling() error
}
type OSFile struct {
FilePath string `json:"path"`
MD5Sum string `json:"MD5,omitempty"`
SHA256Sum string `json:"SHA256,omitempty"`
}
func NewFile(path string) File {
return &OSFile{FilePath: path}
}
//
//func CloneFile(f File) File {
// if f == nil {
// return nil
// }
//
// osFile, ok := f.(*OSFile)
// if ok {
// return &OSFile{
// FilePath: osFile.FilePath,
// MD5Sum: osFile.MD5Sum,
// SHA256Sum: osFile.SHA256Sum,
// }
// }
// return NewFile(f.Path())
//}
func (f *OSFile) Path() string {
return f.FilePath
}
func (f *OSFile) Stat() (os.FileInfo, error) {
return os.Stat(f.FilePath)
}
func (f *OSFile) Hashes() (md5sum, sha256sum string, err error) {
return ComputeHashes(f.FilePath)
}
func (f *OSFile) EnableHashMarshalling() (err error) {
f.MD5Sum, f.SHA256Sum, err = f.Hashes()
return
}

54
filedetection/filescan.go Normal file
View File

@@ -0,0 +1,54 @@
package filedetection
import (
"context"
"fmt"
"sync"
"github.com/hillu/go-yara/v4"
"d-eyes/output"
"d-eyes/yaraobj"
)
func StringSlice(name string) []string {
return nil
}
var sum = 0
func StartFileScan(path string, rules *yara.Rules, thread int, r *[]output.Result) int {
iteratorCtx := context.Background()
var pathIterator Iterator
fileExtensions := StringSlice("")
pIt, err := IteratePath(iteratorCtx, path, fileExtensions)
if err != nil {
fmt.Printf("- %s ERROR: could not intialize scanner for path, reason: %v", path, err)
}
pathIterator = Concurrent(pathIterator, pIt)
fmt.Printf("- %s\n", path)
if pathIterator != nil {
defer pathIterator.Close()
yaraScanner, err := yaraobj.NewYaraScanner(rules)
if err != nil {
fmt.Println("NewYaraScanner goes error !!!")
}
fsScanner := NewFSScanner(yaraScanner)
wg := &sync.WaitGroup{}
wg.Add(thread)
for i := 0; i < thread; i++ {
go fsScanner.Scan(pathIterator, wg, &sum, r)
}
wg.Wait()
}
return sum
}

View File

@@ -0,0 +1,68 @@
package filedetection
import (
"encoding/json"
"io"
"path/filepath"
"strings"
"sync"
"github.com/hillu/go-yara/v4"
"d-eyes/output"
"d-eyes/yaraobj"
)
type FSScanner struct {
scanner *yaraobj.YaraScanner
}
func NewFSScanner(scanner *yaraobj.YaraScanner) *FSScanner {
return &FSScanner{
scanner: scanner,
}
}
type FSScanProgress struct {
File File
Matches yara.MatchRules
Error error
}
func (s *FSScanner) Scan(it Iterator, wg *sync.WaitGroup, sum *int, r *[]output.Result) {
defer wg.Done()
for {
file, err := it.Next()
if err == io.EOF {
break
} else if err != nil {
continue
}
*sum++
switch ext := strings.ToLower(filepath.Ext(file.Path())); ext {
case ".yar":
continue
case ".zip", ".tar.gz", ".rar", ".7z", ".gzp", ".bzp2", ".tar", ".gz", ".iso", ".vmem", ".vhd", ".qcow2", ".vmdk":
continue
default:
matches, err := s.scanner.ScanFile(file.Path())
if err != nil {
//fmt.Println("The matches of ScanFile function goes wrong!!! ")
//fmt.Println("err is ",err," file is ",file.Path())
//fmt.Println("-----------------------------------------------")
//return nil
}
if len(matches) != 0 {
data := matches[0].Metas[0]
dataType, _ := json.Marshal(data)
dataString := string(dataType)
meta := strings.Split(dataString, ":")[2]
metaTmp := strings.Trim(meta, "\"}")
resTmp := output.Result{metaTmp, file.Path()}
*r = append(*r, resTmp)
}
}
}
}

View File

@@ -0,0 +1,61 @@
package filedetection
import (
"encoding/json"
"fmt"
"io"
"path/filepath"
"strings"
"sync"
"github.com/gookit/color"
"d-eyes/output"
"d-eyes/yaraobj"
)
type FSScanner struct {
scanner *yaraobj.YaraScanner
}
func NewFSScanner(scanner *yaraobj.YaraScanner) *FSScanner {
return &FSScanner{
scanner: scanner,
}
}
func (s *FSScanner) Scan(it Iterator, wg *sync.WaitGroup, sum *int, r *[]output.Result) {
defer wg.Done()
for {
file, err := it.Next()
if err == io.EOF {
break
} else if err != nil {
continue
}
*sum++
color.Info.Print("[INFO] D-Eyes FileScan scanning: ")
fmt.Println(file.Path())
switch ext := strings.ToLower(filepath.Ext(file.Path())); ext {
case ".yar":
continue
case ".zip", ".tar.gz", ".rar", ".7z", ".gzp", ".bzp2", ".tar", ".gz", ".iso", ".vmem", ".vhd", ".qcow2", ".vmdk":
continue
default:
matches, err := s.scanner.ScanFile(file.Path())
if err != nil {
continue
}
if len(matches) != 0 {
data := matches[0].Metas[0]
dataType, _ := json.Marshal(data)
dataString := string(dataType)
meta := strings.Split(dataString, ":")[2]
metaTmp := strings.Trim(meta, "\"}")
resTmp := output.Result{Risk: metaTmp, RiskPath: file.Path()}
*r = append(*r, resTmp)
}
}
}
}

View File

@@ -0,0 +1,236 @@
package filedetection
import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"strings"
)
var (
FilesBuffer = 8
)
// doScandir linux
var skippedRoots = []string{
"/dev",
"/proc",
"/sys",
"/run",
}
var skippedDirs = []string{
"lost+found",
}
func doScanDir(path string) bool {
var err error
path, err = filepath.Abs(path)
if err != nil {
return false
}
for _, root := range skippedRoots {
if len(path) < len(root) {
continue
}
if path[:len(root)] == root {
if len(path) == len(root) || path[len(root)] == '/' {
return false
}
}
}
for _, dir := range skippedDirs {
if strings.Contains(path, "/"+dir) {
if len(path) == len(dir)+1 || path[len(dir)+1] == '/' {
return false
}
}
}
return true
}
var ErrSkipped = fmt.Errorf("skipped")
type nextEntry struct {
File File
Err error
}
type fsIterator struct {
root string
validExtensions []string
ctx context.Context
cancel context.CancelFunc
closed bool
dirs []string
next chan *nextEntry
}
func IteratePath(ctx context.Context, path string, validExtensions []string) (Iterator, error) {
stat, err := os.Stat(path)
if err != nil {
return nil, err
}
if !stat.IsDir() {
return nil, fmt.Errorf("path must be a directory")
}
for i := range validExtensions {
validExtensions[i] = strings.ToLower(validExtensions[i])
}
it := &fsIterator{
root: path,
validExtensions: validExtensions,
closed: false,
dirs: make([]string, 1, 16),
next: make(chan *nextEntry, FilesBuffer),
}
it.dirs[0] = path
it.ctx, it.cancel = context.WithCancel(ctx)
go it.dirScanner()
return it, nil
}
func (it *fsIterator) Root() string {
return it.root
}
func (it *fsIterator) doesExtensionMatch(path string) bool {
if it.validExtensions == nil || len(it.validExtensions) == 0 {
return true
}
_, file := filepath.Split(path)
parts := strings.Split(file, ".")
var ext string
if len(parts) > 1 {
ext = parts[len(parts)-1]
}
ext = strings.ToLower(ext)
for _, vExt := range it.validExtensions {
if ext == vExt {
return true
}
}
return false
}
func (it *fsIterator) dirScanner() {
defer close(it.next)
for {
select {
case <-it.ctx.Done():
break
default:
}
if len(it.dirs) == 0 {
break
}
dir := it.dirs[0]
it.dirs = it.dirs[1:]
func() {
f, err := os.Open(dir)
if err != nil {
it.next <- &nextEntry{
File: NewFile(dir),
Err: err,
}
return
}
defer f.Close()
for {
contents, err := f.Readdir(1)
if err == io.EOF {
break
} else if err != nil {
it.next <- &nextEntry{
File: NewFile(dir),
Err: err,
}
return
}
path := filepath.Join(dir, contents[0].Name())
if contents[0].IsDir() {
if doScanDir(path) {
it.dirs = append(it.dirs, path)
}
} else {
if it.doesExtensionMatch(path) {
it.next <- &nextEntry{
File: NewFile(path),
}
} else {
it.next <- &nextEntry{
File: NewFile(path),
Err: ErrSkipped,
}
}
}
}
}()
}
}
func (it *fsIterator) Next() (File, error) {
if it.closed {
return nil, io.EOF
}
next := <-it.next
if next == nil {
return nil, io.EOF
}
return next.File, next.Err
}
func (it *fsIterator) Close() error {
if it.closed {
return nil
}
it.closed = true
defer it.cancel()
return it.ctx.Err()
}
type fileListIterator struct {
files []string
i int
}
func IterateFileList(files []string) Iterator {
return &fileListIterator{
files: files,
i: 0,
}
}
func (it *fileListIterator) Next() (File, error) {
if it.i >= len(it.files) {
return nil, io.EOF
}
file := NewFile(it.files[it.i])
it.i++
return file, nil
}
func (it *fileListIterator) Close() error {
return nil
}

View File

@@ -0,0 +1,203 @@
package filedetection
import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"strings"
)
var (
FilesBuffer = 8
)
//doScandir windows
func doScanDir(path string) bool {
return true
}
var ErrSkipped = fmt.Errorf("skipped")
type nextEntry struct {
File File
Err error
}
type fsIterator struct {
root string
validExtensions []string
ctx context.Context
cancel context.CancelFunc
closed bool
dirs []string
next chan *nextEntry
}
func IteratePath(ctx context.Context, path string, validExtensions []string) (Iterator, error) {
stat, err := os.Stat(path)
if err != nil {
return nil, err
}
if !stat.IsDir() {
return nil, fmt.Errorf("path must be a directory")
}
for i := range validExtensions {
validExtensions[i] = strings.ToLower(validExtensions[i])
}
it := &fsIterator{
root: path,
validExtensions: validExtensions,
closed: false,
dirs: make([]string, 1, 16),
next: make(chan *nextEntry, FilesBuffer),
}
it.dirs[0] = path
it.ctx, it.cancel = context.WithCancel(ctx)
go it.dirScanner()
return it, nil
}
func (it *fsIterator) Root() string {
return it.root
}
func (it *fsIterator) doesExtensionMatch(path string) bool {
if it.validExtensions == nil || len(it.validExtensions) == 0 {
return true
}
_, file := filepath.Split(path)
parts := strings.Split(file, ".")
var ext string
if len(parts) > 1 {
ext = parts[len(parts)-1]
}
ext = strings.ToLower(ext)
for _, vExt := range it.validExtensions {
if ext == vExt {
return true
}
}
return false
}
func (it *fsIterator) dirScanner() {
defer close(it.next)
for {
select {
case <-it.ctx.Done():
break
default:
}
if len(it.dirs) == 0 {
break
}
dir := it.dirs[0]
it.dirs = it.dirs[1:]
func() {
f, err := os.Open(dir)
if err != nil {
it.next <- &nextEntry{
File: NewFile(dir),
Err: err,
}
return
}
defer f.Close()
for {
contents, err := f.Readdir(1)
if err == io.EOF {
break
} else if err != nil {
it.next <- &nextEntry{
File: NewFile(dir),
Err: err,
}
return
}
path := filepath.Join(dir, contents[0].Name())
if contents[0].IsDir() {
if doScanDir(path) {
it.dirs = append(it.dirs, path)
}
} else {
if it.doesExtensionMatch(path) {
it.next <- &nextEntry{
File: NewFile(path),
}
} else {
it.next <- &nextEntry{
File: NewFile(path),
Err: ErrSkipped,
}
}
}
}
}()
}
}
func (it *fsIterator) Next() (File, error) {
if it.closed {
return nil, io.EOF
}
next := <-it.next
if next == nil {
return nil, io.EOF
}
return next.File, next.Err
}
func (it *fsIterator) Close() error {
if it.closed {
return nil
}
it.closed = true
defer it.cancel()
return it.ctx.Err()
}
type fileListIterator struct {
files []string
i int
}
func IterateFileList(files []string) Iterator {
return &fileListIterator{
files: files,
i: 0,
}
}
func (it *fileListIterator) Next() (File, error) {
if it.i >= len(it.files) {
return nil, io.EOF
}
file := NewFile(it.files[it.i])
it.i++
return file, nil
}
func (it *fileListIterator) Close() error {
return nil
}

87
filedetection/hashes.go Normal file
View File

@@ -0,0 +1,87 @@
package filedetection
import (
"crypto/md5"
"crypto/sha256"
"encoding/hex"
"io"
"os"
"sync"
)
var globalHasher *CachingHasher
func init() {
globalHasher = NewCachingHasher()
}
// ComputeHashes computes the md5 and sha256 hashes of a given file.
func ComputeHashes(file string) (md5sum, sha256sum string, err error) {
return globalHasher.ComputeHashes(file)
}
type multiHash struct {
md5sum string
sha256sum string
}
type CachingHasher struct {
hashes map[string]*multiHash
mux *sync.RWMutex
}
func NewCachingHasher() *CachingHasher {
return &CachingHasher{
hashes: map[string]*multiHash{},
mux: &sync.RWMutex{},
}
}
func (h *CachingHasher) readCache(file string) (*multiHash, bool) {
h.mux.RLock()
defer h.mux.RUnlock()
hashes, ok := h.hashes[file]
return hashes, ok
}
func (h *CachingHasher) writeCache(file string, hashes *multiHash) {
h.mux.Lock()
defer h.mux.Unlock()
h.hashes[file] = hashes
}
// ComputeHashes computes the md5 and sha256 hashes of a given file.
func (h *CachingHasher) ComputeHashes(file string) (md5sum, sha256sum string, err error) {
hashes, ok := h.readCache(file)
if ok {
return hashes.md5sum, hashes.sha256sum, nil
}
var f *os.File
f, err = os.OpenFile(file, os.O_RDONLY, 0666)
if err != nil {
return
}
defer f.Close()
h5 := md5.New()
h256 := sha256.New()
teeH5 := io.TeeReader(f, h5)
_, err = io.Copy(h256, teeH5)
if err != nil {
return
}
md5sum = hex.EncodeToString(h5.Sum(nil))
sha256sum = hex.EncodeToString(h256.Sum(nil))
h.writeCache(file, &multiHash{
md5sum: md5sum,
sha256sum: sha256sum,
})
return
}

172
filedetection/iterator.go Normal file
View File

@@ -0,0 +1,172 @@
package filedetection
import (
"io"
"sync"
"github.com/targodan/go-errors"
)
type Iterator interface {
Next() (File, error)
Close() error
}
type concatIterator struct {
i int
iterators []Iterator
}
func concat(it1 Iterator, it2 Iterator) Iterator {
if it1 == nil {
return it2
}
if it2 == nil {
return it1
}
cit1, ok1 := it1.(*concatIterator)
cit2, ok2 := it2.(*concatIterator)
if ok1 && ok2 {
cit1.iterators = append(cit1.iterators, cit2.iterators...)
return cit1
}
if ok1 {
cit1.iterators = append(cit1.iterators, it2)
return cit1
}
if ok2 {
cit2.iterators = append(cit2.iterators, it1)
return cit2
}
return &concatIterator{
i: 0,
iterators: []Iterator{it1, it2},
}
}
func Concat(iterators ...Iterator) Iterator {
var ret Iterator
for _, it := range iterators {
ret = concat(ret, it)
}
return ret
}
func (it *concatIterator) Next() (File, error) {
if it.i >= len(it.iterators) {
return nil, io.EOF
}
f, err := it.iterators[it.i].Next()
if err == io.EOF {
it.i++
return it.Next()
}
return f, err
}
func (it *concatIterator) Close() error {
var err error
for _, iterator := range it.iterators {
err = errors.NewMultiError(err, iterator.Close())
}
return err
}
type concurrentIterator struct {
iterators []Iterator
c chan *nextEntry
wg *sync.WaitGroup
closed bool
}
func concurrent(it1 Iterator, it2 Iterator) Iterator {
if it1 == nil {
return it2
}
if it2 == nil {
return it1
}
cit1, ok1 := it1.(*concurrentIterator)
cit2, ok2 := it2.(*concurrentIterator)
if ok1 && ok2 {
panic("cannot combine two concurrent iterators")
}
if ok1 {
cit1.iterators = append(cit1.iterators, it2)
cit1.wg.Add(1)
go cit1.consume(len(cit1.iterators) - 1)
return cit1
}
if ok2 {
cit2.iterators = append(cit2.iterators, it1)
cit2.wg.Add(1)
go cit2.consume(len(cit2.iterators) - 1)
return cit2
}
cit := &concurrentIterator{
iterators: []Iterator{it1, it2},
c: make(chan *nextEntry),
wg: new(sync.WaitGroup),
}
cit.wg.Add(2)
go cit.consume(0)
go cit.consume(1)
go func() {
cit.wg.Wait()
close(cit.c)
}()
return cit
}
func Concurrent(iterators ...Iterator) Iterator {
var cit Iterator
for _, it := range iterators {
cit = concurrent(cit, it)
}
return cit
}
func (it *concurrentIterator) consume(i int) {
defer it.wg.Done()
for {
f, err := it.iterators[i].Next()
if err == io.EOF {
break
}
it.c <- &nextEntry{
File: f,
Err: err,
}
}
}
func (it *concurrentIterator) Next() (File, error) {
if it.closed {
return nil, io.EOF
}
next := <-it.c
if next == nil {
return nil, io.EOF
}
return next.File, next.Err
}
func (it *concurrentIterator) Close() error {
if it.closed {
return nil
}
it.closed = true
var err error
for _, iterator := range it.iterators {
err = errors.NewMultiError(err, iterator.Close())
}
return err
}

43
go.mod Normal file
View File

@@ -0,0 +1,43 @@
module d-eyes
go 1.21.1
require (
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394
github.com/botherder/go-files v0.0.0-20180205213231-2246e61e05ec
github.com/daviddengcn/go-colortext v1.0.0
github.com/gookit/color v1.5.4
github.com/hillu/go-yara/v4 v4.3.2
github.com/mattn/go-shellwords v1.0.12
github.com/olekukonko/tablewriter v0.0.5
github.com/shirou/gopsutil/v3 v3.23.10
github.com/targodan/go-errors v1.0.0
github.com/toolkits/slice v0.0.0-20141116085117-e44a80af2484
github.com/urfave/cli/v2 v2.25.7
github.com/xuri/excelize/v2 v2.8.0
github.com/yusufpapurcu/wmi v1.2.3
golang.org/x/sys v0.13.0
)
require (
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
github.com/richardlehane/mscfb v1.0.4 // indirect
github.com/richardlehane/msoleps v1.0.3 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 // indirect
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/text v0.13.0 // indirect
)

41
logo/logo_linux.go Normal file
View File

@@ -0,0 +1,41 @@
package logo
import (
"fmt"
"github.com/daviddengcn/go-colortext"
)
var logo = [...]string{
` ____ ______ `,
` / __ \ / ____/_ _____ _____`,
` / / / /_____/ __/ / / / / _ \/ ___/`,
` / /_/ /_____/ /___/ /_/ / __(__ ) `,
`/_____/ /_____/\__, /\___/____/ `,
` /____/ `,
}
func ShowLogo() {
ct.Foreground(ct.Blue, true)
fmt.Println(logo[0])
fmt.Println(logo[1])
ct.ResetColor()
ct.Foreground(ct.Blue, true)
fmt.Println(logo[2])
ct.Foreground(ct.Magenta, true)
fmt.Println(logo[3])
ct.ResetColor()
ct.Foreground(ct.Magenta, true)
fmt.Println(logo[4])
ct.ResetColor()
ct.Foreground(ct.Magenta, true)
fmt.Println(logo[5])
ct.ResetColor()
ct.Foreground(ct.Blue, true)
fmt.Println(" ———The Eyes of Darkness from Nsfocus spy on everything")
ct.ResetColor()
fmt.Println()
}

60
logo/logo_windows.go Normal file
View File

@@ -0,0 +1,60 @@
package logo
import (
"fmt"
"github.com/daviddengcn/go-colortext"
)
var logo = [...]string{
` ____ ______ `,
` / __ \ / ____/_ _____ _____`,
` / / / /_____/ __/ / / / / _ \/ ___/`,
` / /_/ /_____/ /___/ /_/ / __(__ ) `,
`/_____/ /_____/\__, /\___/____/ `,
` /____/ `,
}
func ShowLogo() {
ct.Foreground(ct.Blue, true)
fmt.Println(logo[0])
fmt.Println(logo[1])
ct.ResetColor()
ct.Foreground(ct.Blue, true)
fmt.Println(logo[2])
ct.Foreground(ct.Magenta, true)
fmt.Println(logo[3])
ct.ResetColor()
ct.Foreground(ct.Magenta, true)
fmt.Println(logo[4])
ct.ResetColor()
ct.Foreground(ct.Magenta, true)
fmt.Println(logo[5])
ct.ResetColor()
ct.Foreground(ct.Blue, true)
fmt.Println(" ———The Eyes of Darkness from Nsfocus spy on everything")
ct.ResetColor()
fmt.Println()
}
func Usage() {
usage := `Usage: D-Eyes.exe filescan/processcan/info [other arguments...]
-info string
Basic information options: host, users, netstat, task, autoruns, summary.(For 'basicInfo' function)
-path string
The filepath where you want to scan. Such as C:// (windows) or / (linux).(For 'filescan' function)
-pid int
The pid of process you want to scan. (optional) (Only For processcan.'-1' means all processes.) (default -1)
-rule string
The rule you want to scan with. (optional)
-thread int
The default thread is 5. (optional) (Only For filescan) (default 5)`
fmt.Print(usage)
}

6
output/result.go Normal file
View File

@@ -0,0 +1,6 @@
package output
type Result struct {
Risk string
RiskPath string
}

View File

@@ -0,0 +1,50 @@
package controller
import (
"github.com/gookit/color"
"github.com/shirou/gopsutil/v3/process"
"d-eyes/process/models"
"d-eyes/process/scanner"
"d-eyes/process/utils"
)
func GetProcess() models.Process {
ps, err := process.Processes()
if err != nil {
return models.Process{}
}
return models.Process{Process: ps}
}
func ScanProcess(pid int, rule string) {
var scannerEngine *scanner.Scanner
var err error
if rule == "" {
scannerEngine, err = scanner.NewScannerAllRules()
} else {
rulePath := "yaraRules\\" + rule + ".yar"
scannerEngine, err = scanner.NewScanner(rulePath)
if err != nil {
color.Redln(err.Error())
return
}
}
ipList, err := utils.ReadLindIp("ip.config")
Npattern := []string{"ms-msdt:/id\\s+PCWDiagnostic\\s+/skip force\\s+/param"}
if err == nil {
scanResults, err := scannerEngine.ScanProcesses(pid, ipList, Npattern)
if err == nil {
models.SaveProcessResult(scanResults)
} else {
color.Redln(err.Error())
}
} else {
color.Redln(err.Error())
return
}
//scannerEngine.Rules.Destroy()
}

View File

@@ -0,0 +1,51 @@
package controller
import (
"github.com/gookit/color"
"github.com/shirou/gopsutil/v3/process"
"d-eyes/process/models"
"d-eyes/process/scanner"
"d-eyes/process/utils"
)
func GetProcess() models.Process {
ps, err := process.Processes()
if err != nil {
return models.Process{}
}
return models.Process{Process: ps}
}
func ScanProcess(pid int, rule string, src_path string) {
var scannerEngine *scanner.Scanner
var err error
if rule == "" {
scannerEngine, err = scanner.NewScannerAllRules(src_path)
} else {
rulePath := src_path + "yaraRules\\" + rule + ".yar"
scannerEngine, err = scanner.NewScanner(rulePath)
if err != nil {
color.Redln(err.Error())
return
}
}
ipList, err := utils.ReadLindIp(src_path + "ip.config")
Npattern := []string{"ms-msdt:/id\\s+PCWDiagnostic\\s+/skip force\\s+/param"}
if err == nil {
err, scanResults := scannerEngine.ScanProcesses(pid, ipList, Npattern)
if err == nil {
models.SaveProcessResult(scanResults)
} else {
color.Redln(err.Error())
}
} else {
color.Redln(err.Error())
return
}
// todo
//scannerEngine.Rules.Destroy()
}

View File

@@ -0,0 +1,216 @@
package models
import (
"encoding/json"
"fmt"
"io/ioutil"
"strings"
"github.com/gookit/color"
"github.com/hillu/go-yara/v4"
"github.com/shirou/gopsutil/v3/net"
"github.com/shirou/gopsutil/v3/process"
)
type (
Process struct {
Process []*process.Process
}
ProcessScanResult struct {
//Pid int
CheckIP bool
Connection []string
Ps *process.Process
PidMatches []yara.MatchRule
PathMatches []yara.MatchRule
CheckArgs bool
Args string
}
ProcessResult struct {
Pid int
Path string
Namespace string
Rule string
Description string
}
)
func SaveProcessResult(results []*ProcessScanResult) {
red := color.FgRed.Render
green := color.FgGreen.Render
riskSum := 0
color.Warn.Println("\nD-Eyes Detection Result : \n")
for _, psr := range results {
lenPidMatches := len(psr.PidMatches)
lenPathMatches := len(psr.PathMatches)
psrPath, _ := psr.Ps.Exe()
if lenPidMatches != 0 && lenPathMatches != 0 {
riskSum++
data1 := psr.PidMatches[0].Metas[0]
dataType1, _ := json.Marshal(data1)
dataString1 := string(dataType1)
meta1 := strings.Split(dataString1, ":")[2]
metaTmp1 := strings.Trim(meta1, "\"}")
data2 := psr.PathMatches[0].Metas[0]
dataType2, _ := json.Marshal(data2)
dataString2 := string(dataType2)
met2a := strings.Split(dataString2, ":")[2]
metaTmp2 := strings.Trim(met2a, "\"}")
color.Error.Println("[ Risk ", riskSum, " ]")
fmt.Printf(
"[pid]:%d [%s]:%s | [path]:%s [%s]:%s | ",
psr.Ps.Pid, red("status"), red(metaTmp1), psrPath, red("status"),
red(metaTmp2),
)
if psr.CheckArgs {
fmt.Printf("[args]:%s | ", red(psr.Args))
} else {
fmt.Printf("[args]:%s | ", green(psr.Args))
}
if len(psr.Connection) == 0 {
fmt.Println("[network]:", green("null"))
} else {
fmt.Println("[network]:", psr.Connection)
}
continue
}
if lenPidMatches != 0 && lenPathMatches == 0 {
riskSum++
data := psr.PidMatches[0].Metas[0]
dataType, _ := json.Marshal(data)
dataString := string(dataType)
meta := strings.Split(dataString, ":")[2]
metaTmp := strings.Trim(meta, "\"}")
color.Error.Println("[ Risk ", riskSum, " ]")
fmt.Printf(
"[pid]:%d [%s]:%s | [path]:%s [%s]:%s | ",
psr.Ps.Pid, red("status"), red(metaTmp), psrPath, green("status"), green("safe"),
)
if psr.CheckArgs {
fmt.Printf("[args]:%s | ", red(psr.Args))
} else {
fmt.Printf("[args]:%s | ", green(psr.Args))
}
if len(psr.Connection) == 0 {
fmt.Println("[network]:", green("null"))
} else {
fmt.Println("[network]:", psr.Connection)
}
continue
}
if lenPidMatches == 0 && lenPathMatches != 0 {
riskSum++
data := psr.PathMatches[0].Metas[0]
dataType, _ := json.Marshal(data)
dataString := string(dataType)
meta := strings.Split(dataString, ":")[2]
metaTmp := strings.Trim(meta, "\"}")
color.Error.Println("[ Risk ", riskSum, " ]")
fmt.Printf(
"[pid]:%d [%s]:%s | [path]:%s [%s]:%s | ",
psr.Ps.Pid, green("status"), green("safe"), psrPath, red("status"), red(metaTmp),
)
if psr.CheckArgs {
fmt.Printf("[args]:%s | ", red(psr.Args))
} else {
fmt.Printf("[args]:%s | ", green(psr.Args))
}
if len(psr.Connection) == 0 {
fmt.Println("[network]:", green("null"))
} else {
fmt.Println("[network]:", psr.Connection)
}
continue
}
if psr.CheckIP {
riskSum++
color.Error.Println("[ Risk ", riskSum, " ]")
fmt.Printf(
"[pid]:%d [%s]:%s | [path]:%s [%s]:%s | ",
psr.Ps.Pid, green("status"), green("safe"), psrPath, green("status"), green("safe"),
)
if psr.CheckArgs {
fmt.Printf("[args]:%s | ", red(psr.Args))
} else {
fmt.Printf("[args]:%s | ", green(psr.Args))
}
fmt.Println("[network]:", psr.Connection)
continue
}
if psr.CheckArgs {
riskSum++
color.Error.Println("[ Risk ", riskSum, " ]")
fmt.Printf(
"[pid]:%d [%s]:%s | [path]:%s [%s]:%s | ",
psr.Ps.Pid, green("status"), green("safe"), psrPath, green("status"), green("safe"),
)
fmt.Printf("[args]:%s | ", red(psr.Args))
if len(psr.Connection) == 0 {
fmt.Println("[network]:", green("null"))
} else {
fmt.Println("[network]:", psr.Connection)
}
}
}
if riskSum == 0 {
fmt.Println("\nNo suspicious process found. Your computer is safe with the rules you choose.")
}
}
func DisplayNetworkInfo(connects []net.ConnectionStat) {
green := color.FgGreen.Render
blue := color.FgBlue.Render
red := color.FgRed.Render
if len(connects) == 0 {
fmt.Println("[network]:", green("null"))
return
}
ipf, _ := ioutil.TempFile("", "hostip")
//defer os.Remove(ipf.Name())
connection := make([]string, 0)
for _, conn := range connects {
if conn.Family == 1 {
continue
}
raddrip := red(conn.Raddr.IP)
c := fmt.Sprintf(
"%v:%v<->%v:%v(%v)",
blue(conn.Laddr.IP), blue(conn.Laddr.Port), raddrip, blue(conn.Raddr.Port), blue(conn.Status),
)
connection = append(connection, c)
ipf.Write([]byte(raddrip))
}
ipf.Close()
fmt.Println("[network]:", connection)
}

View File

@@ -0,0 +1,214 @@
package models
import (
"encoding/json"
"fmt"
"io/ioutil"
"strings"
"github.com/gookit/color"
"github.com/hillu/go-yara/v4"
"github.com/shirou/gopsutil/v3/net"
"github.com/shirou/gopsutil/v3/process"
)
type (
Process struct {
Process []*process.Process
}
ProcessScanResult struct {
CheckIP bool
Connection []string
Ps *process.Process
PidMatches yara.MatchRules
PathMatches yara.MatchRules
CheckArgs bool
Args string
}
ProcessResult struct {
Pid int
Path string
Namespace string
Rule string
Description string
}
)
func SaveProcessResult(results []*ProcessScanResult) {
red := color.FgRed.Render
green := color.FgGreen.Render
riskSum := 0
color.Warn.Println("\nD-Eyes Detection Result : \n")
for _, psr := range results {
lenPidMatches := len(psr.PidMatches)
lenPathMatches := len(psr.PathMatches)
psrPath, _ := psr.Ps.Exe()
if lenPidMatches != 0 && lenPathMatches != 0 {
riskSum++
data1 := psr.PidMatches[0].Metas[0]
dataType1, _ := json.Marshal(data1)
dataString1 := string(dataType1)
meta1 := strings.Split(dataString1, ":")[2]
metaTmp1 := strings.Trim(meta1, "\"}")
data2 := psr.PathMatches[0].Metas[0]
dataType2, _ := json.Marshal(data2)
dataString2 := string(dataType2)
met2a := strings.Split(dataString2, ":")[2]
metaTmp2 := strings.Trim(met2a, "\"}")
color.Error.Println("[ Risk ", riskSum, " ]")
fmt.Printf(
"[pid]:%d [%s]:%s | [path]:%s [%s]:%s | ",
psr.Ps.Pid, red("status"), red(metaTmp1), psrPath, red("status"),
red(metaTmp2),
)
if psr.CheckArgs {
fmt.Printf("[args]:%s | ", red(psr.Args))
} else {
fmt.Printf("[args]:%s | ", green(psr.Args))
}
if len(psr.Connection) == 0 {
fmt.Println("[network]:", green("null"))
} else {
fmt.Println("[network]:", psr.Connection)
}
continue
}
if lenPidMatches != 0 && lenPathMatches == 0 {
riskSum++
data := psr.PidMatches[0].Metas[0]
dataType, _ := json.Marshal(data)
dataString := string(dataType)
meta := strings.Split(dataString, ":")[2]
metaTmp := strings.Trim(meta, "\"}")
color.Error.Println("[ Risk ", riskSum, " ]")
fmt.Printf(
"[pid]:%d [%s]:%s | [path]:%s [%s]:%s | ",
psr.Ps.Pid, red("status"), red(metaTmp), psrPath, green("status"), green("safe"),
)
if psr.CheckArgs {
fmt.Printf("[args]:%s | ", red(psr.Args))
} else {
fmt.Printf("[args]:%s | ", green(psr.Args))
}
if len(psr.Connection) == 0 {
fmt.Println("[network]:", green("null"))
} else {
fmt.Println("[network]:", psr.Connection)
}
continue
}
if lenPidMatches == 0 && lenPathMatches != 0 {
riskSum++
data := psr.PathMatches[0].Metas[0]
dataType, _ := json.Marshal(data)
dataString := string(dataType)
meta := strings.Split(dataString, ":")[2]
metaTmp := strings.Trim(meta, "\"}")
color.Error.Println("[ Risk ", riskSum, " ]")
fmt.Printf(
"[pid]:%d [%s]:%s | [path]:%s [%s]:%s | ",
psr.Ps.Pid, green("status"), green("safe"), psrPath, red("status"), red(metaTmp),
)
if psr.CheckArgs {
fmt.Printf("[args]:%s | ", red(psr.Args))
} else {
fmt.Printf("[args]:%s | ", green(psr.Args))
}
if len(psr.Connection) == 0 {
fmt.Println("[network]:", green("null"))
} else {
fmt.Println("[network]:", psr.Connection)
}
continue
}
if psr.CheckIP {
riskSum++
color.Error.Println("[ Risk ", riskSum, " ]")
fmt.Printf(
"[pid]:%d [%s]:%s | [path]:%s [%s]:%s | ",
psr.Ps.Pid, green("status"), green("safe"), psrPath, green("status"), green("safe"),
)
if psr.CheckArgs {
fmt.Printf("[args]:%s | ", red(psr.Args))
} else {
fmt.Printf("[args]:%s | ", green(psr.Args))
}
fmt.Println("[network]:", psr.Connection)
continue
}
if psr.CheckArgs {
riskSum++
color.Error.Println("[ Risk ", riskSum, " ]")
fmt.Printf(
"[pid]:%d [%s]:%s | [path]:%s [%s]:%s | ",
psr.Ps.Pid, green("status"), green("safe"), psrPath, green("status"), green("safe"),
)
fmt.Printf("[args]:%s | ", red(psr.Args))
if len(psr.Connection) == 0 {
fmt.Println("[network]:", green("null"))
} else {
fmt.Println("[network]:", psr.Connection)
}
}
}
if riskSum == 0 {
fmt.Println("\nNo suspicious process found. Your computer is safe with the rules you choose.")
}
}
func DisplayNetworkInfo(connects []net.ConnectionStat) {
green := color.FgGreen.Render
blue := color.FgBlue.Render
red := color.FgRed.Render
if len(connects) == 0 {
fmt.Println("[network]:", green("null"))
return
}
ipf, _ := ioutil.TempFile("", "hostip")
connection := make([]string, 0)
for _, conn := range connects {
if conn.Family == 1 {
continue
}
raddrip := red(conn.Raddr.IP)
c := fmt.Sprintf(
"%v:%v<->%v:%v(%v)",
blue(conn.Laddr.IP), blue(conn.Laddr.Port), raddrip, blue(conn.Raddr.Port), blue(conn.Status),
)
connection = append(connection, c)
ipf.Write([]byte(raddrip))
}
ipf.Close()
fmt.Println("[network]:", connection)
}

View File

@@ -0,0 +1,298 @@
package scanner
import (
"encoding/json"
"fmt"
"os"
"strings"
"sync"
"github.com/gookit/color"
"github.com/hillu/go-yara/v4"
"github.com/shirou/gopsutil/v3/process"
"github.com/toolkits/slice"
"d-eyes/process/models"
"d-eyes/process/utils"
"d-eyes/yaraobj"
)
var resultListTMP []*models.ProcessScanResult
type Scanner struct {
Rules *yara.Rules
}
type (
Process struct {
Process []*process.Process
}
)
func (i Process) Iterator() *Iterator {
return &Iterator{
data: i,
index: 0,
}
}
type Iterator struct {
data Process
index int
}
func (i *Iterator) HasNext() bool {
return i.index < len(i.data.Process)
}
func (i *Iterator) Next() *process.Process {
pro := i.data.Process[i.index]
i.index++
return pro
}
// Open the rule file and add it to the Yara compiler.
func NewScanner(rulepath string) (*Scanner, error) {
f, err := os.ReadFile(rulepath)
if err != nil {
color.Redln("GetErr: Can't open the rule file: ", rulepath)
os.Exit(1)
return nil, err
}
compiler, err := yara.NewCompiler()
if err != nil {
return nil, err
}
err = compiler.AddString(string(f), "")
if err != nil {
return nil, err
}
rules, err := compiler.GetRules()
if err != nil {
return nil, err
}
return &Scanner{Rules: rules}, err
}
func NewScannerAllRules() (*Scanner, error) {
rulesPath := "yaraRules"
_, err := os.Stat(rulesPath)
if os.IsNotExist(err) {
color.Redln("GetErr: The './yaraRules' directory does not exist.")
os.Exit(1)
}
rules, err := yaraobj.LoadAllYaraRules(rulesPath)
if err != nil {
color.Redln("LoadCompiledRules goes error !!!")
color.Redln("GetRules err: ", err)
os.Exit(1)
}
return &Scanner{Rules: rules}, err
}
func (s *Scanner) ScanProcesses(pid int, ipList []string, Npattern []string) ([]*models.ProcessScanResult, error) {
whiteList := []string{"ruby", "sagent", "crond", "mysqld", "rsyslogd"}
var resultList []*models.ProcessScanResult
if pid != -1 {
var pidMatches yara.MatchRules
var pathMatches yara.MatchRules
err := s.Rules.ScanProc(pid, 0, 10, &pidMatches)
if err != nil {
return nil, fmt.Errorf("pid: %d is not exist! (%s)", pid, err)
}
ps, _ := process.NewProcess(int32(pid))
path, _ := ps.Exe()
err = s.Rules.ScanFile(path, 0, 10, &pathMatches)
if err != nil {
return nil, fmt.Errorf("ScanFile err: %s", err)
}
var checkarg bool
var args string
// todo
//for _, i := range Npattern {
// reg := regexp.MustCompile(i)
// if reg.FindString(ps.Arguments) != "" {
// checkarg = true
// args = ps.Arguments
// } else {
// checkarg = false
// args = "safe"
// }
//}
connection, ok := DisplayScanResult(ps, pidMatches, pathMatches, ipList)
resultList = append(
resultList, &models.ProcessScanResult{
CheckIP: ok, Connection: connection,
Ps: ps, PidMatches: pidMatches, PathMatches: pathMatches, CheckArgs: checkarg, Args: args,
},
)
return resultList, nil
}
ps, err := process.Processes()
if err != nil {
return nil, err
}
pss := Process{Process: ps}
it := pss.Iterator()
wg := &sync.WaitGroup{}
wg.Add(5)
for i := 0; i < 5; i++ {
go s.ProScan(it, wg, whiteList, ipList, Npattern)
}
wg.Wait()
resultList = resultListTMP
return resultList, nil
}
func (s *Scanner) ProScan(it *Iterator, wg *sync.WaitGroup, whiteList []string, ipList []string, Npattern []string) {
defer wg.Done()
for {
var err error
if it.HasNext() {
ps := it.Next()
var pidMatches yara.MatchRules
var pathMatches yara.MatchRules
pid := os.Getpid()
if pid == int(ps.Pid) {
continue
}
_psPath, _ := ps.Exe()
t := strings.Split(_psPath, "/")
filename := t[len(t)-1]
if !slice.ContainsString(whiteList, filename) {
err = s.Rules.ScanProc(int(ps.Pid), 0, 10, &pidMatches)
if err != nil {
err = nil
continue
}
err = s.Rules.ScanFile(_psPath, 0, 10, &pathMatches)
if err != nil {
err = nil
continue
}
var checkarg bool
var args string
// todo
//for _, i := range Npattern {
// reg := regexp.MustCompile(i)
// if reg.FindString(ps.Arguments) != "" {
// checkarg = true
// args = ps.Arguments
// } else {
// checkarg = false
// args = "safe"
// }
//}
connection, ok := DisplayScanResult(ps, pidMatches, pathMatches, ipList)
resultListTMP = append(
resultListTMP, &models.ProcessScanResult{
CheckIP: ok, Connection: connection,
Ps: ps, PidMatches: pidMatches, PathMatches: pathMatches, CheckArgs: checkarg, Args: args,
},
)
}
} else {
break
}
}
}
func DisplayScanResult(ps *process.Process, pidMatches yara.MatchRules, pathMatches yara.MatchRules, ipList []string) ([]string, bool) {
var pid_matches string
var path_matches string
var pid_rules string
var path_rules string
var ipexist bool
red := color.FgRed.Render
green := color.FgGreen.Render
blue := color.FgBlue.Render
color.Info.Printf("D-Eyes progress scanning: ")
if len(pidMatches) == 0 {
pid_matches = green("status")
pid_rules = green("safe")
} else {
pid_matches = red("status")
data := pidMatches[0].Metas[0]
dataType, _ := json.Marshal(data)
dataString := string(dataType)
meta := strings.Split(dataString, ":")[2]
metaTmp := strings.Trim(meta, "\"}")
pid_rules = red(metaTmp)
}
if len(pathMatches) == 0 {
path_matches = green("status")
path_rules = green("safe")
} else {
path_matches = red("status")
data := pathMatches[0].Metas[0]
dataType, _ := json.Marshal(data)
dataString := string(dataType)
meta := strings.Split(dataString, ":")[2]
metaTmp := strings.Trim(meta, "\"}")
path_rules = red(metaTmp)
}
_pUname, _ := ps.Username()
_exe, _ := ps.Exe()
fmt.Printf(
"[username]:%s | [pid]:%d [%s]:%s | [path]:%s [%s]:%s | ",
_pUname, ps.Pid, pid_matches, pid_rules, _exe, path_matches, path_rules,
)
// 显示网络连接信息
connection := make([]string, 0)
_psConn, _ := ps.Connections()
for _, conn := range _psConn {
if conn.Family == 1 {
continue
}
ok := utils.CheckIpInipconfig(ipList, conn.Raddr.IP)
if !ok {
c := fmt.Sprintf(
"%v:%v<->%v:%v(%v)",
conn.Laddr.IP, conn.Laddr.Port, conn.Raddr.IP, conn.Raddr.Port, conn.Status,
)
connection = append(connection, blue(c))
} else {
c := fmt.Sprintf(
"%v:%v<->%v:%v(%v)",
blue(conn.Laddr.IP), blue(conn.Laddr.Port), red(conn.Raddr.IP), blue(conn.Raddr.Port), blue(conn.Status),
)
connection = append(connection, c)
ipexist = true
}
}
if len(connection) == 0 {
fmt.Println("[network]:", green("null"))
} else {
fmt.Println("[network]:", connection)
}
return connection, ipexist
}

View File

@@ -0,0 +1,309 @@
package scanner
import (
"encoding/json"
"fmt"
"os"
"strings"
"sync"
"github.com/gookit/color"
"github.com/hillu/go-yara/v4"
"github.com/shirou/gopsutil/v3/process"
"github.com/toolkits/slice"
"d-eyes/process/models"
"d-eyes/process/utils"
"d-eyes/yaraobj"
)
var resultListTMP []*models.ProcessScanResult
type Scanner struct {
Rules *yara.Rules
}
type (
Process struct {
Process []*process.Process
}
)
func (i Process) Iterator() *Iterator {
return &Iterator{
data: i,
index: 0,
}
}
type Iterator struct {
data Process
index int
}
func (i *Iterator) HasNext() bool {
return i.index < len(i.data.Process)
}
func (i *Iterator) Next() *process.Process {
pro := i.data.Process[i.index]
i.index++
return pro
}
// Open the rule file and add it to the Yara compiler.
func NewScanner(rulepath string) (*Scanner, error) {
f, err := os.ReadFile(rulepath)
if err != nil {
color.Redln("GetErr: Can't open the rule file: ", rulepath)
os.Exit(1)
return nil, err
}
compiler, err := yara.NewCompiler()
if err != nil {
return nil, err
}
err = compiler.AddString(string(f), "")
if err != nil {
return nil, err
}
rules, err := compiler.GetRules()
if err != nil {
return nil, err
}
return &Scanner{Rules: rules}, err
}
func NewScannerAllRules(src_path string) (*Scanner, error) {
rulesPath := src_path + "yaraRules"
_, err := os.Stat(rulesPath)
if os.IsNotExist(err) {
color.Redln("GetErr: The './yaraRules' directory does not exist.")
os.Exit(1)
}
rules, err := yaraobj.LoadAllYaraRules(rulesPath)
if err != nil {
color.Redln("LoadCompiledRules goes error !!!")
color.Redln("GetRules err: ", err)
os.Exit(1)
}
return &Scanner{Rules: rules}, err
}
func (s *Scanner) ScanProcesses(pid int, ipList []string, Npattern []string) ([]*models.ProcessScanResult, error) {
whiteList := []string{"ruby", "sagent", "crond", "mysqld", "rsyslogd"}
var resultList []*models.ProcessScanResult
if pid != -1 {
var pidMatches yara.MatchRules
var pathMatches yara.MatchRules
err := s.Rules.ScanProc(pid, 0, 10, &pidMatches)
if err != nil {
return nil, fmt.Errorf("pid: %d is not exist! (%s)", pid, err)
}
ps, _ := process.NewProcess(int32(pid))
_psPath, _ := ps.Exe()
f, err := os.Open(_psPath)
if err != nil {
return fmt.Errorf("ScanFile err: %s", err), nil
}
defer f.Close()
err = s.Rules.ScanFileDescriptor(f.Fd(), 0, 10, &pathMatches)
if err != nil {
return fmt.Errorf("ScanFile err: %s", err), nil
}
var checkarg bool
var args string
// todo
//for _, i := range Npattern {
// reg := regexp.MustCompile(i)
// if reg.FindString(ps.Arguments) != "" {
// checkarg = true
// args = ps.Arguments
// } else {
// checkarg = false
// args = "safe"
// }
//}
connection, ok := DisplayScanResult(ps, pidMatches, pathMatches, ipList)
resultList = append(
resultList, &models.ProcessScanResult{
CheckIP: ok, Connection: connection,
Ps: ps, PidMatches: pidMatches, PathMatches: pathMatches, CheckArgs: checkarg, Args: args,
},
)
return resultList, nil
}
ps, err := process.Processes()
if err != nil {
return nil, err
}
pss := Process{Process: ps}
it := pss.Iterator()
wg := &sync.WaitGroup{}
wg.Add(5)
for i := 0; i < 5; i++ {
go s.ProScan(it, wg, whiteList, ipList, Npattern)
}
wg.Wait()
resultList = resultListTMP
return resultList, nil
}
func (s *Scanner) ProScan(it *Iterator, wg *sync.WaitGroup, whiteList []string, ipList []string, Npattern []string) {
defer wg.Done()
for {
var err error
if it.HasNext() {
ps := it.Next()
var pidMatches yara.MatchRules
var pathMatches yara.MatchRules
pid := os.Getpid()
if pid == int(ps.Pid) {
continue
}
_psPath, _ := ps.Exe()
t := strings.Split(_psPath, "/")
filename := t[len(t)-1]
if !slice.ContainsString(whiteList, filename) {
err = s.Rules.ScanProc(int(ps.Pid), 0, 10, &pidMatches)
if err != nil {
err = nil
continue
}
f, err := os.Open(_psPath)
if err != nil {
continue
}
defer f.Close()
err = s.Rules.ScanFileDescriptor(f.Fd(), 0, 10, &pathMatches)
if err != nil {
err = nil
continue
}
var checkarg bool
var args string
// todo
//for _, i := range Npattern {
// reg := regexp.MustCompile(i)
// if reg.FindString(ps.Arguments) != "" {
// checkarg = true
// args = ps.Arguments
// } else {
// checkarg = false
// args = "safe"
// }
//}
connection, ok := DisplayScanResult(ps, pidMatches, pathMatches, ipList)
resultListTMP = append(
resultListTMP, &models.ProcessScanResult{
CheckIP: ok, Connection: connection,
Ps: ps, PidMatches: pidMatches, PathMatches: pathMatches, CheckArgs: checkarg, Args: args,
},
)
}
} else {
break
}
}
}
func DisplayScanResult(ps *process.Process, pidMatches yara.MatchRules, pathMatches yara.MatchRules, ipList []string) ([]string, bool) {
var pid_matches string
var path_matches string
var pid_rules string
var path_rules string
var ipexist bool
red := color.FgRed.Render
green := color.FgGreen.Render
blue := color.FgBlue.Render
color.Info.Printf("D-Eyes progress scanning: ")
if len(pidMatches) == 0 {
pid_matches = green("status")
pid_rules = green("safe")
} else {
pid_matches = red("status")
data := pidMatches[0].Metas[0]
dataType, _ := json.Marshal(data)
dataString := string(dataType)
meta := strings.Split(dataString, ":")[2]
metaTmp := strings.Trim(meta, "\"}")
pid_rules = red(metaTmp)
}
if len(pathMatches) == 0 {
path_matches = green("status")
path_rules = green("safe")
} else {
path_matches = red("status")
data := pathMatches[0].Metas[0]
dataType, _ := json.Marshal(data)
dataString := string(dataType)
meta := strings.Split(dataString, ":")[2]
metaTmp := strings.Trim(meta, "\"}")
path_rules = red(metaTmp)
}
_pUname, _ := ps.Username()
_exe, _ := ps.Exe()
fmt.Printf(
"[username]:%s | [pid]:%d [%s]:%s | [path]:%s [%s]:%s | ",
_pUname, ps.Pid, pid_matches, pid_rules, _exe, path_matches, path_rules,
)
// 显示网络连接信息
connection := make([]string, 0)
_psConn, _ := ps.Connections()
for _, conn := range _psConn {
if conn.Family == 1 {
continue
}
ok := utils.CheckIpInipconfig(ipList, conn.Raddr.IP)
if !ok {
c := fmt.Sprintf(
"%v:%v<->%v:%v(%v)",
conn.Laddr.IP, conn.Laddr.Port, conn.Raddr.IP, conn.Raddr.Port, conn.Status,
)
connection = append(connection, blue(c))
} else {
c := fmt.Sprintf(
"%v:%v<->%v:%v(%v)",
blue(conn.Laddr.IP), blue(conn.Laddr.Port), red(conn.Raddr.IP), blue(conn.Raddr.Port), blue(conn.Status),
)
connection = append(connection, c)
ipexist = true
}
}
if len(connection) == 0 {
fmt.Println("[network]:", green("null"))
} else {
fmt.Println("[network]:", connection)
}
return connection, ipexist
}

27
process/utils/iputil.go Normal file
View File

@@ -0,0 +1,27 @@
package utils
import (
"math/big"
"net"
)
type IntIP struct {
IP string
Intip int64
}
func (i *IntIP) toIntIp() int64 {
ret := big.NewInt(0)
ret.SetBytes(net.ParseIP(i.IP).To4())
return ret.Int64()
}
func CheckIpInipconfig(ipList []string, ip string) bool {
for _, hip := range ipList {
if hip == ip {
return true
}
}
return false
}

29
process/utils/readfile.go Normal file
View File

@@ -0,0 +1,29 @@
package utils
import (
"bufio"
"os"
"strings"
)
func ReadLindIp(fileName string) ([]string, error) {
f, err := os.Open(fileName)
if err != nil {
return nil, err
}
buf := bufio.NewScanner(f)
var result []string
for {
if !buf.Scan() {
break
}
line := buf.Text()
line = strings.TrimSpace(line)
result = append(result, line)
}
return result, nil
}

View File

@@ -0,0 +1,53 @@
import "hash"
rule blackmoon_hash
{
meta:
description ="Detect the risk of Malware blackmoon Rule 1"
condition:
hash.md5(0,filesize) =="22E46CBCF02D78390D257AEE0FE26EDE" or
hash.md5(0,filesize) =="65982DEB6AC30B9F1F4DAB1AA26A0D0E" or
hash.md5(0,filesize) =="C4A73F3BBDD1E64EF146A232967B1BC5" or
hash.md5(0,filesize) =="93EB67FDB2D0C767887C6F6284844386" or
hash.md5(0,filesize) =="F73436646F905504027809A461D0A8D9" or
hash.md5(0,filesize) =="63EC62319605B43D68EB25B9F84153C8" or
hash.sha256(0,filesize) =="25f87c65a793186c7a9e1d8680ad7f32acb9bae4cb7284b98781b3a15f810ba2" or
hash.sha256(0,filesize) =="a57980012b38dc89baab954e7da3fa7112dd52b2252a72f87ec2510a70d2ade7"
}
rule BLACKMOON_BANKER {
meta:
description ="Detect the risk of Malware blackmoon Rule 2"
detail = "blackmoon update"
strings:
$s1 = "BlackMoon RunTime Error:" nocase wide ascii
$s2 = "\\system32\\rundll32.exe" wide ascii
$s3 = "cmd.exe /c ipconfig /flushdns" wide ascii
$s4 = "\\system32\\drivers\\etc\\hosts.ics" wide ascii
condition:
all of them
}
rule BlackMoon_2022
{
meta:
description ="Detect the risk of Malware blackmoon Rule 3"
strings:
$s1 = "kongxin1123"
$s2 = "m27p.com"
$s3 = "jincpay.com"
$s4 = "xiaoniu321.com"
condition:
hash.md5(0,filesize) == "22e46cbcf02d78390d257aee0fe26ede" or
hash.md5(0,filesize) == "65982deb6ac30b9f1f4dab1aa26a0d0e" or
hash.md5(0,filesize) == "93eb67fdb2d0c767887c6f6284844386" or
hash.md5(0,filesize) == "c4a73f3bbdd1e64ef146a232967b1bc5" or
hash.md5(0,filesize) == "f73436646f905504027809a461d0a8d9" or
hash.md5(0,filesize) == "63ec62319605b43d68eb25b9f84153c8" or
hash.md5(0,filesize) == "37C030456818878AF1DC8CE7928A504F" or
$s1 or
$s2 or
$s3 or
$s4
}

View File

@@ -0,0 +1,11 @@
rule festi_botnet_pdb {
meta:
description = "Detect the risk of Botnet Malware Festi Rule 1"
hash = "e55913523f5ae67593681ecb28d0fa1accee6739fdc3d52860615e1bc70dcb99"
strings:
$pdb = "\\eclipse\\botnet\\drivers\\Bin\\i386\\kernel.pdb"
condition:
uint16(0) == 0x5a4d and
filesize < 80KB and
any of them
}

272
yaraRules/Botnet.Gafgyt.yar Normal file
View File

@@ -0,0 +1,272 @@
rule Gafgyt_Generic_Botnet {
meta:
description = "Detect the risk of Botnet Malware Gafgyt Rule 1"
hash0 = "2a18f2d59f172622e76d9d9b5c73393b"
hash1 = "06de2d19862494be7dbcbcf20b3dbe3a"
hash2 = "0fc30a802a07386f5cd4b18b47547979"
hash3 = "be6865ccb948f2937fd25fe465e434da"
hash4 = "c8d58acfe524a09d4df7ffbe4a43c429"
hash5 = "0f979b4ae1209020dd2b672f9dad7398"
hash6 = "45826c129bf3d3bd067e33cf7bef3883"
hash7 = "79b9d4cea7972951efad765406459f5e"
hash8 = "baad702930571c414b0e8896f8bb4a5f"
hash9 = "11754a20e705dccf96f1a1def7220efc"
hash10 = "67db9ed04d3b56f966a739fd40a47748"
strings:
$s0 = "busybox" fullword
$s1 = "PONG!" fullword
$s2 = "GETLOCALIP" fullword
$s3 = "HTTPFLOOD" fullword
$s4 = "LUCKYLILDUDE" fullword
$s5 = "/dev/null"
$s6 = "/etc/resolv.conf"
$s7 = "/etc/config/resolv.conf"
condition:
all of them
}
rule Gafgyt_July_1 {
meta:
description = "Detect the risk of Botnet Malware Gafgyt Rule 2"
hash1 = "041db2cf6eac2a47ae4651751158838104e502ff33dcc7f5dd48472789870e6c"
hash2 = "0839b33e2da179eac610673769e9568d1942877739cf4d990f3787672a4e9af1"
hash3 = "2a1c1a22ed6989e9ba86f9a192834e0a35afec8026e8ecc0bb5c958d2892d46c"
hash4 = "30b682ee7114bf68f881e641e9ab14c7d62c84f725e9cf5bfccb403aaa1fe8f7"
hash5 = "3b9a35f7a0698b24d214818efd22235c995f1460fc55dd3ebd923ff0dca5370c"
hash6 = "4110dd04db3932f1f03bdce6fa74f5298ffb429b816c7a8fce40f1cbb043e968"
hash7 = "471b4d64420bdf2c8749c390a142ed449aff23b0d67609b268be044657501fa7"
hash8 = "5a9f02031f0b3b1a2edaeae2d77b8c1f67de2b611449432c42c88f840d7a1d5c"
hash9 = "78d9488d688f3b12181b54df0e9da3770e90a4a42a13db001fd211d16645a1bb"
hash10 = "7f2aa6e5e1f1229fb18a15d1599a7a6014796cc7c08b26b9c4336a2048dc8928"
hash11 = "805917658c7761debdaf18e83b54ec4e9ba645950c773ddd21d6cd8ba29b32d6"
hash12 = "ae880c7dd79ebb1d626aea57152fdaa779d07d5b326d7f7fad1d42b637e5da84"
hash13 = "b0d36c18bf900988d01828202ce1ab77949b9a8a29b264ea1639f170a6c9825b"
hash14 = "c17bf892498ed1dce5db1b0f3d588774b8e82f2636f397b2456d15e7442781e6"
hash15 = "c27e328d2fe6fd75066938f58c3359c5dbb9deea166c6a4d3b0397d295a3e8d5"
hash16 = "df292a289d93136fbdd6ac0850b2c8845f967d9a9a3bd29a9386b39843b82eda"
hash17 = "e07a008aaf0a0a2666a705a9756da5bc54be18e2a53a50eb7539f1143548a57f"
hash18 = "0be1e96f318d98398861217a9754bc003e6861d84de8553cdbd87531db66e19b"
hash19 = "2d049876c256e55ae48a1060c32f8d75b691525cd877556172f163fe39466001"
hash20 = "3d8194b7853a1edbaa5d14b4b7a0323c5584b8a5c959efe830073e43d0b4418a"
hash21 = "576bce5c1d1143b0e532333a28d37c98d65b271d651dbce86360d3e80460733f"
hash22 = "b7c5895189c7f4e30984e2f0db703c2120909dccaa339e59795d3e732bca9340"
hash23 = "db23bf90a7f0c69c3501876243ca2fe29e9208864dfa6f2b5d0dac51061a3d86"
hash24 = "e1093d59bef8f260b0ca1ebe82c0635cc225e060b8d7296efe330ca7837e6d44"
hash25 = "e29d1c2cbd64d0f1433602f2b63cf40e33b4376ac613e911a2160b268496164d"
hash26 = "e6523f691d0b4a16cc1892ec4eb3ee113d62443317e337412b70e0cea3e106f7"
hash27 = "ec9387b582e5a935094c6d165741d2c989e72afc3c6063a29e96153e97a74af3"
hash28 = "ed2eaf4c44f83c7920b2d73cbe242b82cc92e3188d04b1bb8742783c49487da7"
strings:
$s1 = "/20x/x58/x4b/x49/x57/x44/x49/x4a/x22/x20/x22/x64/x39/x63/x39/x29/x4d/x20/x29/x57/x5f/x22/x21/x5f/x2b/x20/x51/x53/x4d/x45/x4d/x44" ascii
$s2 = "/73x/6ax/x4a/x4b/x4d/x44/x20/x44/x57/x29/x5f/x20/x44/x57/x49/x4f/x57/x20/x57/x4f/x4b/x3c/x20/x57/x44/x4b/x20/x44/x29/x5f/x41/" fullword ascii
$s3 = "/20x/x58/x4b/x49/x57/x44/x49/x4a/x22/x20/x22/x64/x39/x63/x39/x29/x4d/x20/x29/x57/x5f/x22/x21/x5f/x2b/x20/x51/x53/x4d/x45/x4d/x44" ascii
$s4 = "/x4d/x20/x29/x28/x28/x22/x29/x45/x4f/x4b/x58/x50/x7b/x20/x5f/x57/x44/x44/x57/x44/" fullword ascii
$s5 = "/x71/x3b/x38/x38/x20/x43/x57/x29/x57/x22/x29/x64/x32/x20/x4b/x58/x4b/x4b/x4c/x22/x44/x20/x2d/x44/x5f/" fullword ascii
$s6 = "UDPBYPASS" fullword ascii
$s7 = "Is a named type file" fullword ascii
$s8 = "Structure needs cleaning" fullword ascii
$s9 = "No XENIX semaphores available" fullword ascii
condition:
uint16(0) == 0x457f and filesize < 600KB and 5 of them
}
rule Gafgyt_July_6 {
meta:
description = "Detect the risk of Botnet Malware Gafgyt Rule 3"
author = "LightDefender"
date = "2021-07-06"
hash1 = "821d34f7978fc65fe3b570e86cce45edc921a6cbf02b127fb1263a8448a1f62a"
strings:
$s1 = "infected.log" fullword ascii
$s2 = "Samael-DDoS-Attack" fullword ascii
$s3 = "B0TK1LL" fullword ascii
$s4 = "This Device Has Been Infected by Samael Botnet Made By ur0a :)" ascii
condition:
uint16(0) == 0x457f and filesize < 600KB and 2 of them
}
rule elf_bashlite_auto {
meta:
description = "Detect the risk of Botnet Malware Gafgyt Rule 4"
strings:
$sequence_0 = { 21d0 3345fc c9 c3 55 }
// n = 5, score = 300
// 21d0 | mov dword ptr [ebp - 4], 0
// 3345fc | mov edi, 0x512c00
// c9 | inc esp
// c3 | mov edi, esp
// 55 | mov edi, 0x512c00
$sequence_1 = { e8???????? 89c2 89d0 c1e81f }
// n = 4, score = 300
// e8???????? |
// 89c2 | mov byte ptr [ebx], 0
// 89d0 | sub eax, edx
// c1e81f | cmp eax, dword ptr [esp + 0x7c]
$sequence_2 = { e8???????? 8945ec 837dec00 750b 8b45ec }
// n = 5, score = 300
// e8???????? |
// 8945ec | je 0xffffff7c
// 837dec00 | mov al, byte ptr [ebp - 0xf]
// 750b | cmp al, 0xc0
// 8b45ec | mov al, byte ptr [ebp - 0xd]
$sequence_3 = { f7d0 21d0 3345fc c9 }
// n = 4, score = 300
// f7d0 | mov ecx, eax
// 21d0 | dec eax
// 3345fc | mov edx, dword ptr [ebp - 0x40]
// c9 | mov edi, 0x800
$sequence_4 = { 750c e8???????? 8b00 83f804 }
// n = 4, score = 300
// 750c | cmp al, 0xfc
// e8???????? |
// 8b00 | jne 0x18a
// 83f804 | dec eax
$sequence_5 = { eb0a c785ecefffff00000000 8b85ecefffff c9 c3 }
// n = 5, score = 300
// eb0a | mov eax, dword ptr [eax]
// c785ecefffff00000000 | mov dword ptr [ebp - 0x108], eax
// 8b85ecefffff | mov dword ptr [ebp - 0x10c], 0x8056e9e
// c9 | mov dword ptr [ebp - 0x110], 5
// c3 | mov eax, dword ptr [ebp + 0xc]
$sequence_6 = { 8b85ecefffff c9 c3 55 }
// n = 4, score = 300
// 8b85ecefffff | add eax, 0x41
// c9 | mov byte ptr [ebx], al
// c3 | mov dword ptr [ebp - 0x1c], edx
// 55 | mov eax, dword ptr [ebp - 0x20]
$sequence_7 = { c1f802 89c2 89d0 01c0 01d0 }
// n = 5, score = 300
// c1f802 | mov dword ptr [ebp - 0x88], eax
// 89c2 | jmp 0x159
// 89d0 | mov dword ptr [esp], eax
// 01c0 | mov ecx, eax
// 01d0 | or ecx, 0x800
$sequence_8 = { 85c0 750c c785ecefffff01000000 eb0a c785ecefffff00000000 8b85ecefffff }
// n = 6, score = 300
// 85c0 | mov dword ptr [ebp - 0x4c], edx
// 750c | dec eax
// c785ecefffff01000000 | mov edi, dword ptr [ebp - 0x18]
// eb0a | mov ecx, dword ptr [ebp - 0x38]
// c785ecefffff00000000 | mov edx, dword ptr [ebp - 0x3c]
// 8b85ecefffff | add dword ptr [ebp - 0x34], eax
$sequence_9 = { 21d0 3345fc c9 c3 }
// n = 4, score = 300
// 21d0 | mov eax, dword ptr [ebp - 0x1c]
// 3345fc | mov word ptr [eax + 0xa], dx
// c9 | mov dword ptr [esp], 0
// c3 | movzx edx, ax
condition:
7 of them and filesize < 274018
}
rule Gafgyt_Botnet_generic : MALW
{
meta:
description = "Detect the risk of Botnet Malware Gafgyt Rule 5"
MD5 = "e3fac853203c3f1692af0101eaad87f1"
SHA1 = "710781e62d49419a3a73624f4a914b2ad1684c6a"
strings:
$etcTZ = "/bin/busybox;echo -e 'gayfgt'"
$s2 = "/proc/net/route"
$s3 = "admin"
$s4 = "root"
condition:
$etcTZ and $s2 and $s3 and $s4
}
rule Gafgyt_Botnet_oh : MALW
{
meta:
description = "Detect the risk of Botnet Malware Gafgyt Rule 6"
MD5 = "97f5edac312de349495cb4afd119d2a5"
SHA1 = "916a51f2139f11e8be6247418dca6c41591f4557"
strings:
$s1 = "busyboxterrorist"
$s2 = "BOGOMIPS"
$s3 = "124.105.97.%d"
$s4 = "fucknet"
condition:
$s1 and $s2 and $s3 and $s4
}
rule Gafgyt_Botnet_bash : MALW
{
meta:
description = "Detect the risk of Botnet Malware Gafgyt Rule 7"
MD5 = "c8d58acfe524a09d4df7ffbe4a43c429"
SHA1 = "b41fefa8470f3b3657594af18d2ea4f6ac4d567f"
strings:
$s1 = "PONG!"
$s2 = "GETLOCALIP"
$s3 = "HTTPFLOOD"
$s4 = "LUCKYLILDUDE"
condition:
$s1 and $s2 and $s3 and $s4
}
rule Gafgyt_Botnet_hoho : MALW
{
meta:
description = "Detect the risk of Botnet Malware Gafgyt Rule 8"
MD5 = "369c7c66224b343f624803d595aa1e09"
SHA1 = "54519d2c124cb536ed0ddad5683440293d90934f"
strings:
$s1 = "PING"
$s2 = "PRIVMSG"
$s3 = "Remote IRC Bot"
$s4 = "23.95.43.182"
condition:
$s1 and $s2 and $s3 and $s4
}
rule Gafgyt_Botnet_jackmy : MALW
{
meta:
description = "Detect the risk of Botnet Malware Gafgyt Rule 9"
MD5 = "419b8a10a3ac200e7e8a0c141b8abfba"
SHA1 = "5433a5768c5d22dabc4d133c8a1d192d525939d5"
strings:
$s1 = "PING"
$s2 = "PONG"
$s3 = "jackmy"
$s4 = "203.134.%d.%d"
condition:
$s1 and $s2 and $s3 and $s4
}
rule Gafgyt_Botnet_HIHI: MALW
{
meta:
description = "Detect the risk of Botnet Malware Gafgyt Rule 10"
MD5 = "cc99e8dd2067fd5702a4716164865c8a"
SHA1 = "b9b316c1cc9f7a1bf8c70400861de08d95716e49"
strings:
$s1 = "PING"
$s2 = "PONG"
$s3 = "TELNET LOGIN CRACKED - %s:%s:%s"
$s4 = "ADVANCEDBOT"
$s5 = "46.166.185.92"
$s6 = "LOLNOGTFO"
condition:
$s1 and $s2 and $s3 and $s4 and $s5 and $s6
}

View File

@@ -0,0 +1,24 @@
import "pe"
rule KelihosHlux
{
meta:
description = "Detect the risk of Botnet Malware Kelihos Rule 1"
strings:
$KelihosHlux_HexString = { 73 20 7D 8B FE 95 E4 12 4F 3F 99 3F 6E C8 28 26 C2 41 D9 8F C1 6A 72 A6 CE 36 0F 73 DD 2A 72 B0 CC D1 07 8B 2B 98 73 0E 7E 8C 07 DC 6C 71 63 F4 23 27 DD 17 56 AE AB 1E 30 52 E7 54 51 F7 20 ED C7 2D 4B 72 E0 77 8E B4 D2 A8 0D 8D 6A 64 F9 B7 7B 08 70 8D EF F3 9A 77 F6 0D 88 3A 8F BB C8 89 F5 F8 39 36 BA 0E CB 38 40 BF 39 73 F4 01 DC C1 17 BF C1 76 F6 84 8F BD 87 76 BC 7F 85 41 81 BD C6 3F BC 39 BD C0 89 47 3E 92 BD 80 60 9D 89 15 6A C6 B9 89 37 C4 FF 00 3D 45 38 09 CD 29 00 90 BB B6 38 FD 28 9C 01 39 0E F9 30 A9 66 6B 19 C9 F8 4C 3E B1 C7 CB 1B C9 3A 87 3E 8E 74 E7 71 D1 }
condition:
$KelihosHlux_HexString
}
rule kelihos_botnet_pdb {
meta:
description = "Detect the risk of Botnet Malware Kelihos Rule 2"
hash = "f0a6d09b5f6dbe93a4cf02e120a846073da2afb09604b7c9c12b2e162dfe7090"
strings:
$pdb = "\\Only\\Must\\Not\\And.pdb"
$pdb1 = "\\To\\Access\\Do.pdb"
condition:
uint16(0) == 0x5a4d and
filesize < 1440KB and
any of them
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,14 @@
rule Rule_Coinminer_ELF_Format {
meta:
description = "Detect the risk of CoinMiner ELF Rule 1"
detail= "Detects Crypto Miner ELF format"
strings:
$str1 = "mining.set_difficulty" ascii
$str2 = "mining.notify" ascii
$str3 = "GhostRider" ascii
$str4 = "cn/turtle-lite" ascii
$str5 = "spend-secret-key" ascii
condition:
uint16(0) == 0x457f and
4 of them
}

View File

@@ -0,0 +1,88 @@
rule MINER_monero_mining_detection {
meta:
description = "Detect the risk of CoinMiner Monero Rule 1"
detail= "Monero mining software"
strings:
$1 = "* COMMANDS: 'h' hashrate, 'p' pause, 'r' resume" fullword ascii
$2 = "--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1" fullword ascii
$3 = "* THREADS: %d, %s, av=%d, %sdonate=%d%%%s" fullword ascii
$4 = "--user-agent set custom user-agent string for pool" fullword ascii
$5 = "-O, --userpass=U:P username:password pair for mining server" fullword ascii
$6 = "--cpu-priority set process priority (0 idle, 2 normal to 5 highest)" fullword ascii
$7 = "-p, --pass=PASSWORD password for mining server" fullword ascii
$8 = "* VERSIONS: XMRig/%s libuv/%s%s" fullword ascii
$9 = "-k, --keepalive send keepalived for prevent timeout (need pool support)" fullword ascii
$10 = "--max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)" fullword ascii
$11 = "--nicehash enable nicehash/xmrig-proxy support" fullword ascii
$12 = "<!--The ID below indicates application support for Windows 10 -->" fullword ascii
$13 = "* CPU: %s (%d) %sx64 %sAES-NI" fullword ascii
$14 = "-r, --retries=N number of times to retry before switch to backup server (default: 5)" fullword ascii
$15 = "-B, --background run the miner in the background" fullword ascii
$16 = "* API PORT: %d" fullword ascii
$17 = "--api-access-token=T access token for API" fullword ascii
$18 = "-t, --threads=N number of miner threads" fullword ascii
$19 = "--print-time=N print hashrate report every N seconds" fullword ascii
$20 = "-u, --user=USERNAME username for mining server" fullword ascii
condition:
( uint16(0) == 0x5a4d and
filesize < 4000KB and
( 8 of them )) or
( all of them )
}
import "hash"
rule xmrig_moneroocean_prebuild: elf mining xmrig
{
meta:
description = "Detect the risk of CoinMiner Monero Rule 2"
condition:
hash.md5(0, filesize) == "5a818e75dff6adfe9f645cc49d6c0b70"
}
rule setup_moneroocean_miner: bash mining xmrig
{
meta:
description = "Detect the risk of CoinMiner Monero Rule 3"
strings:
$ = "MoneroOcean mining setup script"
$ = "setup_moneroocean_miner.sh <wallet address>"
$ = "TOTAL_CACHE=$(( $CPU_THREADS*$CPU_L1_CACHE + $CPU_SOCKETS"
$ = "$HOME/moneroocean/xmrig"
$ = "$LATEST_XMRIG_LINUX_RELEASE"
$ = "moneroocean_miner.service"
condition:
any of them or hash.md5(0, filesize) == "75363103bb838ca8e975d318977c06eb"
}
rule uninstall_moneroocean_miner: bash mining xmrig
{
meta:
description = "Detect the risk of CoinMiner Monero Rule 4"
strings:
$default1 = "moneroocean"
$default2 = "mining uninstall script"
$s1 = "sudo systemctl stop"
$s2 = "sudo systemctl disable"
$s3 = "rm -f /etc/systemd/system/"
$s4 = "sudo systemctl daemon-reload"
condition:
($default1 or $default2) and any of ($s*) or hash.md5(0, filesize) == "b059718f365d30a559afacf2d86bc379"
}
rule moneroocean_miner_service: mining xmrig
{
meta:
description = "Detect the risk of CoinMiner Monero Rule 5"
strings:
$default1 = "ExecStart="
$default2 = "moneroocean"
$s1 = "[Service]"
$s2 = "[Unit]"
condition:
all of ($default*) and any of ($s*)
}

View File

@@ -0,0 +1,138 @@
import "pe"
rule CoinMiner01 {
meta:
description = "Detects the risk of CoinMiner Trojan rule 1"
detail = "Detects coinminer payload"
strings:
$s1 = "-o pool." ascii wide
$s2 = "--cpu-max-threads-hint" ascii wide
$s3 = "-P stratum" ascii wide
$s4 = "--farm-retries" ascii wide
$dl = "github.com/ethereum-mining/ethminer/releases/download" ascii wide
condition:
uint16(0) == 0x5a4d and (3 of ($s*) or ($dl))
}
rule win_coinminer_auto {
meta:
description = "Detects the risk of CoinMiner Trojan rule 2"
strings:
$sequence_0 = { 56 85c0 7511 e8???????? 83c404 32c0 5e }
// n = 7, score = 100
// 56 | push esi
// 85c0 | test eax, eax
// 7511 | jne 0x13
// e8???????? |
// 83c404 | add esp, 4
// 32c0 | xor al, al
// 5e | pop esi
$sequence_1 = { e8???????? 8d8c24500b0000 8bf0 e8???????? }
// n = 4, score = 100
// e8???????? |
// 8d8c24500b0000 | lea ecx, [esp + 0xb50]
// 8bf0 | mov esi, eax
// e8???????? |
$sequence_2 = { 09c0 744a 8b5f04 48 8d8c3000700800 48 }
// n = 6, score = 100
// 09c0 | or eax, eax
// 744a | je 0x4c
// 8b5f04 | mov ebx, dword ptr [edi + 4]
// 48 | dec eax
// 8d8c3000700800 | lea ecx, [eax + esi + 0x87000]
// 48 | dec eax
$sequence_3 = { 8bf1 8b0d???????? 85ff 7527 85c9 7523 e8???????? }
// n = 7, score = 100
// 8bf1 | mov esi, ecx
// 8b0d???????? |
// 85ff | test edi, edi
// 7527 | jne 0x29
// 85c9 | test ecx, ecx
// 7523 | jne 0x25
// e8???????? |
$sequence_4 = { 8bcb e8???????? 57 ff15???????? 5f b001 5b }
// n = 7, score = 100
// 8bcb | mov ecx, ebx
// e8???????? |
// 57 | push edi
// ff15???????? |
// 5f | pop edi
// b001 | mov al, 1
// 5b | pop ebx
$sequence_5 = { f30f6f05???????? 56 57 f30f7f442440 b920000000 be???????? f30f6f05???????? }
// n = 7, score = 100
// f30f6f05???????? |
// 56 | push esi
// 57 | push edi
// f30f7f442440 | movdqu xmmword ptr [esp + 0x40], xmm0
// b920000000 | mov ecx, 0x20
// be???????? |
// f30f6f05???????? |
$sequence_6 = { 756e 56 e8???????? 83c404 33c0 5f }
// n = 6, score = 100
// 756e | jne 0x70
// 56 | push esi
// e8???????? |
// 83c404 | add esp, 4
// 33c0 | xor eax, eax
// 5f | pop edi
$sequence_7 = { 6b45e430 8945e0 8d8098589000 8945e4 803800 8bc8 7435 }
// n = 7, score = 100
// 6b45e430 | imul eax, dword ptr [ebp - 0x1c], 0x30
// 8945e0 | mov dword ptr [ebp - 0x20], eax
// 8d8098589000 | lea eax, [eax + 0x905898]
// 8945e4 | mov dword ptr [ebp - 0x1c], eax
// 803800 | cmp byte ptr [eax], 0
// 8bc8 | mov ecx, eax
// 7435 | je 0x37
$sequence_8 = { 7314 33c0 8974241c 85f6 }
// n = 4, score = 100
// 7314 | jae 0x16
// 33c0 | xor eax, eax
// 8974241c | mov dword ptr [esp + 0x1c], esi
// 85f6 | test esi, esi
$sequence_9 = { 83c102 ebe2 8d8df8fdffff b8???????? 90 668b10 }
// n = 6, score = 100
// 83c102 | add ecx, 2
// ebe2 | jmp 0xffffffe4
// 8d8df8fdffff | lea ecx, [ebp - 0x208]
// b8???????? |
// 90 | nop
// 668b10 | mov dx, word ptr [eax]
condition:
7 of them and filesize < 1523712
}
rule CoinMiner_imphash {
meta:
description = "Detects the risk of CoinMiner Trojan rule 3"
condition:
pe.imphash() == "563557d99523e4b1f8aab2eb9b79285e"
}
rule Trojan_CoinMiner {
meta:
description = "Detects the risk of CoinMiner Trojan rule 4"
hash1 = "3bdac08131ba5138bcb5abaf781d6dc7421272ce926bc37fa27ca3eeddcec3c2"
hash2 = "d60766c4e6e77de0818e59f687810f54a4e08505561a6bcc93c4180adb0f67e7"
strings:
$seq0 = { df 75 ab 7b 80 bf 83 c1 48 b3 18 74 70 01 24 5c }
$seq1 = { 08 37 4e 6e 0f 50 0b 11 d0 98 0f a8 b8 27 47 4e }
$seq2 = { bf 17 5a 08 09 ab 80 2f a1 b0 b1 da 47 9f e1 61 }
$seq3 = { 53 36 34 b2 94 01 cc 05 8c 36 aa 8a 07 ff 06 1f }
$seq4 = { 25 30 ae c4 44 d1 97 82 a5 06 05 63 07 02 28 3a }
$seq5 = { 01 69 8e 1c 39 7b 11 56 38 0f 43 c8 5f a8 62 d0 }
condition:
( uint16(0) == 0x5a4d and filesize < 5000KB and pe.imphash() == "e4290fa6afc89d56616f34ebbd0b1f2c" and 3 of ($seq*)
)
}

View File

@@ -0,0 +1,36 @@
rule RULE_ETERNALBLUE_GENERIC_SHELLCODE
{
meta:
description = "Detect the risk of Wannamine Rule 1"
detail = "Detecta una shellcode genérica de EternalBlue, con payload variable"
strings:
$sc = { 31 c0 40 0f 84 ?? ?? ?? ?? 60 e8 00 00 00 00 5b e8 23 00 00 00 b9
76 01 00 00 0f 32 8d 7b 39 39 }
condition:
all of them
}
rule RULE_XMRIG
{
meta:
description = "Detect the risk of Wannamine Rule 2"
detail = "Minero XMRig WannaMine"
strings:
$xmrig = "xmrig"
$randomx = "randomx"
condition:
uint16(0) == 0x5A4D and
all of them
}
rule CoinMiner_WannaMine_Opcodes
{
meta:
description = "Detect the risk of Wannamine Rule 3"
strings:
$s1 = {558BEC83EC10A05BE241008B550C8BCA}
$s2 = {8B45008954243C03D081FAA00500000F}
$s3 = {558BEC6AFF68786F410064A100000000}
condition:
uint16(0) == 0x5a4d and all of them
}

View File

@@ -0,0 +1,215 @@
import "hash"
rule givemexyz_family_hash
{
meta:
description ="Detect the risk of CoinMiner givemexyz Rule 1"
condition:
hash.sha256(0,filesize) =="599393e258d8ba7b8f8633e20c651868258827d3a43a4d0712125bc487eabf92" or
hash.sha256(0,filesize) =="2c356d4621626e3de5f268aea9e7736840bbfcdc02e15d2b3cda1050f4f50798" or
hash.sha256(0,filesize) =="2fc3be782b1803c6e1c17e386136e6b2fb7e5054e2a81eee8f866eeaa44beab1" or
hash.sha256(0,filesize) =="8a877dc7afbfb6701ac42630c2adafb9ef46e8942e5b17372f07c892a7bee1b3" or
hash.sha256(0,filesize) =="1225cc15a71886e5b11fca3dc3b4c4bcde39f4c7c9fbce6bad5e4d3ceee21b3a" or
hash.sha256(0,filesize) =="11547e36146e0b0956758d48faeb19d4db5e737dc942bc7498ed86a8010bdc8b" or
hash.sha256(0,filesize) =="86f57444e6f4a40378fd0959a54794c7384d04678f8c66dfb7801f3d0cfc0152" or
hash.sha256(0,filesize) =="86859ad5e3115893e5878e91168367d564c1eb937af0d1e4c29dd38fb9647362" or
hash.sha256(0,filesize) =="f8744257415d256512c8b2f3501be20a0a30e37357e71df3986e2918fd53ef5e" or
hash.sha256(0,filesize) =="b6154d25b3aa3098f2cee790f5de5a727fc3549865a7aa2196579fe39a86de09" or
hash.sha256(0,filesize) =="a5604893608cf08b7cbfb92d1cac20868808218b3cc453ca86da0abaeadc0537" or
hash.sha256(0,filesize) =="f994135b5285cc481f2bfc213395e81c656542d1b6b5f23551565d524f3cdb89" or
hash.sha256(0,filesize) =="ceb3a7a521dc830a603037c455ff61e8849235f74db3b5a482ad5dcf0a1cdbc5"
}
rule XmrigCnrigOptions: mining xmrig cnrig
{
meta:
description ="Detect the risk of CoinMiner givemexyz Rule 2"
strings:
$s1 = "--donate-level" ascii
$s2 = "--nicehash" ascii
$s3 = "--algo" ascii
$s4 = "--threads" ascii
$s5 = "--cpu-max-threads-hint" ascii
$x = "xmrig" ascii fullword
condition:
3 of ($s*) and $x
}
import "hash"
// xmrig_md5_5_9_0
private rule tar_gz_5_9_0
{
meta:
description = "xmrig-5.9.0-xenial-x64.tar.gz"
condition:
hash.md5(0, filesize) == "b63ead42823ae63c93ac401e38937323"
}
private rule xmrig_5_9_0
{
meta:
description = "xmrig.elf"
condition:
hash.md5(0, filesize) == "d351de486d4bb4e80316e1524682c602"
}
private rule xmrig_notls_5_9_0
{
meta:
description = "xmrig-notls.elf"
condition:
hash.md5(0, filesize) == "187ed1d112e4a9dff0241368f2868615"
}
rule xmrig_md5_5_9_0: mining md5 xmrig
{
meta:
description ="Detect the risk of CoinMiner givemexyz Rule 3"
condition:
tar_gz_5_9_0 or xmrig_5_9_0 or xmrig_notls_5_9_0
}
// xmrig_md5_5_10_0
private rule tar_gz_5_10_0
{
meta:
description = "xmrig-5.10.0-xenial-x64.tar.gz"
condition:
hash.md5(0, filesize) == "416079fd0c7b45307556198f3f67754d"
}
private rule xmrig_5_10_0
{
meta:
description = "xmrig.elf"
condition:
hash.md5(0, filesize) == "3939395192972820ce2cf99db0c239d7"
}
private rule xmrig_notls_5_10_0
{
meta:
description = "xmrig-notls.elf"
condition:
hash.md5(0, filesize) == "0456ef39240c75e0862b30419d4c6359"
}
rule xmrig_md5_5_10_0: mining md5 xmrig
{
meta:
description ="Detect the risk of CoinMiner givemexyz Rule 4"
condition:
tar_gz_5_10_0 or xmrig_5_10_0 or xmrig_notls_5_10_0
}
// xmrig_md5_5_11_0
private rule tar_gz_5_11_0
{
meta:
description = "xmrig-5.11.0-xenial-x64.tar.gz"
condition:
hash.md5(0, filesize) == "abf7feaf1e456c0fc6e8f1e40af9211c"
}
private rule xmrig_5_11_0
{
meta:
description = "xmrig.elf"
condition:
hash.md5(0, filesize) == "56aec7d8d2aba5ba2b82930408f0b5d3"
}
private rule xmrig_notls_5_11_0
{
meta:
description = "xmrig-notls.elf"
condition:
hash.md5(0, filesize) == "9a5c0a5d960b676ba4db535f71ee7cef"
}
rule xmrig_md5_5_11_0: mining md5 xmrig
{
meta:
description ="Detect the risk of CoinMiner givemexyz Rule 5"
condition:
tar_gz_5_11_0 or xmrig_5_11_0 or xmrig_notls_5_11_0
}
// xmrig_md5_5_11_1
private rule tar_gz_5_11_1
{
meta:
description = "xmrig-5.11.1-xenial-x64.tar.gz"
condition:
hash.md5(0, filesize) == "820022ba985b4d21637bf6d3d1e53001"
}
private rule xmrig_5_11_1
{
meta:
description = "xmrig.elf"
condition:
hash.md5(0, filesize) == "0090962752b93454093239f770628006"
}
private rule xmrig_notls_5_11_1
{
meta:
description = "xmrig-notls.elf"
condition:
hash.md5(0, filesize) == "54158be61b8011a10d1a94432ead208c"
}
rule xmrig_md5_5_11_1: mining md5 xmrig
{
meta:
description ="Detect the risk of CoinMiner givemexyz Rule 6"
condition:
tar_gz_5_11_1 or xmrig_5_11_1 or xmrig_notls_5_11_1
}
rule xmrig_md5_samples_1: mining md5 xmrig
{
meta:
description ="Detect the risk of CoinMiner givemexyz Rule 7"
condition:
hash.md5(0, filesize) == "6f2a2ff340fc1307b65174a3451f8c9a"
}
rule xmrig_md5_samples_2: mining md5 xmrig
{
meta:
description ="Detect the risk of CoinMiner givemexyz Rule 8"
condition:
hash.md5(0, filesize) == "22a213bfd093c402312d75f5f471505e"
}
rule XmrigConfig: json mining xmrig
{
meta:
description ="Detect the risk of CoinMiner givemexyz Rule 9"
detail = "xmrig config.json"
strings:
$ = "\"worker-id\":" ascii
$ = "\"randomx\":" ascii
$ = "\"donate-level\":" ascii
$ = "\"rig-id\":" ascii
$ = "\"donate-over-proxy\":" ascii
condition:
3 of them
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
rule Rootkit_FiveSys {
meta:
description ="Detect the risk of Malware FiveSys Rule 1"
hash1 = "cce24ebdd344c8184dbaa0a0c4a65c7d952a11f6608fe23d562a4d1178915eac"
strings:
$s1 = "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 %s " fullword ascii
$s2 = "GET %s%s HTTP/1.1" fullword ascii
$s3 = "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 sysWeb/1.0.1 " fullword ascii
$s4 = "D:\\record.txt" fullword ascii
$s5 = "number=%s;name=%s;switch=%s;server=%s;tag=%s;altitude=%s;serverDownloadFileName=%s;serverDownloadFileMd5=%s;" fullword ascii
$s6 = "%d - fileName=%s result=%s DownFile=%s" fullword ascii
$s7 = "/driverfile/Jck.txt" fullword ascii
$s8 = "/driverfile/shuiliasafao.txt" fullword ascii
$s9 = "\\FiveSys_1\\x64\\Debug\\FiveSys.pdb" fullword ascii
$s10 = "/api/drive_config/driveDownloadFileList" fullword ascii
$s11 = "[%s] CreateMiniKey failed!Error code:%x" fullword ascii
$s12 = "Host: %d.%d.%d.%d" fullword ascii
$s13 = "serverDownloadFileMd5" fullword ascii
$s14 = "/api/safe/checkver?name=FiveSys_1.sys&ver=" fullword ascii
$s15 = "Haining shengdun Network Information Technology Co., Ltd" fullword ascii
$s16 = "\\cdriversock.cpp" fullword ascii
$s17 = "FiveSys_1.sys\",\"md5\":\"" fullword ascii
$s18 = "/api/popup/fiveDriveCheckdownloadfile?filelist=[{\"name\":\"" fullword ascii
$s19 = "[%s] StartMinifilter failed!Error code:%x" fullword ascii
$s20 = "[%s] CreateMiniKey success!" fullword ascii
condition:
uint16(0) == 0x5a4d and
8 of them
}

View File

@@ -0,0 +1,31 @@
import "hash"
rule Gen_Trojan_Mikey {
meta:
description ="Detect the risk of Malware Mikey Rule 1"
hash = "a8e6c3ca056b3ff2495d7728654b780735b3a4cb"
strings:
$s0 = "nuR\\noisreVtnerruC\\swodniW\\tfosorciM\\ERAWTFOS" fullword ascii
/* reversed string 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run' */
$x1 = "User-Agent:Mozilla/4.0 (compatible; MSIE %d.0; Windows NT %d.1; SV1)" fullword ascii
$x2 = "User-Agent:Mozilla/4.0 (compatible; MSIE 6.00; Windows NT 5.0; MyIE 3.01)" fullword ascii
$x3 = "%d*%u%s" fullword ascii
$x4 = "%s %s:%d" fullword ascii
$x5 = "Mnopqrst Vwxyabcde Ghijklm Opqrstuv Xya" fullword ascii
condition:
uint16(0) == 0x5a4d and $s0 and 2 of ($x*)
}
rule Mikey_hash
{
meta:
description ="Detect the risk of Malware Mikey Rule 2"
condition:
hash.sha256(0,filesize) =="71f9b10d43494f2b88e0621f0b389f3848415e6737510d8e882b58ba0dad56b0" or
hash.sha256(0,filesize) =="b5c0ffd178d50a325199f3df0951d088585f40a00d0cd44fa610c894867935f6" or
hash.sha256(0,filesize) =="0f5827b2364a8411542b806aa02c106473faff7b9b7a4da5eaa98104a8abf7fd" or
hash.sha256(0,filesize) =="dc422934a782db00afa24cc085c779101386bf8d11bc2fda0db73418935f9fc5" or
hash.sha256(0,filesize) =="37699bfb7cae547a1a312ba7cc47716e6d805b48f58c3783342b801875e20ff8" or
hash.sha256(0,filesize) =="f55af21f69a183fb8550ac60f392b05df14aa01d7ffe9f28bc48a118dc110b4c" or
hash.sha256(0,filesize) =="121157e0fcb728eb8a23b55457e89d45d76aa3b7d01d3d49105890a00662c924"
}

View File

@@ -0,0 +1,48 @@
import "hash"
rule MAL_ELF_Rekoobe_Nov_2021_1
{
meta:
description ="Detect the risk of Malware Rekoobe Rule 1"
hash1 = "bf09a1a7896e05b18c033d2d62f70ea4cac85e2d72dbd8869e12b61571c0327e"
hash2 = "e1999a3e5a611312e16bb65bb5a880dfedbab8d4d2c0a5d3ed1ed926a3f63e94"
strings:
$s1 = { 00 ?? 19 00 00 00 48 85 c0 [2-6] bf 0a 00 00 00 e8 [2] 01 00 ?? 24 00 00 00 48 85 c0 [2-6] c6 00 48 c6 40 05 49 c6 40 01 49 c6 40 06 4c c6 40 02 53 c6 40 07 45 c6 40 03 54 c6 40 08 3d c6 40 04 46 c6 40 09 00 48 89 c7 e8 [2] 00 00 48 8d 54 24 0c }
$s2 = "GETCONF_DIR" ascii
$s3 = "/var/run/nscd/so/dev/ptmx" ascii
$s4 = { 45 78 65 63 53 74 61 72 74 3d 2f 62 69 6e 2f 62 61 73 68 20 2d 63 20 2f 75 73 72 2f 62 69 6e 2f 62 69 6f 73 65 74 64 }
$s5 = { 48 89 df e8 [3] ff 31 f6 48 89 df e8 [3] ff 48 8d 58 01 48 }
$s6 = { 2f 76 61 72 2f 74 6d 70 00 2f 76 61 72 2f 70 72 6f 66 69 6c 65 }
condition:
uint32(0) == 0x464C457F and filesize > 100KB and 5 of ($s*)
}
rule Rekoobe_v2
{
meta:
description ="Detect the risk of Malware Rekoobe Rule 2"
strings:
$a0 = { 83 ?? ?? FF 7? ?? 5? 89 ?? 5? 5? 5? 5? 83 ?? ?? 8B ?? ?? 65 ?? ?? ?? ?? ?? 89 ?? ?? 31 ?? 8B ?? B9 ?? ?? ?? ?? 89 ?? F2 ?? 89 ?? F7 ?? 83 ?? ?? 5? 6A ?? 5? E8 ?? ?? ?? ?? 8B ?? C7 ?? ?? ?? ?? ?? C7 ?? ?? ?? ?? ?? ?? C7 ?? ?? ?? ?? ?? ?? C7 ?? ?? ?? ?? ?? ?? C7 ?? ?? ?? ?? ?? ?? C7 ?? ?? ?? ?? ?? ?? 66 ?? ?? ?? ?? ?? C6 ?? ?? ?? E8 ?? ?? ?? ?? 83 ?? ?? 85 ?? 0F 88 [0-128] 89 ?? B8 ?? ?? ?? ?? 85 ?? 0F 85 [0-128] E8 ?? ?? ?? ?? 89 ?? }
$a1 = { 6A ?? E8 ?? ?? ?? ?? 83 ?? ?? 6A ?? 6A ?? 6A ?? E8 ?? ?? ?? ?? 89 ?? 83 ?? ?? 85 ?? 78 [0-128] 83 ?? ?? 68 ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 ?? ?? 85 ?? 74 [0-128] 6A ?? FF 7? ?? 8B ?? ?? FF 3? 5? E8 ?? ?? ?? ?? 66 ?? ?? ?? ?? ?? 66 ?? ?? ?? ?? ?? 83 ?? ?? 6A ?? 5? 5? E8 ?? ?? ?? ?? 83 }
$b0 = { 0F 8E [0-128] 0F B6 ?? 4C ?? ?? ?? ?? ?? ?? ?? 4C ?? ?? ?? 4C ?? ?? 48 ?? ?? ?? 40 ?? ?? ?? 4C ?? ?? ?? ?? ?? ?? ?? 48 ?? ?? 48 ?? ?? ?? 40 ?? ?? ?? 4C ?? ?? ?? ?? ?? ?? ?? 0F B6 ?? 4C ?? ?? ?? ?? ?? ?? ?? 0F B6 ?? 4C ?? ?? ?? ?? ?? ?? ?? 4C ?? ?? ?? 48 ?? ?? 48 ?? ?? ?? 40 ?? ?? ?? 4C ?? ?? ?? ?? ?? ?? ?? 4C ?? ?? 48 ?? ?? ?? 40 ?? ?? ?? 4C ?? ?? ?? ?? ?? ?? ?? 0F B6 ?? 4C ?? ?? ?? ?? ?? ?? ?? 0F B6 ?? 48 ?? ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? 48 ?? ?? ?? 40 ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? ?? 48 ?? ?? 48 ?? ?? ?? 40 ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? ?? 49 ?? ?? 4C ?? ?? 0F B6 ?? 4C ?? ?? 48 ?? ?? ?? ?? ?? ?? ?? 41 ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? 0F B6 ?? 48 ?? ?? ?? ?? ?? ?? ?? 48 ?? ?? 48 ?? ?? ?? 0F B6 ??}
$b1 = { BB ?? ?? ?? ?? 45 ?? ?? 7F [0-128] EB [0-128] 49 ?? ?? C6 ?? ?? ?? ?? ?? ?? 41 ?? ?? ?? ?? 48 ?? C6 ?? ?? ?? ?? ?? ?? 41 ?? ?? ?? ?? 48 ?? C6 ?? ?? ?? ?? ?? ?? 41 ?? ?? ?? ?? 48 ?? 48 ?? ?? ?? ?? ?? ?? 88 ?? ?? ?? ?? ?? 48 ?? ?? E8 ?? ?? ?? ?? BA ?? ?? ?? ?? BE ?? ?? ?? ?? 48 ?? ?? E8 ?? ?? ?? ?? 41 ?? ?? ?? ?? 48 ?? ?? BE ?? ?? ?? ?? 48 ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? ?? 48 ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? E8 ?? ?? ?? ?? BA ?? ?? ?? ?? BE ?? ?? ?? ?? 48 ?? ?? E8 ?? ?? ?? ?? BA ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? ?? 48 ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? ?? 41 ?? ?? ?? ?? 48 ?? ?? B9 ?? ?? ?? ?? BE ?? ?? ?? ?? 44 ?? ?? E8 ?? ?? ?? ?? 89 ?? B8 ?? ?? ?? ?? 83 ?? ?? 75 }
$b2 = { 8D [0-128] 44 ?? ?? ?? 4D ?? ?? B9 ?? ?? ?? ?? 4C ?? ?? BE ?? ?? ?? ?? 89 ?? E8 ?? ?? ?? ?? B9 ?? ?? ?? ?? 83 ?? ?? 0F 85 [0-128] 48 ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? 89 ?? ?? ?? ?? ?? ?? C6 ?? ?? ?? ?? ?? ?? 8D ?? ?? 48 ?? C6 ?? ?? ?? ?? ?? ?? 8D ?? ?? 48 ?? C6 ?? ?? ?? ?? ?? ?? 8D ?? ?? 48 ?? 48 ?? ?? ?? ?? ?? ?? 88 ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? E8 ?? ?? ?? ?? BA ?? ?? ?? ?? BE ?? ?? ?? ?? 48 ?? ?? ?? ?? E8 ?? ?? ?? ?? 4C ?? ?? BE ?? ?? ?? ?? 48 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? ?? E8 ?? ?? ?? ?? BA ?? ?? ?? ?? BE ?? ?? ?? ?? 48 ?? ?? ?? ?? E8 ?? ?? ?? ?? BA ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ?? ?? 48 }
$b3 = { 49 ?? ?? 48 ?? ?? 49 ?? ?? 49 ?? ?? ?? 41 ?? ?? ?? BB ?? ?? ?? ?? 4C ?? ?? 48 ?? ?? ?? ?? ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? 01 ?? 48 ?? ?? 48 ?? ?? 0F 97 ?? 0F B6 ?? 48 ?? ?? 48 ?? ?? ?? 49 ?? ?? 0F 82 [0-128] 4D ?? ?? 74 [0-128] 4A ?? ?? ?? ?? 48 ?? ?? E8 ?? ?? ?? ?? 49 ?? ?? ?? ?? 4C ?? ?? E8 ?? ?? ?? ?? 49 ?? ?? 49 ?? ?? 49 ?? ?? ?? 76 }
condition:
all of ($a*) or all of ($b*)
}
rule Rekoobe_hash
{
meta:
description ="Detect the risk of Malware Rekoobe Rule 3"
condition:
hash.sha256(0,filesize) =="c1aa86482bb9999ca6e7fe771745f4d58f574a90f9f4abf96c16965b3364854b" or
hash.sha256(0,filesize) =="696ddb493016d46780aaecafa731c76fef2d28a56fc75afe1f9b4535612c1db9" or
hash.sha256(0,filesize) =="7b88fa41d6a03aeda120627d3363b739a30fe00008ce8d848c2cbb5b4473d8bc" or
hash.sha256(0,filesize) =="31330c0409337592e9de7ac981cecb7f37ce0235f96e459fefbd585e35c11a1a" or
hash.sha256(0,filesize) =="275d63587f3ac511d7cca5ff85af2914e74d8b68edd5a7a8a1609426d5b7f6a9" or
hash.sha256(0,filesize) =="df90558a84cfcf80639f32b31aec187b813df556e3c155a05af91dedfd2d7429" or
hash.sha256(0,filesize) =="2e81517ee4172c43a2084be1d584841704b3f602cafc2365de3bcb3d899e4fb8"
}

View File

@@ -0,0 +1,18 @@
rule Ransom_BCrypt {
meta:
description= "Detect the risk of Ransomware BCrypt Rule 1"
hash1 = "9b710b07d9192d590ecf8be939ce8ff44e23e64569687f636995270c618582a7"
hash2 = "e47e4060f7a53eb7851b4f9622dccead3594b4af759f882f700cb1737b5f09c5"
strings:
$s1 = "https://www.douban.com/note/693052956/" fullword ascii
$s2 = "C:\\windows64.ntd" fullword ascii
$s3 = "AliWorkbench.exe" fullword ascii
$s4 = "C:\\windows64-2.ntd" fullword ascii
$s5 = "/bEncrypt" fullword wide
$s6 = "unname_1989\\" fullword wide
$s7 = "libcef.dll" fullword wide
$s8 = "C:\\123456789.txt" fullword ascii
$s9 = "SearchCompterFileEncrypt.dll" fullword ascii
condition:
uint16(0) == 0x5a4d and 2 of them
}

View File

@@ -0,0 +1,31 @@
rule Ransom_Babuk {
meta:
description= "Detect the risk of Ransomware Babuk Rule 1"
hash1 = "5eb21c59b6a0df15be307fc5ef82464f3d9a56dff8f4214576c48dbc9d3fe7af"
hash2 = "1f2edda243404918b78aa6123aa1fc5b18dd9506e4042c7a1547b565334527e1"
strings:
$mutex = "DoYouWantToHaveSexWithCuongDong" fullword ascii
$mutex_api1 = "OpenMutexA" fullword ascii
$mutex_api2 = "CreateMutexA" fullword ascii
$delshadow1 = "/c vssadmin.exe delete shadows /all /quiet" wide
$delshadow2 = "cmd.exe" wide
$delshadow3 = "open" fullword wide
$delshadow_api = "ShellExecuteW" fullword ascii
$folder1 = "AppData" fullword wide
$folder2 = "Boot" fullword wide
$folder3 = "Windows.old" fullword wide
$folder4 = "Tor Browser" fullword wide
$folder5 = "$Recycle.Bin" fullword wide
$note = "\\How To Restore Your Files.txt" fullword wide
$encrypt = ".babyk" fullword wide
$op1 = {C7 85 D0 FE FF FF 63 68 6F 75}
$op2 = {C7 85 D4 FE FF FF 6E 67 20 64}
$op3 = {C7 85 D8 FE FF FF 6F 6E 67 20}
$op4 = {C7 85 DC FE FF FF 6C 6F 6F 6B}
$op5 = {C7 85 E0 FE FF FF 73 20 6C 69}
$op6 = {C7 85 E4 FE FF FF 6B 65 20 68}
$op7 = {C7 85 E8 FE FF FF 6F 74 20 64}
$op8 = {C7 85 EC FE FF FF 6F 67 21 21 68 80 00 00 00}
condition:
uint16(0) == 0x5a4d and filesize < 200KB and (all of ($mutex*) or all of ($delshadow*) or all of ($folder*) or $note or $encrypt or 3 of ($op*))
}

View File

@@ -0,0 +1,112 @@
rule Ransom_BadEncript {
meta:
description= "Detect the risk of Ransomware BadEncript Rule 1"
hash1 = "3bba4636606843da8e3591682b4433bdc94085a1939bbdc35f10bbfd97ac3d3d"
strings:
$x1 = "c:\\users\\nikitos\\documents\\visual studio 2015\\Projects\\BadEncriptMBR\\Release\\BadEncriptMBR.pdb" fullword ascii
$s2 = "DoctorPetrovic.org" fullword wide
$s3 = "oh lol it failed" fullword ascii
$s4 = "Allows DoctorPetrovic Scanner" fullword wide
condition:
uint16(0) == 0x5a4d and filesize < 400KB and
(any of ($x*) or 2 of them)
}
rule win_badencript_auto {
meta:
description= "Detect the risk of Ransomware BadEncript Rule 2"
strings:
$sequence_0 = { 8bc1 83e13f c1f806 6bc930 8b048548414100 0fb6440828 }
// n = 6, score = 100
// 8bc1 | mov eax, ecx
// 83e13f | and ecx, 0x3f
// c1f806 | sar eax, 6
// 6bc930 | imul ecx, ecx, 0x30
// 8b048548414100 | mov eax, dword ptr [eax*4 + 0x414148]
// 0fb6440828 | movzx eax, byte ptr [eax + ecx + 0x28]
$sequence_1 = { 8d7f08 8b048d04b54000 ffe0 f7c703000000 7413 8a06 8807 }
// n = 7, score = 100
// 8d7f08 | lea edi, [edi + 8]
// 8b048d04b54000 | mov eax, dword ptr [ecx*4 + 0x40b504]
// ffe0 | jmp eax
// f7c703000000 | test edi, 3
// 7413 | je 0x15
// 8a06 | mov al, byte ptr [esi]
// 8807 | mov byte ptr [edi], al
$sequence_2 = { 83c8ff eb07 8b04cdecfd4000 5f 5e 5b 8be5 }
// n = 7, score = 100
// 83c8ff | or eax, 0xffffffff
// eb07 | jmp 9
// 8b04cdecfd4000 | mov eax, dword ptr [ecx*8 + 0x40fdec]
// 5f | pop edi
// 5e | pop esi
// 5b | pop ebx
// 8be5 | mov esp, ebp
$sequence_3 = { 83e03f c1f906 6bc030 03048d48414100 }
// n = 4, score = 100
// 83e03f | and eax, 0x3f
// c1f906 | sar ecx, 6
// 6bc030 | imul eax, eax, 0x30
// 03048d48414100 | add eax, dword ptr [ecx*4 + 0x414148]
$sequence_4 = { 8b049548414100 804c182d04 ff4604 eb08 ff15???????? }
// n = 5, score = 100
// 8b049548414100 | mov eax, dword ptr [edx*4 + 0x414148]
// 804c182d04 | or byte ptr [eax + ebx + 0x2d], 4
// ff4604 | inc dword ptr [esi + 4]
// eb08 | jmp 0xa
// ff15???????? |
$sequence_5 = { 8b1c9d68d14000 56 6800080000 6a00 53 ff15???????? 8bf0 }
// n = 7, score = 100
// 8b1c9d68d14000 | mov ebx, dword ptr [ebx*4 + 0x40d168]
// 56 | push esi
// 6800080000 | push 0x800
// 6a00 | push 0
// 53 | push ebx
// ff15???????? |
// 8bf0 | mov esi, eax
$sequence_6 = { 6a00 6a03 6a00 6a04 6800000010 }
// n = 5, score = 100
// 6a00 | push 0
// 6a03 | push 3
// 6a00 | push 0
// 6a04 | push 4
// 6800000010 | push 0x10000000
$sequence_7 = { 33c0 3b0cc520db4000 7427 40 83f82d 72f1 }
// n = 6, score = 100
// 33c0 | xor eax, eax
// 3b0cc520db4000 | cmp ecx, dword ptr [eax*8 + 0x40db20]
// 7427 | je 0x29
// 40 | inc eax
// 83f82d | cmp eax, 0x2d
// 72f1 | jb 0xfffffff3
$sequence_8 = { c1fa06 8bc6 83e03f 6bc830 8b049548414100 f644082801 }
// n = 6, score = 100
// c1fa06 | sar edx, 6
// 8bc6 | mov eax, esi
// 83e03f | and eax, 0x3f
// 6bc830 | imul ecx, eax, 0x30
// 8b049548414100 | mov eax, dword ptr [edx*4 + 0x414148]
// f644082801 | test byte ptr [eax + ecx + 0x28], 1
$sequence_9 = { 8bc8 d1f9 6a41 5f 894df0 8b34cde8fd4000 }
// n = 6, score = 100
// 8bc8 | mov ecx, eax
// d1f9 | sar ecx, 1
// 6a41 | push 0x41
// 5f | pop edi
// 894df0 | mov dword ptr [ebp - 0x10], ecx
// 8b34cde8fd4000 | mov esi, dword ptr [ecx*8 + 0x40fde8]
condition:
7 of them and filesize < 335872
}

View File

@@ -0,0 +1,39 @@
rule BadRabbit_Gen {
meta:
description= "Detect the risk of Ransomware BadRabbit Rule 1"
hash1 = "8ebc97e05c8e1073bda2efb6f4d00ad7e789260afa2c276f0c72740b838a0a93"
hash2 = "579fd8a0385482fb4c789561a30b09f25671e86422f40ef5cca2036b28f99648"
hash3 = "630325cac09ac3fab908f903e3b00d0dadd5fdaa0875ed8496fcbb97a558d0da"
strings:
$x1 = "schtasks /Create /SC ONCE /TN viserion_%u /RU SYSTEM /TR \"%ws\" /ST" fullword wide
$x2 = "schtasks /Create /RU SYSTEM /SC ONSTART /TN rhaegal /TR \"%ws /C Start \\\"\\\" \\\"%wsdispci.exe\\\"" fullword wide
$x3 = "C:\\Windows\\infpub.dat" fullword wide
$x4 = "C:\\Windows\\cscc.dat" fullword wide
$s1 = "need to do is submit the payment and get the decryption password." fullword ascii
$s2 = "\\\\.\\GLOBALROOT\\ArcName\\multi(0)disk(0)rdisk(0)partition(1)" fullword wide
$s3 = "\\\\.\\pipe\\%ws" fullword wide
$s4 = "fsutil usn deletejournal /D %c:" fullword wide
$s5 = "Run DECRYPT app at your desktop after system boot" fullword ascii
$s6 = "Files decryption completed" fullword wide
$s7 = "Disable your anti-virus and anti-malware programs" fullword wide
$s8 = "SYSTEM\\CurrentControlSet\\services\\%ws" fullword wide
$s9 = "process call create \"C:\\Windows\\System32\\rundll32.exe" fullword wide
$s10 = "%ws C:\\Windows\\%ws,#1 %ws" fullword wide
condition:
uint16(0) == 0x5a4d and filesize < 700KB and ( 1 of ($x*) or 2 of them )
}
rule BadRabbit_Mimikatz_Comp {
meta:
description= "Detect the risk of Ransomware BadRabbit Rule 2"
hash1 = "2f8c54f9fa8e47596a3beff0031f85360e56840c77f71c6a573ace6f46412035"
strings:
$s1 = "%lS%lS%lS:%lS" fullword wide
$s2 = "lsasrv" fullword wide
$s3 = "CredentialKeys" ascii
/* Primary\x00m\x00s\x00v */
$s4 = { 50 72 69 6D 61 72 79 00 6D 00 73 00 76 00 }
condition:
( uint16(0) == 0x5a4d and filesize < 200KB and 3 of them )
}

View File

@@ -0,0 +1,9 @@
rule Ransom_BlackMatter {
meta:
description= "Detect the risk of Ransomware BlackMatter Rule 1"
strings:
$op1 = {558BEC81EC0401000053515256578DBDFCFEFFFF32C0AAB92A000000B0FFF3AAB03EAAB903000000B0FF}
$op2 = {02C28B7D0CC1EB028D145B2BD052895DFC8B0E0FB6D10FB6DD578DBDFCFEFFFF}
condition:
uint16(0) == 0x5a4d and any of them
}

133
yaraRules/Ransom.Cerber.yar Normal file
View File

@@ -0,0 +1,133 @@
rule cerber3{
meta:
description= "Detect the risk of Ransomware Cerber Rule 1"
strings:
$a = {00 6A 00 68 80 00 00 00 6A 03 6A 00 6A 03 6A 01 8B 85}
$b = {68 3B DB 00 00 ?? ?? ?? ?? 00 ?? FF 15}
condition:
1 of them
}
rule cerber4{
meta:
description= "Detect the risk of Ransomware Cerber Rule 2"
strings:
$a = {8B 0D ?? ?? 43 00 51 8B 15 ?? ?? 43 00 52 E8 C9 04 00 00 83 C4 08 89 45 FC A1 ?? ?? 43 00 3B 05 ?? ?? 43 00 72 02}
condition:
1 of them
}
rule cerber5{
meta:
description= "Detect the risk of Ransomware Cerber Rule 3"
strings:
$a = {83 C4 04 A3 ?? ?? ?? 00 C7 45 ?? ?? ?? ?? 00 8B ?? ?? C6 0? 56 8B ?? ?? 5? 68 ?? ?? 4? 00 FF 15 ?? ?? 4? 00 50 FF 15 ?? ?? 4? 00 A3 ?? ?? 4? 00 68 1D 10 00 00 E8 ?? ?? FF FF 83 C4 04 ?? ?? ??}
condition:
1 of them
}
rule cerber5b{
meta:
description= "Detect the risk of Ransomware Cerber Rule 4"
strings:
$a={8B ?? ?8 ?? 4? 00 83 E? 02 89 ?? ?8 ?? 4? 00 68 ?C ?9 4? 00 [0-6] ?? ?? ?? ?? ?? ?8 ?? 4? 00 5? FF 15 ?? ?9 4? 00 89 45 ?4 83 7D ?4 00 75 02 EB 12 8B ?? ?0 83 C? 06 89 ?? ?0 B? DD 03 00 00 85}
condition:
$a
}
rule win_cerber_auto {
meta:
description= "Detect the risk of Ransomware Cerber Rule 5"
strings:
$sequence_0 = { eba0 47 3bf8 0f8c3effffff 5e 5b 5f }
// n = 7, score = 1200
// eba0 | jmp 0xffffffa2
// 47 | inc edi
// 3bf8 | cmp edi, eax
// 0f8c3effffff | jl 0xffffff44
// 5e | pop esi
// 5b | pop ebx
// 5f | pop edi
$sequence_1 = { ff750c e8???????? 59 59 84c0 74e9 8d45f8 }
// n = 7, score = 1200
// ff750c | push dword ptr [ebp + 0xc]
// e8???????? |
// 59 | pop ecx
// 59 | pop ecx
// 84c0 | test al, al
// 74e9 | je 0xffffffeb
// 8d45f8 | lea eax, [ebp - 8]
$sequence_2 = { 8b4510 c6040200 4a 79f6 }
// n = 4, score = 1200
// 8b4510 | mov eax, dword ptr [ebp + 0x10]
// c6040200 | mov byte ptr [edx + eax], 0
// 4a | dec edx
// 79f6 | jns 0xfffffff8
$sequence_3 = { 237878 899804010000 8b5864 23de 8b75fc }
// n = 5, score = 1200
// 237878 | and edi, dword ptr [eax + 0x78]
// 899804010000 | mov dword ptr [eax + 0x104], ebx
// 8b5864 | mov ebx, dword ptr [eax + 0x64]
// 23de | and ebx, esi
// 8b75fc | mov esi, dword ptr [ebp - 4]
$sequence_4 = { 6a00 ff36 ff15???????? bf02010000 3bc7 7561 }
// n = 6, score = 1200
// 6a00 | push 0
// ff36 | push dword ptr [esi]
// ff15???????? |
// bf02010000 | mov edi, 0x102
// 3bc7 | cmp eax, edi
// 7561 | jne 0x63
$sequence_5 = { 7508 6a03 58 e9???????? 39860c010000 }
// n = 5, score = 1200
// 7508 | jne 0xa
// 6a03 | push 3
// 58 | pop eax
// e9???????? |
// 39860c010000 | cmp dword ptr [esi + 0x10c], eax
$sequence_6 = { 75d9 8b45f8 5f 5e 5b c9 c3 }
// n = 7, score = 1200
// 75d9 | jne 0xffffffdb
// 8b45f8 | mov eax, dword ptr [ebp - 8]
// 5f | pop edi
// 5e | pop esi
// 5b | pop ebx
// c9 | leave
// c3 | ret
$sequence_7 = { 51 8d843078030000 50 e8???????? eb1d }
// n = 5, score = 1200
// 51 | push ecx
// 8d843078030000 | lea eax, [eax + esi + 0x378]
// 50 | push eax
// e8???????? |
// eb1d | jmp 0x1f
condition:
7 of them and filesize < 573440
}
rule Ransom_Cerber {
meta:
description= "Detect the risk of Ransomware Cerber Rule 6"
strings:
$s0 = {558BEC83EC0C8B45088945FC8B4D0C89}
$s1 = {8B45AB2603A9D1CBF8490724599ADA8F}
condition:
uint16(0) == 0x5a4d and all of them
}

View File

@@ -0,0 +1,14 @@
rule Ransom_Chaos {
meta:
description= "Detect the risk of Ransomware Chaos Rule 1"
hash1 = "08c82472215e1c5deda74584d2b685c04f4fa13c1d30cf3917f850f545bba82d"
hash2 = "a61ee15abf9142f2e3f311cf4dd54d1b2d2c7feb633c75083a8006cd0572ed29"
strings:
$s1 = "Coinmama - hxxps://www.coinmama.com Bitpanda - hxxps://www.bitpanda.com" fullword wide
$s2 = "read_it.txt" fullword wide
$s3 = "<EncryptedKey>" fullword wide
$s4 = "Your computer was infected with a ransomware virus." wide
condition:
( uint16(0) == 0x5a4d and 2 of them
) or ( all of them )
}

View File

@@ -0,0 +1,30 @@
rule Ransom_ChupaCabra {
meta:
description= "Detect the risk of Ransomware ChupaCabra Rule 1"
hash1 = "213d6a4c5a5c0045550fa2b822434c51dfd1b6f573c1d1bf22d9eda4f7ab2259"
hash2 = "ce900eefb44f7e49b9c17f35caeed82d0766b71c715b89a60346c0ae19d5df78"
hash3 = "7feeee667beb4d3b5f33611dc8a2735a1b23b9c7b11fa7b71ce33ea865b6c785"
strings:
$s1 = "PasswordEncrypt" fullword ascii
$s2 = "IMPORTANT INFORMATION!!!!" fullword wide
$s3 = "\\HowToDecrypt.txt" fullword wide
$s4 = "password_aes" fullword ascii
$s5 = "\\AX754VD.tmp" fullword wide
$s6 = "http://anubiscloud.xyz/" fullword wide
$s7 = "EncryptFiles" fullword ascii
$s8 = "RidjinEncrypt" fullword ascii
$s9 = "stringa" fullword ascii
$s10 = "ransomware" fullword ascii
$s11 = "loki_decrypt" fullword ascii
$s12 = "To Decrypt: " fullword wide
$s13 = "fuWinIni" fullword ascii
$s14 = "AESDecript" fullword ascii
$s15 = "uAction" fullword ascii
$s16 = "RansomwareCrypt" fullword ascii
$s17 = "v.2.0 Reload" fullword wide
$x1 = "bitcoin_keshel" fullword ascii
$x2 = "All your files are encrypted with ChupaCabra:"
condition:
( uint16(0) == 0x5a4d and filesize < 700KB and (( 5 of ($s*) ) or (any of ($x*)))
) or ( all of them )
}

101
yaraRules/Ransom.Common.yar Normal file
View File

@@ -0,0 +1,101 @@
import "pe"
rule Win_Trojan_Ransom_Common
{
meta:
description= "Detect the risk of Ransomware Common Rule 1"
strings:
$ = { e8ecfbfeffe9933b01006a146868df4400e8373e010033ff897de4 }
$ = { 4bfeffc7455cf668ce4bc745684653b55c8b }
$ = { 60e803000000e9eb045d4555c3e801000000eb5dbbedffffff03dd81eb0000090083bd7d04000000899d7d0400000f85c00300008d858904000050ff95090f00008985810400008bf08d7d515756ff95050f0000abb000ae75fd380775ee8d457affe05669727475616c416c6c6f63005669727475616c467265650056697274 }
$ = { 60bef1e04200bf00104000e80d21fdffb956090000e8bfffffffbf00304100e8f920fdffbf00704100b9dbb20000f3a4bf00904200e8e320fdffbf00b04200e8d920fdffbe009042008b4e0ce33a5651ff1500e0420009c0742389c58b34248b7e108b0fe311575155ff1504e042005f09c07409abebeb5e83c614ebccb8ffff }
$ = { 558bec83ec4868fc598658ff156e16400085c074030145c068b17f29fcff156e16400085c075df6a0068060100006a036a006a04680000006068346c4100ff153a18400083f8ff8945ec0f858e0000006a006843e2e68a6823bf726cff158a1640002145c06a0068bf934b5c68ac01c21aff158a16400068856b4100ff15ca15 }
$ = { 683c114000e8eeffffff000000000000300000004000000000000000f7fbe694f24d754290f5240ebdff2147000000000000010000000a0d0a436f6e726948517a686a45686c003d20226a6c00000000060000001c21400007000000f81a400007000000a41a400056423521f01f2a000000000000000000000000007e000000 }
$ = { 558bec81ecd0020000c685d3fdffffc06800401a00680000001fff151c714000898540fdffff8985c4fdffff6800880200680000b800ff1538714000ff15dc704000052cda0380018540fdffff0185c4fdffff89d6c685d0fdfffff7c685d1fdfffffcc685d4fdffffc48185c4fdffff10453c808bbdc4fdffff8b078985c8fd }
$ = { 558bec6aff6848614000689836400064a100000000506489250000000083c4c05356578965e8c745fc00000000c745d000000000eb098b45d083c0018945d0817dd0102700007d1eff150c504000a39c344100833d9c3441000075086a00ff1500504000ebd06a006a006800000400ff1510504000a39c34410068631000006a }
$ = { 40bb4ee673716c686f73742e646c6c00536553687574646f776e50726976696c656765005c5c2e5c504859534943414c44524956453000005c737973332e6578650000005c737973746d2e747874000072756e61730000006675636b65642d75702d73686974 }
$ = { 6d9f2261749b30726f951b73733600c001711b74436b0e726500000000480c5072611d657345001402791b744d491c756c1b3a696c1342616d1b2900003bff4478061f6e64f321766904216e6d1322000000007453ea0d696ed10c5700b1ff4272d31e7465f8266c65e1fff001f91a7446cf2365539f0a6545ae00e90488197274a3216c4100000000a21c6f633600c0036425616470196c6536002505811269745b46696c5300 }
$ = { 686c184000e8eeffffff000000000000300000003800000000000000e320f04819417b419fb6c109d57078030000000000000100000000000084fc0062616c7a6f00fb000000000007000000e06d400007000000806d400007000000386d400007000000646b4000070000008469400007000000d465400007000000785a4000 }
$ = { 354f465457415245000000006177747761337400326b336a3468696f753233342e646c6c }
$ = { 558bec83ec0c568b3540069b006840069b006bf652ff15902496008b0d40069b003d02400080756c85c9756853578b3d9424960083e611bb04000080eb0f8bc6257f0000808d46ff83e00b03f06a0153ffd783f80675e7bfc0289600b900f0ffff8d5514528bc723c1ba5a4596006a402bd023d152506affff1518229600e8f1 }
$ = { 558bec83ec18c745ecbeffdfbdc745f4bdffdfbdc745f012000000ff45f06808834000ff15ec8540006a33ff15e08540006a33ff15e48540008d }
$ = { e8f4490000e978feffff8325a454470000e8c94a0000a3a454470033c0c3cccccccccccccccccccccccccccc558bec83ec0883e4f0dd1c24f30f7e0424e808000000c9c3660f12442404660fc5c0036625ff7f662d2038663da8080f87d7010000660f14c0660f280d10384100660f59c8f20f2dd1660f281520384100660f58 }
$ = { 558bec892d2ce70210e8020000005dc3558bec83ec20535657c745f800000000c745e4e0140010a1201001108945f468037f00006a00ff152c1001108b4df40fb61181faff000000742a8b45f40fb60883f96a741f8b55f40fb6023d8b00000074128b4df40fb61183fa55740733c0e95d010000a1201001108945e08b0d3420 }
$ = { 68b0144000e8f0ffffff000000000000300000003800000000000000e3e703383595d0499655c676fec77d3700000000000001000000000000000000417072696c000000000000000700000088274000070000001c27400007000000602540000700000018254000010004004421400000000000ffffffffffffffff00000000 }
$ = { e9d6350000e97d390000e929290000e912350000e919240000e946290000e9b6380000e9062b0000e969250000e9d6350000e975260000e9482b0000e9b1390000e9d2370000e920210000e998340000e946320000e989280000e984380000e987240000e91a340000e9fd330000cccccccccccccccccccccccccccccccccccc }
$ = { 558bec51c745fc6edd0100892d10e70310e80a0000008be55dc3cccccccccccc558bec83ec3c53c745f800000000c745e420120010a1b45000108945f4ff15bc5000108b0d14500010894dc46a00ff152050001085c0750733c0e95a0100008b1528600210c60253a128600210c64001598b0d28600210c64102538d55f852a1 }
$ = { 6874144000e8f0ffffff00000000000030000000400053656d616e006a98f07187cc384581798af4453ad8ff0000000000000100000000010000000053656d616e6173656d6153656d616e000000000006000000f06a400001000500bc4f400000000000ffffffffffffffff000000000051400094b040000000000000008f05 }
$ = { 558bec51c745fc80cc0000892d10170410e85a0100008be55dc3cccccccccccc558bec51c745fc54420800c745fc54420800c745fc54420800c745fc54420800c745fc54420800c745fc54420800c745fc54420800c745fc54420800c745fc54420800c745fc54420800c745fc54420800c745fc54420800c745fc54420800c7 }
$ = { e9641a0000e9370e0000e9ad0e0000e997040000e9e2000000e9fe150000e9040d0000e9840f0000e9cf0f0000e9ff0c0000e9b1140000e9bf170000e92a050000e9a20e0000e9b4000000e95d120000e90d100000e94f150000e94e0f0000e9b0120000e9a3110000e9400c0000e970170000e947130000cccccccccccccccc }
$ = { 8b3da82040006681e7fcffb445b0508bc8fd66f2affc8a471f502c2c720f583c55770abb02304000e9cffefffff7f10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008bff558bec83ec4853ff33ff33e89201000083c4085b83ec }
$ = { 68a400000068000000006828af4000e85c30000083c40c6800000000e855300000a32caf4000680000000068001000006800000000e842300000a328af4000e8bc2f0000b8a8a04000a330af4000e8ed720000e80d710000e89a670000e8b75f0000e85d5f0000e8cf5e0000e817560000e8f6540000e8ba4e0000e88b4a0000 }
$ = { e984140000e953090000e9630e0000e918080000e992190000e9910c0000e9c8000000e9f5100000e9c8000000e9f30f0000e982130000e941110000e9b5000000e9520b0000e964190000e91e0c0000e9490e0000e9d10a0000e91c0a0000e974090000e97e080000e99f0f0000cccccccccccccccccccccccccccccccccccc }
$ = { 689090000068000000006880894000e85c30000083c40c6800000000e855300000a384894000680000000068001000006800000000e842300000a380894000e8bc2f0000b884814000a388894000e80d550000e825530000e82c4e0000e8fe4d0000e8033a0000e831390000e8a7380000e8c5320000e8f5300000c7058c8940 }
$ = { e9d80b0000e967090000e947100000e9630f0000e922190000e9e60c0000e90a100000e9660c0000e9bc0a0000e9b9000000e952100000e9d9010000e99b090000e9f9180000e9f00e0000e97e120000e96b010000e9a20b0000e9b5010000e9740e0000e92c0a0000e9c90f0000cccccccccccccccccccccccccccccccccccc }
$ = { 50006c006500610073006500200063006f006d0070006c0065007400650020007400680065002000730075007200760065007900200074006f00200075006e006c006f0063006b00200079006f0075007200200063006f006d007000750074006500720021 }
$ = { 33f68bc681c64028400083ee6d8b4eff6a558ac58ae10fc8598bf083c08f8b444802c1e80803f08d461d8038007421b21c38107213b2c03810770dbf0030400033c00f84ccfeffff33c064892060ebf8b970000000e20083e90175f9cc000000cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc }
$ = { 33f68bc681c6????400083ee6d8b4eff6a558ac58ae10fc8598bf083c08f8b444802c1e80803f08d461d8038007421b21c38107213b2c03810770dbf0030400033c00f84a0feffff33c064892060ebf8b970000000e20083e90175f9cc000000????????????????????????????????????????????????????????????cccc }
$ = { 2bf68bc681f64428400083ee6d8b4eff6a2a8ac58ae10fc8598bf083c08f8b4488048acc03f18d461d8038007423b21c38107213b2e03810770dbf0030400033c00f84edfeffff6a00ff1534274000ebf6b972000000e20083e90175f9fa000b9090909090909090909090909090909090909090909090909090909090909090 }
$ = { 2bf68bc681f64828400083ee6d8b4eff6a2a8ac58ae10fc8598bf083c08f8b4488048acc03f18d461d8038007423b21c38107213b2e03810770dbf0030400033c00f84e5feffff6a00ff1584274000ebf6b972000000e20083e90175f9fa000b9090909090909090909090909090909090909090909090909090909090909090 }
$ = { 6818050000680000000068a8454000e81310000083c40c6800000000e812100000a3ac454000680000000068001000006800000000e8ff0f0000a3a8454000e8ec190000e8c2160000e862120000e80d110000e876100000c705b445400014000000b8201900003b05b44540007c2d8b15b8454000ff35e84c4000e8301a0000 }
$ = { 558bec83e4f883ec4c53565768f0b340006810b4400033f656ff15ba8040006a096834b440006a09685cb440006a0468000c0000ff15c68040006890b4400068f4b44000ff15be804000688100000068890000006893080000ff15c28040008d44241c894424188d450450e823390000a3ecb3400033c066a368b64000a1ecb3 }
$ = { 6aff5941be0431400083ee6d8b46ff8bf0c1e6106633f6680a12400081ee20ff000050648b19648921b0503806740383c6108d86ac000000b61a3830720eb538382877088d3d004040007eae9d6a07ff3574304000ff0c24ff242400004490909090909090909090909090909090558bec83ec3857ff37ff37ff3753e8590000 }
$ = { 6a0059be0c31400083ee6d8b46ff8bd0c1e2106633d268ad11400081ea20ff000050648b19648921803a50740383c2088d82ac000000410fb6121bca7721b61a3a30731290b6383830770b8d3d004040007ea79d6a07ff357c304000ff0c24ff2424558bec83ec3457565051ff37e86b0b000083c4145f8be55d58ffd000558b }
$ = { 558bec83e4f883ec3c53565768d0134100c7442414afdfcaffc7442418aedfcaff6820154100ff15860241006a00ff157e0241008d442424894424188d5504e825ddffffa3a4134100a1a41341008b4004a398134100a1a41341008b4008a39c134100a1a41341008b400ca3a0134100c744240c00000000a198134100a3f012 }
$ = { 5589e583ec08c7042402000000ff157c314100e8a8feffff908db42600000000558b0da031410089e55dffe18d742600558b0d9431410089e55dffe1909090905589e5b8cd100000e8bb83000083e4f0b80000000083c00f83c00fc1e804c1e004898574efffff8b8574efffffe896830000e821830000c745f400000000c745 }
$ = { 68903a4000e8f0ffffff000000000000300000003800000000000000e3ea7bd202008844807bc3fd7cc88f27000000000000010000000450e00570ed54686973497300a400000000ffcc310005ccedb412b420f04ab7ee3152698cad4e0c707228a1a79344af62505ec820fc7b3a4fad339966cf11b70c00aa0060d393000000 }
$ = { b94e0e0000558bec83ec0c81052ac4400026c4400056c745f8e3eff20d68f0744000812526c4400007c54000c745f8e4eff20dff15487140008b3577c54000be003000003bc6c7052ec44000f65400000f821200000033c040c7051bc54000672c0000e9590300005381e3de6800008b1d44714000812583c540008c76000068 }
$ = { 68883d4000e8f0ffffff000040000000300000003800000000000000334c50709658ac4c998b4fd69cf9f0b800000000000001000000000000000000614d6172650000000000000000000000000000008800000000000000020000000400000053dca641c6a8594e908b33a627d537ea0100000098000000a800000001000000 }
$ = { 68a400000068000000006898864000e8fc2f000083c40c6800000000e8f52f0000a39c864000680000000068001000006800000000e8e22f0000a398864000e8fc3f0000e8213e0000e8a23c0000e8cc390000e8f2370000ba148140008d0dd4864000e8a02f0000ba518040008d0dcc864000e8902f0000ba898040008d0da4 }
$ = { 2d0d180000558bec83ec105329150baa4500c745fc1beff20d2bc056c7052baa450011000000833d2baa4500000f8478000000833d2baa4500130f8500000000a12baa450048a32baa4500e9d6ffffff8125b7aa450000000000e90d0000008b1db7aa450043891db7aa4500833db7aa4500100f8332000000833db7aa450004 }
$ = { 81e27c730000558bec83ec100d6f2d000053c745fc1beff20d8125b61e440000000000e90d0000008b1db61e440043891db61e4400833db61e44001e0f8314000000833db61e4400210f8500000000e9d4ffffff2bd856c705661e44001b000000833d661e4400000f847d000000833d661e4400070f8500000000833d661e44 }
$ = { ff746365f6ffefffff77f6f6fff6ffefffffeffffffff6fff6ffefffffeffff6ffeffffffff6ffefffffeffffff6ffefffff546f0174735a05f6ffefffff4461490072636565656572f6fff6ffefffffefffff6e6f726973f6ffeffff6ffefffffff006f6961746765017269726524626f6df6ffefffff490075744df6ffefffff65656b6a747274f6ffeffff6ffefffffff69655372006c69f6ffefffff65637565616501576d77f6ffefffff76f6ff }
$ = { 68c0324000e8f0ffffff0000000000003000000040000000000000009718d095d178574d8c9ecfd535de51b600000000000001000000000000000000496c5f5072616e7a6f0000000000000000000000ffcc3100073c33be2f4a1ca044bf40bbcfda18d8606cb22d8bde1af244909cdd860057b93d3a4fad339966cf11b70c00 }
$ = { e874240000e916feffff558bec81ec28030000a3c0434200890dbc4342008915b8434200891db44342008935b0434200893dac434200668c15d8434200668c0dcc434200668c1da8434200668c05a4434200668c25a0434200668c2d9c4342009c8f05d04342008b4500a3c44342008b4504a3c84342008d4508a3d44342008b }
$ = { bb535b0000558bec83ec0c8125a8674000702d0000c745f8f9a6bf30c745f8f8a6bf3081056c674000352800006878634000ff1510804100a16c6440003ddbb47c7fc705f0664000376a00000f85140000008105ac674000fc674000c7056c64400000000000810d04684000f46740008d45f4811df46640008c6d00008945fc }
$ = { 6a6068f0504000e87f030000bf940000008bc7e8771000008965e88bf4893e56ff15605040008b4e10890da47340008b4604a3b07340008b56088915b47340008b760c81e6ff7f00008935a873400083f902740c81ce008000008935a8734000c1e00803c2a3ac73400033f6568b3d1c504000ffd76681384d5a751f8b483c03 }
$ = { 683110400064ff350000000064892500000000e814050000e82d050000e8fe040000e8ff040000e80605000033db891bc3ff0d283040007401c3b81f1540002dd2104000a33a3040008d053e304000506a40ff353a30400068d2104000e8060500006800304000e802050000506800304000ff353a30400068d2104000e82900 }
$ = { e583ec08c7042402000000ff152cf14300e8a8feffff908db42600000000558b0d44f1430089e55dffe18d742600558b0d38f1430089e55dffe1909090905589e55de9c7400000909090909090905589e583ec188b450c0faf450c89450cc7042404000000e8e44300008945fc8b55fc8b450c8902c7042400b04300e8ed4400 }
$ = { 83C404C9C30000000000000000000000000000000000000000000000000000000000872C24558D6C24045189E981E90010000085012D001000003D001000007DEC29C1850189E089CC8B08FF60048B45ECC3E8F7FFFFFF8B008B00C3E8EDFFFFFF50E8EBFFFFFF50E8CD00000081C408000000C38B65E8E8D6FFFFFF50E8C0000000FFFFFFFFBA124000D2124000E9B7000000 }
$ = { 740068006900730020006900730020006E006F00740020006100200058006F0072006900730074002000760061007200690061006E0074 }
$ = "vssadmin.exe delete shadows /all" nocase
$ = "vssadmin delete shadows /all" nocase
$ = "You cannot recover them without paying us some money."
$ = "The price for the recovery software is "
$ = "<h3>How to Pay</h3><p>Send"
$ = "bcdedit /set {default} recoveryenabled no"
$ = "To decrypt all the data"
$ = "wmic shadowcopy delete /nointeractive" nocase
$ = "vssadmin resize shadowstorage /for" nocase
$ = "delete catalog -quiet" fullword wide
condition:
uint16(0) == 0x5a4d and any of them
}
rule Win_MSIL_Ransom
{
meta:
description= "Detect the risk of Ransomware Common Rule 2"
strings:
$a1 = "RijndaelManaged" ascii
$a2 = "GetDirectories" ascii
$a3 = "password" ascii
$a4 = "System.IO" ascii
$a5 = "GetFiles" ascii
$a6 = "System.Security.Cryptography" fullword ascii
$a7 = "encryptDirectory" fullword ascii
$b4 = "files have been encrypted" ascii wide nocase
$b5 = "files has been encrypted" ascii wide nocase
$b6 = "EncryptFile" ascii
$c1 = ".doc" fullword ascii wide
$c2 = ".docx" fullword ascii wide
$c3 = ".xls" fullword ascii wide
$c4 = ".xlsx" fullword ascii wide
$c5 = ".ppt" fullword ascii wide
$c6 = ".pptx" fullword ascii wide
$c7 = ".html" fullword ascii wide
$d1 = "Windows" fullword ascii wide
$d2 = "Program Files (x86)" fullword ascii wide
$d3 = "GetExtension" fullword ascii wide
condition:
uint16(0) == 0x5a4d and (all of ($a*) or (2 of ($b*) and 5 of ($a*)) or (all of ($c*) and 5 of ($a*)) or (all of ($d*) and 6 of ($a*))) and pe.imphash() == "f34d5f2d4577ed6d9ceec516c1f5a744"
}

200
yaraRules/Ransom.Conti.yar Normal file
View File

@@ -0,0 +1,200 @@
import "pe"
rule Ransom_Conti {
meta:
description= "Detect the risk of Ransomware Conti Rule 1"
strings:
$header = "MZ" ascii
$op1 = {B6 C0 B9 54 00 00 00 2B C8 6B C1 2C 99 F7 FE 8D 42 7F 99 F7 FE 88 57 FF}
$op2 = {83 EB 01 75 DD 8B 45 FC 5F 5B 40 5E 8B E5 5D C3 8D 46 01 5E 8B E5 5D C3}
condition:
$header at 0 and filesize < 500KB and (2 of them or pe.imphash()=="c2a4becf8f921158319527ff0049fea9" or pe.imphash()=="5a02193e843512ee9c9808884c6abd23" or pe.imphash()=="39dafb68ebe9859afe79428db28af625")
}
rule win_conti_auto {
meta:
description= "Detect the risk of Ransomware Conti Rule 2"
strings:
$sequence_0 = { 85c0 750f c705????????0b000000 e9???????? }
// n = 4, score = 600
// 85c0 | test eax, eax
// 750f | jne 0x11
// c705????????0b000000 |
// e9???????? |
$sequence_1 = { 0fb6c0 2bc8 8d04c9 c1e002 }
// n = 4, score = 500
// 0fb6c0 | movzx eax, al
// 2bc8 | sub ecx, eax
// 8d04c9 | lea eax, dword ptr [ecx + ecx*8]
// c1e002 | shl eax, 2
$sequence_2 = { 03c1 03c0 99 f7fb 8d427f }
// n = 5, score = 500
// 03c1 | add eax, ecx
// 03c0 | add eax, eax
// 99 | cdq
// f7fb | idiv ebx
// 8d427f | lea eax, dword ptr [edx + 0x7f]
$sequence_3 = { 753f 53 bb0c000000 57 }
// n = 4, score = 500
// 753f | jne 0x41
// 53 | push ebx
// bb0c000000 | mov ebx, 0xc
// 57 | push edi
$sequence_4 = { 753f 53 bb0a000000 57 8d7e01 8d7375 }
// n = 6, score = 500
// 753f | jne 0x41
// 53 | push ebx
// bb0a000000 | mov ebx, 0xa
// 57 | push edi
// 8d7e01 | lea edi, dword ptr [esi + 1]
// 8d7375 | lea esi, dword ptr [ebx + 0x75]
$sequence_5 = { 803900 7533 53 56 57 }
// n = 5, score = 500
// 803900 | cmp byte ptr [ecx], 0
// 7533 | jne 0x35
// 53 | push ebx
// 56 | push esi
// 57 | push edi
$sequence_6 = { 56 8bf1 8975fc 803e00 }
// n = 4, score = 500
// 56 | push esi
// 8bf1 | mov esi, ecx
// 8975fc | mov dword ptr [ebp - 4], esi
// 803e00 | cmp byte ptr [esi], 0
$sequence_7 = { 99 f7fb 8856ff 83ef01 75df }
// n = 5, score = 500
// 99 | cdq
// f7fb | idiv ebx
// 8856ff | mov byte ptr [esi - 1], dl
// 83ef01 | sub edi, 1
// 75df | jne 0xffffffe1
$sequence_8 = { 57 6a04 6800300000 6820005000 }
// n = 4, score = 400
// 57 | push edi
// 6a04 | push 4
// 6800300000 | push 0x3000
// 6820005000 | push 0x500020
$sequence_9 = { 6a01 6810660000 ff7508 ff15???????? }
// n = 4, score = 400
// 6a01 | push 1
// 6810660000 | push 0x6610
// ff7508 | push dword ptr [ebp + 8]
// ff15???????? |
$sequence_10 = { 6800100000 68???????? ff75f8 ff15???????? 85c0 7508 6a01 }
// n = 7, score = 400
// 6800100000 | push 0x1000
// 68???????? |
// ff75f8 | push dword ptr [ebp - 8]
// ff15???????? |
// 85c0 | test eax, eax
// 7508 | jne 0xa
// 6a01 | push 1
$sequence_11 = { 6aff ff75f0 ff15???????? ff75f4 ff15???????? }
// n = 5, score = 400
// 6aff | push -1
// ff75f0 | push dword ptr [ebp - 0x10]
// ff15???????? |
// ff75f4 | push dword ptr [ebp - 0xc]
// ff15???????? |
$sequence_12 = { 85c0 750f c705????????0a000000 e9???????? }
// n = 4, score = 400
// 85c0 | test eax, eax
// 750f | jne 0x11
// c705????????0a000000 |
// e9???????? |
$sequence_13 = { ff75fc ff15???????? e9???????? 6800800000 6a00 }
// n = 5, score = 400
// ff75fc | push dword ptr [ebp - 4]
// ff15???????? |
// e9???????? |
// 6800800000 | push 0x8000
// 6a00 | push 0
$sequence_14 = { 8bce e8???????? 8bb6007d0000 85f6 75ef 6aff 6a01 }
// n = 7, score = 400
// 8bce | mov ecx, esi
// e8???????? |
// 8bb6007d0000 | mov esi, dword ptr [esi + 0x7d00]
// 85f6 | test esi, esi
// 75ef | jne 0xfffffff1
// 6aff | push -1
// 6a01 | push 1
$sequence_15 = { 7605 b800005000 6a00 8d4c2418 51 50 ff742424 }
// n = 7, score = 400
// 7605 | jbe 7
// b800005000 | mov eax, 0x500000
// 6a00 | push 0
// 8d4c2418 | lea ecx, dword ptr [esp + 0x18]
// 51 | push ecx
// 50 | push eax
// ff742424 | push dword ptr [esp + 0x24]
$sequence_16 = { 7411 a801 740d 83f001 }
// n = 4, score = 400
// 7411 | je 0x13
// a801 | test al, 1
// 740d | je 0xf
// 83f001 | xor eax, 1
$sequence_17 = { 85c0 ba0d000000 0f44ca 890d???????? }
// n = 4, score = 300
// 85c0 | test eax, eax
// ba0d000000 | mov edx, 0xd
// 0f44ca | cmove ecx, edx
// 890d???????? |
$sequence_18 = { 83c10b f7e9 c1fa02 8bc2 }
// n = 4, score = 300
// 83c10b | add ecx, 0xb
// f7e9 | imul ecx
// c1fa02 | sar edx, 2
// 8bc2 | mov eax, edx
$sequence_19 = { 83c00b 99 83c117 f7f9 }
// n = 4, score = 300
// 83c00b | add eax, 0xb
// 99 | cdq
// 83c117 | add ecx, 0x17
// f7f9 | idiv ecx
$sequence_20 = { ffd0 8b0d???????? 85c0 ba0d000000 }
// n = 4, score = 300
// ffd0 | call eax
// 8b0d???????? |
// 85c0 | test eax, eax
// ba0d000000 | mov edx, 0xd
$sequence_21 = { ffd0 85c0 750f c705????????0c000000 }
// n = 4, score = 300
// ffd0 | call eax
// 85c0 | test eax, eax
// 750f | jne 0x11
// c705????????0c000000 |
$sequence_22 = { 83c10b f7e9 03d1 c1fa06 8bc2 c1e81f }
// n = 6, score = 300
// 83c10b | add ecx, 0xb
// f7e9 | imul ecx
// 03d1 | add edx, ecx
// c1fa06 | sar edx, 6
// 8bc2 | mov eax, edx
// c1e81f | shr eax, 0x1f
condition:
7 of them and filesize < 520192
}

View File

@@ -0,0 +1,15 @@
rule Ransom_Cryakl {
meta:
description = "Detect the risk of Ransomeware Cryakl Rule 1"
hash1 = "735abbb3b5a1e7eeb625696c92c08ca4cfda110c1f6627524ade4f368a311bc0"
strings:
$s1 = "bin:com:exe:bat:png:bmp:dat:log:ini:dll:sys:|||QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ" ascii
$s2 = "README.txt" fullword wide
$s3 = "/Create /RU SYSTEM /SC ONCE /TN VssDataRestore /F /RL HIGHEST /TR \"vssadmin delete shadows /all /quiet\" /st 00:00" fullword ascii
$s4 = "schtasks" fullword ascii
$s5 = "/Run /tn VssDataRestore" fullword ascii
$s6 = "software\\microsoft\\windows\\currentversion\\run" fullword ascii
condition:
uint16(0) == 0x5a4d and filesize < 1000KB and
3 of them
}

View File

@@ -0,0 +1,41 @@
rule Ransom_CryptoLocker {
meta:
description= "Detect the risk of Ransomware CryptoLocker Rule 1"
strings:
$s1 = {558BEC83EC0C56C745F8240100008B45}
$s2 = {8B45F82DE92E00002B45F48945F48D05}
condition:
uint16(0) == 0x5a4d and all of them
}
rule Ransom_Cryptolocker_2 {
meta:
description= "Detect the risk of Ransomware CryptoLocker Rule 2"
strings:
$s1 = {8B454821E8306DCFFF63804528050000}
condition:
uint16(0) == 0x5a4d and all of them
}
rule CryptoLocker {
meta:
description= "Detect the risk of Ransomware CryptoLocker Rule 3"
strings:
$x1 = "CryptoLocker" fullword wide
$x2 = ".betarasite" fullword wide
$x3 = "CMSTPBypass" fullword ascii
$s1 = "CommandToExecute" fullword ascii
$s2 = "SetInfFile" fullword ascii
$s3 = "SchoolPrject1" ascii
$s4 = "$730d5f64-bd57-47c1-9af4-d20aec714d02" fullword ascii
$s5 = "Encrypt" fullword ascii
$s6 = "Invalide Key! Please Try Again." fullword wide
$s7 = "RegAsm" fullword wide
$s8 = "Your key will be destroyed" wide
$s9 = "encrypted using RC4 and RSA-2048" wide
$c1 = "https://coinbase.com" fullword wide
$c2 = "https://localbictoins.com" fullword wide
$c3 = "https://bitpanda.com" fullword wide
condition:
uint16(0) == 0x5a4d and (all of ($x*) or all of ($s*) or (2 of ($x*) and 5 of ($s*)) or (all of ($c*) and 1 of ($x*) and 2 of ($s*)))
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,29 @@
rule Ransom_Fonix {
meta:
description= "Detect the risk of Ransomware Fonix Rule 1"
hash1 = "79288ff9ff7fd26aabc9b9220c98be69fc50d5962e99f313219c4b2512796d6a"
strings:
$x1 = "start cmd.exe /c taskkill /t /f /im sql* && taskkill /f /t /im veeam* && taskkill /F /T /IM MSExchange* && taskkill /F /T /IM Mi" ascii
$x2 = "start cmd.exe /c taskkill /t /f /im sql* && taskkill /f /t /im veeam* && taskkill /F /T /IM MSExchange* && taskkill /F /T /IM Mi" ascii
$x3 = "start cmd.exe /c \"C:\\ProgramData\\How To Decrypt Files.hta\" && exit" fullword ascii
$x4 = "start cmd.exe /c \"C:\\ProgramData\\WindowsUpdate.hta\" && exit" fullword ascii
$x5 = "reg add HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\ /v \"Michael Gillespie\" /t REG_SZ /d C:\\Program" ascii
$x6 = "reg add HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\ /v \"Michael Gillespie\" /t REG_SZ /d C:\\Pro" ascii
$x7 = "start cmd.exe /c wmic shadowcopy delete " fullword ascii
$x8 = "start cmd.exe /c bcdedit /set {default} boostatuspolicy ignoreallfailures " fullword ascii
$x9 = "schtasks /CREATE /SC ONLOGON /TN fonix /TR C:\\ProgramData\\XINOF.exe /RU SYSTEM /RL HIGHEST /F" fullword ascii
$x10 = "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF - 8\" /><title>windowse update</title> <HTA:APPLICATION icon=\"#\" WI" ascii
$x11 = "C:\\Users\\Phoenix\\Downloads\\cryptopp800\\sse_simd.cpp" fullword ascii
$x12 = "C:\\Users\\Phoenix\\Downloads\\cryptopp800\\sha_simd.cpp" fullword ascii
$x13 = "C:\\Users\\Phoenix\\Downloads\\cryptopp800\\chacha_avx.cpp" fullword ascii
$x14 = "start cmd.exe /c vssadmin Delete Shadows /All /Quiet " fullword ascii
$x15 = "C:\\Users\\Phoenix\\Downloads\\cryptopp800\\rijndael_simd.cpp" fullword ascii
$x16 = "start cmd.exe /c icacls * /grant Everyone:(OI)(CI)F /T /C /Q" fullword ascii
$x17 = "C:\\Users\\Phoenix\\Downloads\\cryptopp800\\chacha_simd.cpp" fullword ascii
$x18 = "start cmd.exe /c bcdedit /set {default} recoveryenabled no " fullword ascii
$x19 = "schtasks /CREATE /SC ONLOGON /TN exp /TR C:\\Windows\\explorer.exe /F" fullword ascii
$x20 = "schtasks /CREATE /SC ONLOGON /TN fonix /TR C:\\ProgramData\\XINOF.exe /F" fullword ascii
condition:
uint16(0) == 0x5a4d and
1 of ($x*)
}

View File

@@ -0,0 +1,101 @@
import "hash"
rule GandCrab_hash{
meta:
description= "Detect the risk of GandCrab Rule 1"
condition:
hash.sha256(0,filesize) =="49b769536224f160b6087dc866edf6445531c6136ab76b9d5079ce622b043200" or
hash.sha256(0,filesize) =="a45bd4059d804b586397f43ee95232378d519c6b8978d334e07f6047435fe926"
}
rule GandCrab {
meta:
description ="Detect the risk of GandCrab Rule 2"
hash1 = "ce9c9917b66815ec7e5009f8bfa19ef3d2dfc0cf66be0b4b99b9bebb244d6706"
strings:
$s1 = "tXujazajiyani voxazo. Wi wayepaxoli wuropiyenazizo fo. Cona leseyimucaye dupoxiyo. Nice mibehahasepa wudehukusidada garaterisovu" ascii
$s2 = "Gihepipigudi sirabuzogasoji. Sorizo sexabonera. Muyokeza niboru kikekimuxu rupo vojurotavugoyi. Yi yugose kadohajedumiya. Bedase" ascii
$s3 = " tixakehe. Reseyetasohora benusere vata kenevagume. Gedagu pegaleheruwago bukiredexuvuwa je. Yowujovu tuzudiposuxe zoyirudipu fo" ascii
$s4 = "imarijoyaneye vetuwipu. Fe. Bedopiyo comu jiye ze. Josusutime vumavizaseha. Pezofogijuxo nucosegogili bobi xayogaci. Kuyi letozo" ascii
$s5 = "**,,,," fullword ascii /* reversed goodware string ',,,,**' */
$s6 = "seyeruxiyehoxidecekajegexozaya gopegiyutusuwofobolikuhubu" fullword wide
$s7 = "Jetewavasaloge" fullword wide
$s8 = "vice zako wukewofeja vehe. Baji givihazi fuyacizogizanu. Gipayacucipi. Wetewavasa. Logeju xosidijoha ruxayo. Gorayo cicenehozogo" ascii
$s9 = "zimosafodi dusepe. Jacudagemuva falo miseyicuwatita koneyepijo. Sudotakupovete mulavifiposo xohilujusucu fususabo. Henihideya di" ascii
$s10 = "zumi gesakuki xoyefepuwahuje. Cugetutu. Nivileralu wafu jojoxaruku luraza punekuce. Dolape dubo. Jirehebeta jeda raguluyoda wohu" ascii
$s11 = "444F4,F44" fullword ascii /* hex encoded string 'DOOD' */
$s12 = "ale wufevujo kagomi haciceye. Yevaxudizera fasumatevakuvo kogumiwubo ta. Hutucozamevi jiharabeme bopobozeharu puyucite fuvukuyi." ascii
$s13 = "44,,,,,,4b" fullword ascii /* hex encoded string 'DK' */
$s14 = "jojukalo lijogagulucurukeyuroyupoheve mi" fullword wide
$s15 = "YKuluye sepuhe zi mosafodidusepe jacudagemuva falomiseyicuwa titako neyepijosu dotakupo ve" fullword wide
$s16 = "Yefepuwahuje cugetutu nivi le" fullword wide
$s17 = " yeruxiyeho xide cekajegexoza. Yagopegi. Yutu suwofo bo. Likuhubujojuka lolijogagulucu. Ru keyuro yupohevelivu dubiyuyinaxo. Dey" ascii
$s18 = "VUGOYIYIYUGOSEKADOHAJEDUMIYA" fullword wide
$s19 = "XCJSEUPAVJ" fullword wide
$s20 = "Eimnxjk" fullword ascii
$s21 = "ikernel32.dll" fullword wide
$s22 = "hulinowujovimuxatelo zabemaperetaboyazowa vituxifuyuyakixi" fullword ascii
$s23 = "Va penoyotoretunurosacidutezajogu fatixiposapapabicu boyokopusidonoyododusahehu" fullword ascii
$s24 = " Base Class Descriptor at (" fullword ascii
$s25 = "ruxayogorayocice" fullword wide
$s26 = "GDCB-DECRYPT.txt" wide
$s27 = "culico yami" fullword ascii
$s28 = "ReflectiveLoader" fullword ascii
condition:
uint16(0) == 0x5a4d and filesize < 1000KB and
4 of them
}
// From Malpedia
rule win_gandcrab_auto {
meta:
description ="Detect the risk of GandCrab Rule 3"
detail= "GandCrab Ransomware win_gandcrab_auto"
strings:
$sequence_0 = { ff15???????? 03c3 8d5e04 03d8 837f6000 }
$sequence_1 = { ff15???????? ff7728 8bf0 ff15???????? 03c3 8d5e04 }
$sequence_2 = { 03c3 8d5e04 03d8 837f1800 741b ff7720 ff15???????? }
$sequence_3 = { ff777c ff15???????? ff7778 8bf0 ff15???????? 03c3 }
$sequence_4 = { ff774c 8bf0 ff15???????? 03c3 8d5e04 03d8 }
$sequence_5 = { 8d5e04 03d8 837f3c00 741b ff7744 ff15???????? }
$sequence_6 = { ff772c ff15???????? ff7728 8bf0 ff15???????? 03c3 8d5e04 }
$sequence_7 = { 5f 66894c46fe 8bc6 5e 5b }
$sequence_8 = { 741b ff772c ff15???????? ff7728 8bf0 ff15???????? }
$sequence_9 = { 03c3 8d5e04 03d8 837f5400 741b ff775c ff15???????? }
condition:
any of them and filesize < 1024000
}
rule Gandcrab4
{
meta:
description ="Detect the risk of GandCrab Rule 4"
strings:
$hex1 = { 55 8B EC 83 EC ?? 53 56 ?? 3? ?? ?? ?? ?? 5? ?? }
$hex2 = { 8B 45 08 33 45 FC 89 ?1 ?C ?? ?? ?? ?? ?8 ?? ?? }
condition:
all of them and uint16(0) == 0x5A4D and filesize < 100KB
}
rule GandCrab5
{
meta:
description ="Detect the risk of GandCrab Rule 5"
strings:
$s1 = "&version=" wide ascii
$s2 = "/c timeout -c 5 & del \"%s\" /f /q" wide ascii
$s3 = "GANDCRAB" wide ascii
$t1 = "%s\\GDCB-DECRYPT.txt" wide ascii
$t2 = "%s\\KRAB-DECRYPT.txt" wide ascii
condition:
all of ($s*) and ($t1 or $t2)
}
rule Gandcrab_hash
{
meta:
description ="Detect the risk of GandCrab Rule 5"
condition:
hash.sha256(0,filesize) =="eb9207371e53414cfcb2094a2e34bd68be1a9eedbe49c4ded82b2adb8fa1d23d"
}

View File

@@ -0,0 +1,162 @@
import "hash"
rule Globeimposter {
meta:
description = "Detect the risk of Ransomware Globeimposter Rule 1"
hash1 = "e478fe703e64b417ed40b35dc5063e78afc00b26b867b12e648efd94d8be59cc"
strings:
$s1 = "fistulization7.dll" fullword ascii
$s2 = "Husmandsforeningen.exe" fullword wide
$s3 = "GetPrintProcessorDirectoryA" fullword ascii
$s4 = "C:\\Program Files (x86)\\Microsoft Visual Studio\\VB98\\VB6.OLB" fullword ascii
$s5 = "AShell_NotifyIconA" fullword ascii
$s6 = "EnumPortsA" fullword ascii
$s7 = "Tittupping" fullword ascii
$s8 = "Husmandsforeningen" fullword wide
$s9 = "Slappendes" fullword ascii
$s10 = "Cosmetics" fullword ascii
$s11 = "Besindedes" fullword ascii
$s12 = "Pimpstenens" fullword ascii
$s13 = "Pneumatogenic" fullword ascii
$s14 = "Epimorphosis8" fullword ascii
$s15 = "Antistimulation4" fullword ascii
$s16 = "Crithidia3" fullword ascii
$s17 = "Teksthenvisningen5" fullword ascii
$s18 = "Unpuddled7" fullword ascii
$s19 = "Underfakturerings6" fullword ascii
$s20 = "UY3 /i" fullword ascii
condition:
uint16(0) == 0x5a4d and filesize < 1000KB and
8 of them
}
rule Ransomware_Globeimposter {
meta:
description = "Detect the risk of Ransomware Globeimposter Rule 2"
hash1 = "e478fe703e64b417ed40b35dc5063e78afc00b26b867b12e648efd94d8be59cc"
strings:
$s1 = "fistulization7.dll" fullword ascii
$s2 = "Husmandsforeningen.exe" fullword wide
$s3 = "GetPrintProcessorDirectoryA" fullword ascii
$s4 = "C:\\Program Files (x86)\\Microsoft Visual Studio\\VB98\\VB6.OLB" fullword ascii
$s5 = "AShell_NotifyIconA" fullword ascii
$s6 = "EnumPortsA" fullword ascii
$s7 = "Tittupping" fullword ascii
$s8 = "Husmandsforeningen" fullword wide
$s9 = "Slappendes" fullword ascii
$s10 = "Cosmetics" fullword ascii
$s11 = "Besindedes" fullword ascii
$s12 = "Pimpstenens" fullword ascii
$s13 = "Pneumatogenic" fullword ascii
$s14 = "Epimorphosis8" fullword ascii
$s15 = "Antistimulation4" fullword ascii
$s16 = "Crithidia3" fullword ascii
$s17 = "Teksthenvisningen5" fullword ascii
$s18 = "Unpuddled7" fullword ascii
$s19 = "Underfakturerings6" fullword ascii
$s20 = "UY3 /i" fullword ascii
condition:
uint16(0) == 0x5a4d and filesize < 1000KB and
5 of them
}
rule win_globeimposter_auto {
meta:
description = "Detect the risk of Ransomware Globeimposter Rule 3"
strings:
$sequence_0 = { 0ff4d0 0f6e6604 0ff4e0 0f6e7608 0ff4f0 0f6e7e0c }
// n = 6, score = 700
// 0ff4d0 | pmuludq mm2, mm0
// 0f6e6604 | movd mm4, dword ptr [esi + 4]
// 0ff4e0 | pmuludq mm4, mm0
// 0f6e7608 | movd mm6, dword ptr [esi + 8]
// 0ff4f0 | pmuludq mm6, mm0
// 0f6e7e0c | movd mm7, dword ptr [esi + 0xc]
$sequence_1 = { 45 8364241000 8d442410 50 6880000000 8d44241c }
// n = 6, score = 700
// 45 | inc ebp
// 8364241000 | and dword ptr [esp + 0x10], 0
// 8d442410 | lea eax, [esp + 0x10]
// 50 | push eax
// 6880000000 | push 0x80
// 8d44241c | lea eax, [esp + 0x1c]
$sequence_2 = { 43 85d2 7e18 8d4e7c 8b41fc 3b01 }
// n = 6, score = 700
// 43 | inc ebx
// 85d2 | test edx, edx
// 7e18 | jle 0x1a
// 8d4e7c | lea ecx, [esi + 0x7c]
// 8b41fc | mov eax, dword ptr [ecx - 4]
// 3b01 | cmp eax, dword ptr [ecx]
$sequence_3 = { 8b450c 99 33c2 c745f401000000 }
// n = 4, score = 700
// 8b450c | mov eax, dword ptr [ebp + 0xc]
// 99 | cdq
// 33c2 | xor eax, edx
// c745f401000000 | mov dword ptr [ebp - 0xc], 1
$sequence_4 = { 48 8bfb 2bf8 89442414 }
// n = 4, score = 700
// 48 | dec eax
// 8bfb | mov edi, ebx
// 2bf8 | sub edi, eax
// 89442414 | mov dword ptr [esp + 0x14], eax
$sequence_5 = { 5e 5b 5f 5d 83c420 c20c00 }
// n = 6, score = 700
// 5e | pop esi
// 5b | pop ebx
// 5f | pop edi
// 5d | pop ebp
// 83c420 | add esp, 0x20
// c20c00 | ret 0xc
$sequence_6 = { 7e0e 8d4678 8928 41 8d4014 3b4e6c }
// n = 6, score = 700
// 7e0e | jle 0x10
// 8d4678 | lea eax, [esi + 0x78]
// 8928 | mov dword ptr [eax], ebp
// 41 | inc ecx
// 8d4014 | lea eax, [eax + 0x14]
// 3b4e6c | cmp ecx, dword ptr [esi + 0x6c]
$sequence_7 = { 7505 6ac4 58 eb2f }
// n = 4, score = 700
// 7505 | jne 7
// 6ac4 | push -0x3c
// 58 | pop eax
// eb2f | jmp 0x31
$sequence_8 = { 8d0445ffffffff 8945f0 8d45fc 8945f8 8d45f0 50 }
// n = 6, score = 700
// 8d0445ffffffff | lea eax, [eax*2 - 1]
// 8945f0 | mov dword ptr [ebp - 0x10], eax
// 8d45fc | lea eax, [ebp - 4]
// 8945f8 | mov dword ptr [ebp - 8], eax
// 8d45f0 | lea eax, [ebp - 0x10]
// 50 | push eax
$sequence_9 = { ff15???????? 85c0 7405 3975fc 7405 6afe 58 }
// n = 7, score = 700
// ff15???????? |
// 85c0 | test eax, eax
// 7405 | je 7
// 3975fc | cmp dword ptr [ebp - 4], esi
// 7405 | je 7
// 6afe | push -2
// 58 | pop eax
condition:
7 of them and filesize < 327680
}
rule globeimposter_hash
{
meta:
description ="Detect the risk of globeimposter Rule 4"
condition:
hash.sha256(0,filesize) =="70866cee3b129918e2ace1870e66801bc25a18efd6a8c0234a63fccaee179b68" or
hash.sha256(0,filesize) =="8b6993a935c33bbc028b2c72d7b2e769ff2cd5ad35331bc4d2dcce67a0c81569"
}

View File

@@ -0,0 +1,30 @@
import "pe"
rule henry217 {
meta:
description= "Detect the risk of Ransomware henry217 Rule 1"
hash1 = "8dd3fba314bdef96075961d8e0ee3a45d5a3030f89408d2b7f9d9fa5eedc66cd"
strings:
$s1 = "RansomeWare" ascii
$s2 = "AESEncrypt" fullword ascii
$s3 = {AE 5F 6F 8F C5 96 D1 9E}
$s4 = {59 00 6F 00 75 00 72 00 20 00 66 00 69 00 6C 00 65 00}
$s5 = {48 00 65 00 6C 00 6C 00 6F}
$o1 = {68 00 65 00 6E 00 72 00 79 00 32 00 31 00 37}
$o2 = {43 00 3A 00 5C 00 00 00 2E 00 73 00 79 00 73 00}
$pdb = {44 3A 5C D4 B4 C2 EB 5C [2-60] 2E 70 64 62}
$x1 = "RansomeWare.Form1.resources"
$x2 = "76a60872-fdf3-466a-9d80-a853c3485b32" nocase ascii wide
condition:
uint16(0) == 0x5a4d and filesize < 2000KB and ((all of ($s*) or 1 of ($o*)) or (1 of ($s*) and $pdb) or 1 of ($x*)) and pe.imphash() == "f34d5f2d4577ed6d9ceec516c1f5a744"
}
rule henry217_opcode {
meta:
description= "Detect the risk of Ransomware henry217 Rule 2"
hash1 = "8dd3fba314bdef96075961d8e0ee3a45d5a3030f89408d2b7f9d9fa5eedc66cd"
strings:
$opcode1 = {1B300400A9000000020000111F208D270000010A281800000A03068E696F1900000A6F1A00000A06068E69281B00000A1F108D270000010B281800000A04078E696F1900000A6F1A00000A07078E69281B00000A140C281C00000A0D731D00000A130411040906076F1E00000A17731F00000A130511050216028E696F2000000A11056F2100000A11046F2200000A0CDE0C11052C0711056F2300000ADCDE0C11042C0711046F2300000ADCDE0526140CDE00082A00000001280000020069001D86000C00000000020057003D94000C000000000000500052A2000513000001}
$opcode2 = {1B3005004F01000003000011036F2400000A0A16}
condition:
uint16(0) == 0x5a4d and filesize < 2000KB and (1 of them) and pe.imphash() == "f34d5f2d4577ed6d9ceec516c1f5a744"
}

View File

@@ -0,0 +1,32 @@
rule Ransom_HiddenTear_1
{
meta:
description= "Detect the risk of Ransomware HiddenTear Rule 1"
strings:
$s1 = "computerName" fullword ascii
$s2 = "userDir" fullword ascii
$s3 = "userName" fullword ascii
$s4 = "AES_Encrypt" fullword ascii
$s5 = "CreatePassword" fullword ascii
$op1 = {72????0070 28??00000A 6F??00000A 28??00000A 6F??00000A 26}
$x1 = "7ab0dd04-43e0-4d89-be59-60a30b766467" nocase ascii wide
condition:
uint16(0) == 0x5a4d and (4 of ($s*) or any of ($op*) and $x1)
}
rule MAL_RANSOM_COVID19_Apr20_1 {
meta:
description= "Detect the risk of Ransomware HiddenTear Rule 2"
detail= "Detects ransomware distributed in COVID-19 theme"
hash1 = "2779863a173ff975148cb3156ee593cb5719a0ab238ea7c9e0b0ca3b5a4a9326"
strings:
$s1 = "/savekey.php" wide
$op1 = { 3f ff ff ff ff ff 0b b4 }
$op2 = { 60 2e 2e 2e af 34 34 34 b8 34 34 34 b8 34 34 34 }
$op3 = { 1f 07 1a 37 85 05 05 36 83 05 05 36 83 05 05 34 }
condition:
uint16(0) == 0x5a4d and
filesize < 700KB and
2 of them
}

View File

@@ -0,0 +1,78 @@
import "hash"
rule RansomHouseRule1
{
meta:
description ="Detect the Malware of RansomHouse Rule 1, if you need help, call NSFOCUS's support team 400-8186868, please."
condition:
hash.sha256(0,filesize) =="f494629cab071bd384f7998014729d7537a9db0cf7d954b0ff74ea5235c11b1c"
}
rule RansomHouseRule2
{
meta:
description ="Detect the Malware of RansomHouse Rule 2, if you need help, call NSFOCUS's support team 400-8186868, please."
condition:
hash.sha256(0,filesize) =="f88c9366798cd5bd09bebf5b3e44f73c16825ae24dee2e89feeafe0875164348"
}
rule RansomHouseRule3{
meta:
description ="Detect the Malware of RansomHouse Rule 3, if you need help, call NSFOCUS's support team 400-8186868, please."
strings:
$s1 = "unknown error - system account operation failed" fullword ascii
$s2 = "command not found - does the file exist? do you run it like ./commandname if the file is in the same folder?" fullword ascii
$s3 = "warning - no output from process" fullword ascii
$s4 = "failed to create file to run process" fullword ascii
$s5 = "esxcli system account command not found" fullword ascii
$s6 = "failed to start process" fullword ascii
$s7 = "unknown error - operation failed" fullword ascii
$s8 = "failed to chmod file to run process" fullword ascii
$s9 = "Dear IT Department and Company Management! If you are reading this message, it means that your network infrastructure has been c" ascii
$s10 = "esxcli --formatter=csv vm process list" fullword ascii
$s11 = "process was killed by force" fullword ascii
$s12 = "rm -rf /var/log/*.log" fullword ascii
$s13 = "RunProcess" fullword ascii
$s14 = "ps | grep sshd | grep -v -e grep -e root -e 12345 | awk '{print \"kill -9\", $2}' | sh " fullword ascii
$s15 = "esxcli command not found" fullword ascii
$s16 = "esxcli --formatter=csv system account list" fullword ascii
$s17 = "esxcli --formatter=csv network ip interface ipv4 get" fullword ascii
$s18 = "Dear IT Department and Company Management! If you are reading this message, it means that your network infrastructure has been c" ascii
$s19 = "welcomeset" fullword ascii
$s20 = "ompromised. Look for 'How To Restore Your Files.txt' document for more information." fullword ascii
condition:
uint16(0) == 0x457f and filesize < 200KB and
8 of them
}
rule RansomHouseRule4{
meta:
description = "Detect the Malware of RansomHouse Rule 4, if you need help, call NSFOCUS's support team 400-8186868, please."
strings:
$s1 = "OxyKeyScout.exe" fullword wide
$s2 = "https://sectigo.com/CPS0" fullword ascii
$s3 = "https://sectigo.com/CPS0C" fullword ascii
$s4 = "N$.DlL" fullword ascii
$s5 = "3http://crt.usertrust.com/USERTrustRSAAddTrustCA.crt0%" fullword ascii
$s6 = "?http://crl.usertrust.com/USERTrustRSACertificationAuthority.crl0v" fullword ascii
$s7 = ",https://enigmaprotector.com/taggant/user.crl0" fullword ascii
$s8 = " <requestedExecutionLevel level='asInvoker' uiAccess='false' />" fullword ascii
$s9 = "(Symantec SHA256 TimeStamping Signer - G3" fullword ascii
$s10 = "(Symantec SHA256 TimeStamping Signer - G30" fullword ascii
$s11 = "http://ocsp.sectigo.com0&" fullword ascii
$s12 = "http://ocsp.sectigo.com0" fullword ascii
$s13 = "support@oxygen-forensic.com0" fullword ascii
$s14 = "2http://crt.sectigo.com/SectigoRSACodeSigningCA.crt0#" fullword ascii
$s15 = "2http://crl.sectigo.com/SectigoRSACodeSigningCA.crl0s" fullword ascii
$s16 = "3http://crl.sectigo.com/SectigoRSATimeStampingCA.crl0t" fullword ascii
$s17 = "+https://enigmaprotector.com/taggant/spv.crl0" fullword ascii
$s18 = "3http://crt.sectigo.com/SectigoRSATimeStampingCA.crt0#" fullword ascii
$s19 = "NNkz:\"J" fullword ascii
$s20 = "ETCkW:\\" fullword ascii
$op0 = { a4 00 0c 01 c8 d4 f2 af 34 50 c5 1b 1b 55 03 fc }
$op1 = { d3 0f 0c 01 34 0f 0c 01 }
$op2 = { 54 41 47 47 00 30 00 00 b6 1a 00 00 01 00 30 82 }
condition:
uint16(0) == 0x5a4d and filesize < 244000KB and
( 8 of them and all of ($op*) )
}

View File

@@ -0,0 +1,29 @@
rule Ransom_Lockbit {
meta:
description= "Detect the risk of Ransomware Lockbit Rule 1"
hash1 = "717585e9605ac2a971b7c7537e6e311bab9db02ecc6451e0efada9b2ff38b474"
strings:
$x1 = "powershell.exe -Command \"Get-ADComputer -filter * -Searchbase '%s' | foreach{ Invoke-GPUpdate -computer $_.name -force -RandomD" wide
$x2 = "cmd.exe /c \"shutdown.exe /r /f /t 0\"" fullword wide
$x3 = "C:\\Windows\\System32\\taskkill.exe" fullword wide
$s4 = "\"C:\\Windows\\system32\\mshta.exe\" \"%s\"" fullword wide
$s5 = "<Exec><Command>%s</Command><Arguments>%s</Arguments></Exec>" fullword wide
$s6 = " /C ping 127.0.0.7 -n 3 > Nul & fsutil file setZeroData offset=0 length=524288 \"%s\" & Del /f /q \"%s\"" fullword wide
$s7 = "C:\\windows\\system32\\%02X%02X%02X.ico" fullword wide
$s8 = "\\??\\C:\\windows\\system32\\%02X%02X%02X.ico" fullword wide
$s9 = "%%DesktopDir%%\\%02X%02X%02X.exe" fullword wide
$s10 = "%02X%02X%02X.exe" fullword wide
$s11 = "\\Registry\\Machine\\Software\\Classes\\Lockbit\\shell\\Open\\Command" fullword wide
$s12 = "You can provide us accounting data for the access to any company, for example, login and password to RDP, VPN, corporate email, " wide
$s13 = "\\\\%s\\ROOT\\CIMV2" fullword wide
$s14 = "https://tox.chat/download.html" fullword wide
$s15 = "LDAP://CN=%s,CN=Policies,CN=System,DC=%s,DC=%s" fullword wide
$s16 = "\\LockBit_Ransomware.hta" fullword wide
$s17 = "https://bigblog.at" fullword wide
$s18 = "\\NetworkShares.xml" fullword wide
$s19 = "\\Services.xml" fullword wide
$s20 = "RESTORE-MY-FILES.TXT" fullword wide
condition:
uint16(0) == 0x5a4d and
5 of them
}

185
yaraRules/Ransom.Locky.yar Normal file
View File

@@ -0,0 +1,185 @@
rule Ransom_Locky {
meta:
description= "Detect the risk of Ransomware Locky Rule 1"
hash1 = "5606e9dc4ab113749953687adac6ddb7b19c864f6431bdcf0c5b0e2a98cca39e"
hash2 = "8ff979f23f8bab94ce767d4760811bde66c556c0c56b72bb839d4d277b3703ad"
strings:
$s1 = "gefas.pdb" fullword ascii
$s2 = "ggqfslmb" fullword ascii
$s3 = "gr7shadtasghdj" fullword ascii
$s4 = "ppgnui.dll" fullword ascii
$s5 = "unqxfddunlkl" fullword ascii
$s6 = "hpmeiokm" fullword ascii
$s7 = "bdkc" fullword ascii
$s8 = {47 41 41 00 63 65 73 73 68 3B 41 41 00 82 04 24}
$s9 = {41 00 68 77 41 41 00 E8}
$s10 = "sctrs.dll" fullword ascii
$s11 = {61 8D 35 2E 41 41}
$pack = {00 ?? 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 E0 2E 64 65 63 00 00 00 00 00 00}
condition:
uint16(0) == 0x5a4d and filesize < 2000KB and 2 of them
}
rule win_locky_auto {
meta:
description= "Detect the risk of Ransomware Locky Rule 2"
strings:
$sequence_0 = { 33c9 8d8445e8fbffff c7461407000000 50 66890e 56 8d8de8fbffff }
// n = 7, score = 2100
// 33c9 | xor ecx, ecx
// 8d8445e8fbffff | lea eax, [ebp + eax*2 - 0x418]
// c7461407000000 | mov dword ptr [esi + 0x14], 7
// 50 | push eax
// 66890e | mov word ptr [esi], cx
// 56 | push esi
// 8d8de8fbffff | lea ecx, [ebp - 0x418]
$sequence_1 = { 85c0 7528 38450c 751e ff15???????? }
// n = 5, score = 2100
// 85c0 | test eax, eax
// 7528 | jne 0x2a
// 38450c | cmp byte ptr [ebp + 0xc], al
// 751e | jne 0x20
// ff15???????? |
$sequence_2 = { 7430 3bc7 5f 732b ff75fc 83661000 }
// n = 6, score = 2100
// 7430 | je 0x32
// 3bc7 | cmp eax, edi
// 5f | pop edi
// 732b | jae 0x2d
// ff75fc | push dword ptr [ebp - 4]
// 83661000 | and dword ptr [esi + 0x10], 0
$sequence_3 = { eb02 8bce 3bc1 740e 48 ebea }
// n = 6, score = 2100
// eb02 | jmp 4
// 8bce | mov ecx, esi
// 3bc1 | cmp eax, ecx
// 740e | je 0x10
// 48 | dec eax
// ebea | jmp 0xffffffec
$sequence_4 = { 8365fc00 56 83c9ff 8bf0 }
// n = 4, score = 2100
// 8365fc00 | and dword ptr [ebp - 4], 0
// 56 | push esi
// 83c9ff | or ecx, 0xffffffff
// 8bf0 | mov esi, eax
$sequence_5 = { 33ff 8d75b8 e8???????? 57 ff15???????? cc }
// n = 6, score = 2100
// 33ff | xor edi, edi
// 8d75b8 | lea esi, [ebp - 0x48]
// e8???????? |
// 57 | push edi
// ff15???????? |
// cc | int3
$sequence_6 = { 99 5e f7fe 8bf0 81fe48922409 }
// n = 5, score = 2100
// 99 | cdq
// 5e | pop esi
// f7fe | idiv esi
// 8bf0 | mov esi, eax
// 81fe48922409 | cmp esi, 0x9249248
$sequence_7 = { c3 8b00 85c0 7407 50 ff15???????? c3 }
// n = 7, score = 2100
// c3 | ret
// 8b00 | mov eax, dword ptr [eax]
// 85c0 | test eax, eax
// 7407 | je 9
// 50 | push eax
// ff15???????? |
// c3 | ret
$sequence_8 = { 8b442408 f7e1 03d3 5b c21000 e9???????? 8bff }
// n = 7, score = 1400
// 8b442408 | mov eax, dword ptr [esp + 8]
// f7e1 | mul ecx
// 03d3 | add edx, ebx
// 5b | pop ebx
// c21000 | ret 0x10
// e9???????? |
// 8bff | mov edi, edi
$sequence_9 = { e9???????? 90 31c0 e9???????? 90 }
// n = 5, score = 700
// e9???????? |
// 90 | nop
// 31c0 | xor eax, eax
// e9???????? |
// 90 | nop
$sequence_10 = { 8d36 e9???????? 90 8d6d00 90 }
// n = 5, score = 700
// 8d36 | lea esi, [esi]
// e9???????? |
// 90 | nop
// 8d6d00 | lea ebp, [ebp]
// 90 | nop
$sequence_11 = { 31c0 90 e9???????? 8d36 90 }
// n = 5, score = 700
// 31c0 | xor eax, eax
// 90 | nop
// e9???????? |
// 8d36 | lea esi, [esi]
// 90 | nop
$sequence_12 = { 90 e9???????? 90 59 e9???????? 90 }
// n = 6, score = 700
// 90 | nop
// e9???????? |
// 90 | nop
// 59 | pop ecx
// e9???????? |
// 90 | nop
$sequence_13 = { 5e c21000 8bff 55 8bec 33c0 8b4d08 }
// n = 7, score = 700
// 5e | pop esi
// c21000 | ret 0x10
// 8bff | mov edi, edi
// 55 | push ebp
// 8bec | mov ebp, esp
// 33c0 | xor eax, eax
// 8b4d08 | mov ecx, dword ptr [ebp + 8]
$sequence_14 = { e8???????? e9???????? 8d09 e9???????? 90 }
// n = 5, score = 700
// e8???????? |
// e9???????? |
// 8d09 | lea ecx, [ecx]
// e9???????? |
// 90 | nop
$sequence_15 = { e9???????? 90 8d00 90 e9???????? 8d09 }
// n = 6, score = 700
// e9???????? |
// 90 | nop
// 8d00 | lea eax, [eax]
// 90 | nop
// e9???????? |
// 8d09 | lea ecx, [ecx]
condition:
7 of them and filesize < 1122304
}
// From ClamAV
rule Win_Ransomware_Locky
{
meta:
description= "Detect the risk of Ransomware Locky Rule 3"
strings:
$a0 = { 558bec518d45??50ff15[4]50ff15[4]85c074158b4d??83f9027c0dff7488fcff15[4]59c9c333c0c9c3 }
$a1 = { 558bec5156578d45??50ff15[4]50ff15[4]8bf085f6741b837d??027c15ff7604ff15[4]59568bf8ff15[4]eb0233ff8bc75f5ec9c3 }
$a2 = { 8d45??5068[4]c745??47657454c745??69636b43c745??6f756e74c645??00ff15[4]50ff15[4]8945??ffd0 }
$a3 = { F51A5B38A8AF95760C8CF179CB43474580A5E48E2D74EF4E56660CA4A2A1407D }
condition:
any of them
}

View File

@@ -0,0 +1,28 @@
rule Ransom_MBRLocker {
meta:
description= "Detect the risk of Ransomware MBRLocker Rule 1"
strings:
$s1 = "PhysicalDrive0" nocase
$s2 = "Your disk have a lock!" nocase
$s3 = "Please input the unlock password!" nocase
$s4 = {5bc678014e0d80fd8d858fc731384f4dff01ff01ff01ff01ff01}
$s5 = {5bc678014e0d53ef4ee54e3a7a7a7684}
$s6 = "jiesuo+qq"
$s7 = "jiesuo+QQ"
$x1 = {566A0068800000006A036A006A0168000000406828645900ff15????????8B}
$x2 = "CreateFileA" fullword ascii
condition:
uint16(0) == 0x5a4d and $s1 and 3 of them
}
rule KillMBR {
meta:
description= "Detect the risk of Ransomware MBRLocker Rule 2"
strings:
$s1 = "\\\\.\\PhysicalDrive" ascii
$s2 = "/logger.php" ascii
$s3 = "Ooops! Your MBR was been rewritten" ascii
$s4 = "No, this ransomware dont encrypt your files, erases it" ascii
condition:
uint16(0) == 0x5a4d and (2 of them and #s1 > 10)
}

View File

@@ -0,0 +1,16 @@
import "hash"
rule Magniber_hash
{
meta:
description ="Detect the risk of Magniber Rule 1"
condition:
hash.sha256(0,filesize) == "a09b48239e7aba75085e2217e13da0eb1cb8f01a2e4e08632769097e0c412b9f"
}
rule Ransom_Magniber {
meta:
description ="Detect the risk of Magniber Rule 2"
strings:
$header = {4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 B0 00 00 00 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50 45 00 00 64 86 01 00 ?? ?? ?? 60 00 00 00 00 00 00 00 00 F0 00 22 00 0B 02 0B 00 00 52 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 10 00 00 00 00 00 40 01 00 00 00 00 10 00 00 00 02 00 00 06 00 00 00 00 00 00 00 06 00 00 00 00 00 00 00 00 70 00 00 00 02 00 00 00 00 00 00 02 00 60 81 00 00 10 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2E 74 65 78 74 00 00 00 ?? 51 00 00 00 10 00 00 00 52 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 56 EB}
condition:
$header at 0 and filesize < 30KB
}

174
yaraRules/Ransom.Makop.yar Normal file
View File

@@ -0,0 +1,174 @@
rule RANSOM_makop
{
meta:
description= "Detect the risk of Ransomware Makop Rule 1"
hash = "008e4c327875110b96deef1dd8ef65cefa201fef60ca1cbb9ab51b5304e66fe1"
strings:
$pattern_0 = { 50 8d7c2420 e8???????? 84c0 0f84a6020000 8b742460 ba???????? }
$pattern_1 = { 51 52 53 ffd5 85c0 746d 8b4c240c }
$pattern_2 = { 7521 68000000f0 6a18 6a00 6a00 56 ff15???????? }
$pattern_3 = { 83c40c 8d4e0c 51 66c7060802 66c746041066 c6460820 }
$pattern_4 = { 51 ffd3 50 ffd7 8b4628 85c0 }
$pattern_5 = { 85c9 741e 8b4508 8b4d0c 8a11 }
$pattern_6 = { 83c002 6685c9 75f5 2bc6 d1f8 66390c46 8d3446 }
$pattern_7 = { 895a2c 8b7f04 85ff 0f85f7feffff 55 6a00 }
$pattern_8 = { 8b3d???????? 6a01 6a00 ffd7 50 ff15???????? }
$pattern_9 = { 85c0 7407 50 ff15???????? }
condition:
7 of them and
filesize < 237568
}
rule win_makop_ransomware_auto {
meta:
description= "Detect the risk of Ransomware Makop Rule 2"
strings:
$sequence_0 = { 6a04 8d542408 52 6a18 50 c744241400000000 ff15???????? }
// n = 7, score = 100
// 6a04 | push 4
// 8d542408 | lea edx, [esp + 8]
// 52 | push edx
// 6a18 | push 0x18
// 50 | push eax
// c744241400000000 | mov dword ptr [esp + 0x14], 0
// ff15???????? |
$sequence_1 = { 8d442410 e8???????? 6a00 6a00 6a00 6a00 }
// n = 6, score = 100
// 8d442410 | lea eax, [esp + 0x10]
// e8???????? |
// 6a00 | push 0
// 6a00 | push 0
// 6a00 | push 0
// 6a00 | push 0
$sequence_2 = { 7403 50 ffd6 8b442410 83f8ff 7403 }
// n = 6, score = 100
// 7403 | je 5
// 50 | push eax
// ffd6 | call esi
// 8b442410 | mov eax, dword ptr [esp + 0x10]
// 83f8ff | cmp eax, -1
// 7403 | je 5
$sequence_3 = { 57 6a2c 33db 53 ffd6 8b3d???????? }
// n = 6, score = 100
// 57 | push edi
// 6a2c | push 0x2c
// 33db | xor ebx, ebx
// 53 | push ebx
// ffd6 | call esi
// 8b3d???????? |
$sequence_4 = { 0fb74c1702 83c202 0fb7ee 2bcd 74e8 33ed 3bcd }
// n = 7, score = 100
// 0fb74c1702 | movzx ecx, word ptr [edi + edx + 2]
// 83c202 | add edx, 2
// 0fb7ee | movzx ebp, si
// 2bcd | sub ecx, ebp
// 74e8 | je 0xffffffea
// 33ed | xor ebp, ebp
// 3bcd | cmp ecx, ebp
$sequence_5 = { 7420 837c240c08 7219 8b442410 8b4c2414 50 51 }
// n = 7, score = 100
// 7420 | je 0x22
// 837c240c08 | cmp dword ptr [esp + 0xc], 8
// 7219 | jb 0x1b
// 8b442410 | mov eax, dword ptr [esp + 0x10]
// 8b4c2414 | mov ecx, dword ptr [esp + 0x14]
// 50 | push eax
// 51 | push ecx
$sequence_6 = { 85c0 751a ff15???????? 8b4c2404 51 ff15???????? 32c0 }
// n = 7, score = 100
// 85c0 | test eax, eax
// 751a | jne 0x1c
// ff15???????? |
// 8b4c2404 | mov ecx, dword ptr [esp + 4]
// 51 | push ecx
// ff15???????? |
// 32c0 | xor al, al
$sequence_7 = { 56 6a00 ffd7 50 ff15???????? 6a08 }
// n = 6, score = 100
// 56 | push esi
// 6a00 | push 0
// ffd7 | call edi
// 50 | push eax
// ff15???????? |
// 6a08 | push 8
$sequence_8 = { ffd3 50 ffd7 8b4628 85c0 741a b92c000000 }
// n = 7, score = 100
// ffd3 | call ebx
// 50 | push eax
// ffd7 | call edi
// 8b4628 | mov eax, dword ptr [esi + 0x28]
// 85c0 | test eax, eax
// 741a | je 0x1c
// b92c000000 | mov ecx, 0x2c
$sequence_9 = { 8b442418 8b542414 8bcf e8???????? 85c0 0f84db020000 8b442414 }
// n = 7, score = 100
// 8b442418 | mov eax, dword ptr [esp + 0x18]
// 8b542414 | mov edx, dword ptr [esp + 0x14]
// 8bcf | mov ecx, edi
// e8???????? |
// 85c0 | test eax, eax
// 0f84db020000 | je 0x2e1
// 8b442414 | mov eax, dword ptr [esp + 0x14]
condition:
7 of them and filesize < 107520
}
rule win_makop_ransomware_w0 {
meta:
description= "Detect the risk of Ransomware Makop Rule 3"
strings:
$str1 = "-%08X"
$str2 = "MPR.dll"
$str3 = "\\*.*" wide
$dec1 = { 8b ?? ?? 6a 08 8d ?? ?? ?? 52 8d ?? ?? ?? 50 e8 ?? ?? ?? ?? 66 ?? ?? ?? ?? 66 ?? ?? ?? ?? 83 c4 0c 66 3b c1 76 ?? 0f b7 c9 0f b7 f8 2b f9 74 ?? 57 6a 00 ff ?? ?? ?? ?? ?? 50 ff ?? ?? ?? ?? ?? 8b d8 85 db 74 ?? 0f ?? ?? ?? ?? 03 ?? ?? 57 52 53 e8 ?? ?? ?? ?? 83 c4 0c 8d ?? ?? 55 ff ?? ?? ?? ?? ?? e8 ?? ?? ?? ?? 84 c0 74 ?? 8b ?? ?? ?? 50 53 6a 00 6a 00 89 ?? 8b ?? ?? 6a 00 50 ff ?? ?? ?? ?? ?? 85 c0 75 ?? ff ?? ?? ?? ?? ?? 50 e8 ?? ?? ?? ?? 83 c4 04 33 c0 5f 5e 5d 5b 83 c4 0c c2 08 00}
$start = {55 8b ec 83 e4 f8 a1 ?? ?? ?? ?? 81 ec 64 02 00 00 85 c0 53 56 57 74 ?? 6a 00 50 ff ?? ?? ?? ?? ?? 85 c0 0f ?? ?? ?? ?? ?? 8b ?? ?? 0f ?? ?? ?? 8b ?? ?? 51 e8 ?? ?? ?? ?? 83 c4 04 84 c0 0f ?? ?? ?? ?? ?? 8b ?? ?? 8d ?? ?? 8d ?? ?? 85 c0 0f ?? ?? ?? ?? ?? 50 6a 00 ff ?? ?? ?? ?? ?? 50 ff ?? ?? ?? ?? ?? 8b f0 85 f6 0f ?? ?? ?? ?? ?? 8b ?? ?? 80 ?? ?? ?? 75 ?? 81 fb fa 00 00 00 72 ?? 8b ?? ?? ?? ?? ?? 8b de e8 ?? ?? ?? ?? 8b ?? ?? 8b ?? ?? 83 c7 04 8d ?? ?? e8 ?? ?? ?? ?? 8b ?? ?? 8d ?? ?? ?? bf 05 00 00 00 eb ??}
condition:
( uint16(0) == 0x5a4d and
( 4 of them )
) or ( all of them )
}
rule Makop_Ransomware {
meta:
description= "Detect the risk of Ransomware Makop Rule 4"
hash1 = "082a2ce2dde8b3a50f2d499496879e85562ee949cb151c8052eaaa713cddd0f8"
strings:
$s1 = "MPR.dll" fullword ascii
$s2 = "-%08X" fullword ascii
$api1 = {43 72 79 70 74 47 65 6E 52 61 6E 64 6F 6D 00 00 CA 00 43 72 79 70 74 49 6D 70 6F 72 74 4B 65 79 00 00 BA 00 43 72 79 70 74 45 6E 63 72 79 70 74}
$api2 = {B7 00 43 72 79 70 74 44 65 73 74 72 6F 79 4B 65 79 00 B4 00 43 72 79 70 74 44 65 63 72 79 70 74 00 00 B1 00 43 72 79 70 74 41 63 71 75 69 72 65 43 6F 6E 74 65 78 74 57}
$api3 = {10 00 57 4E 65 74 43 6C 6F 73 65 45 6E 75 6D 00 3D 00 57 4E 65 74 4F 70 65 6E 45 6E 75 6D 57 00 1C 00 57 4E 65 74 45 6E 75 6D 52 65 73 6F 75 72 63 65 57 00 4D 50 52 2E 64 6C 6C}
condition:
uint16(0) == 0x5a4d and filesize < 200KB and
3 of them
}
rule Makop_Ransomware_2 {
meta:
description= "Detect the risk of Ransomware Makop Rule 5"
hash1 = "082a2ce2dde8b3a50f2d499496879e85562ee949cb151c8052eaaa713cddd0f8"
strings:
$s1 = "CryptSetKeyParam" fullword ascii
$s2 = "CryptImportKey" fullword ascii
$opcode1 = {8B 44 24 08 8B 0E 57 6A 00 6A 00 6A 2C 50 51 FF 15 [4] 85 C0 75 0C}
$opcode2 = {6A 00 52 6A 01 50 FF 15 [4] 85 C0}
condition:
uint16(0) == 0x5a4d and filesize < 200KB and
all of them
}

View File

@@ -0,0 +1,18 @@
rule Ransom_MedusaLocker {
meta:
description= "Detect the risk of Ransomware MedusaLocker Rule 1"
hash1 = "1e2335fef46f7320069623fff6702acb41c2877aff5fec83d94a561af37c3c7a"
strings:
$exts = ".exe,.dll,.sys,.ini,.lnk,.rdp,.encrypted,.READINSTRUCTIONS,.recoverme,.Readinstructions,.hivteam,.hiv,.386,.adv,.ani,.bat,.bin,." ascii
$process1 = "wxServer.exe,wxServerView,sqlservr.exe,sqlmangr.exe,RAgui.exe,supervise.exe,Culture.exe,RTVscan.exe,Defwatch.exe,sqlbrowser.exe," ascii
$process2 = "DtSrvr.exe,tomcat6.exe,java.exe,360se.exe,360doctor.exe,wdswfsafe.exe,fdlauncher.exe,fdhost.exe,GDscan.exe,ZhuDongFangYu.exe" fullword ascii
$delshadows = "vssadmin.exe Delete Shadows /All /Quiet" fullword wide
$s1 = "<!-- !!! dont changing this !!! -->" fullword ascii
$s2 = "\\Users\\All Users" fullword wide
$s3 = "[LOCKER] Kill processes" fullword wide
$s4 = " <!-- -->" fullword ascii
$s5 = "[LOCKER] Is already running" fullword wide
condition:
uint16(0) == 0x5a4d and
3 of them
}

189
yaraRules/Ransom.Nemty.yar Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,20 @@
rule Ransom_NoCry {
meta:
description= "Detect the risk of Ransomware NoCry Rule 1"
hash1 = "486f2053c32ba44eb2afaf87e1ba8d8db408ef09cb7d895f3a8dc0f4081a7467"
strings:
$a1 = "https://www.google.com/search?q=how+to+buy+bitcoin"
$a2 = "C:\\Users\\ku5h2\\OneDrive\\Desktop\\NoCry Discord\\ransomeware\\obj\\Debug\\NoCry.pdb" fullword ascii
$a3 = " worth of bitcoin to this address:"
$a4 = "Ooooops All Your Files Are Encrypted ,NoCry"
$a5 = "NoCry.Form4.resources"
$a6 = "Decryption : Working * "
$a7 = "Runcount.cry"
$aop1 = {28 36 00 00 0A 00 1F FE 0A 18 0C 02 19 17 73 EE 00 00 0A 80 4E 00 00 04 19 0C 03 1A 18 73 EE 00 00 0A 80 4F 00 00}
$b1 = "EncryptOrDecryptFile" fullword ascii
$b2 = "bytKey" fullword ascii
$b3 = "MD5HASH" fullword ascii
condition:
uint16(0) == 0x5a4d and (any of ($a*) or all of ($b*))
}

273
yaraRules/Ransom.Petya.yar Normal file
View File

@@ -0,0 +1,273 @@
rule win_petya_auto {
meta:
description= "Detect the risk of Ransomware Petya Rule 1"
strings:
$sequence_0 = { 8d4e28 e8???????? 8d4e4c e8???????? }
// n = 4, score = 600
// 8d4e28 | lea ecx, [esi + 0x28]
// e8???????? |
// 8d4e4c | lea ecx, [esi + 0x4c]
// e8???????? |
$sequence_1 = { 8bc6 c1e810 88442429 8bc6 c1e808 8844242a }
// n = 6, score = 600
// 8bc6 | mov eax, esi
// c1e810 | shr eax, 0x10
// 88442429 | mov byte ptr [esp + 0x29], al
// 8bc6 | mov eax, esi
// c1e808 | shr eax, 8
// 8844242a | mov byte ptr [esp + 0x2a], al
$sequence_2 = { 0f42f2 6a04 56 e8???????? 8bd8 }
// n = 5, score = 600
// 0f42f2 | cmovb esi, edx
// 6a04 | push 4
// 56 | push esi
// e8???????? |
// 8bd8 | mov ebx, eax
$sequence_3 = { 6a04 6a20 c705????????20000000 e8???????? }
// n = 4, score = 600
// 6a04 | push 4
// 6a20 | push 0x20
// c705????????20000000 |
// e8???????? |
$sequence_4 = { 51 83c050 03c7 53 50 e8???????? }
// n = 6, score = 600
// 51 | push ecx
// 83c050 | add eax, 0x50
// 03c7 | add eax, edi
// 53 | push ebx
// 50 | push eax
// e8???????? |
$sequence_5 = { e8???????? 8d4e10 e8???????? 8d4e1c e8???????? 8d4e28 e8???????? }
// n = 7, score = 600
// e8???????? |
// 8d4e10 | lea ecx, [esi + 0x10]
// e8???????? |
// 8d4e1c | lea ecx, [esi + 0x1c]
// e8???????? |
// 8d4e28 | lea ecx, [esi + 0x28]
// e8???????? |
$sequence_6 = { c7461001000000 33c0 5e 8be5 }
// n = 4, score = 600
// c7461001000000 | mov dword ptr [esi + 0x10], 1
// 33c0 | xor eax, eax
// 5e | pop esi
// 8be5 | mov esp, ebp
$sequence_7 = { 8bda c1e60e c1e017 33ff 0bf9 c1eb09 8b4c2424 }
// n = 7, score = 600
// 8bda | mov ebx, edx
// c1e60e | shl esi, 0xe
// c1e017 | shl eax, 0x17
// 33ff | xor edi, edi
// 0bf9 | or edi, ecx
// c1eb09 | shr ebx, 9
// 8b4c2424 | mov ecx, dword ptr [esp + 0x24]
$sequence_8 = { 7617 53 33db 8b4e74 03cb }
// n = 5, score = 600
// 7617 | jbe 0x19
// 53 | push ebx
// 33db | xor ebx, ebx
// 8b4e74 | mov ecx, dword ptr [esi + 0x74]
// 03cb | add ecx, ebx
$sequence_9 = { 8d4e10 e8???????? 8d4e1c e8???????? 8d4e28 e8???????? }
// n = 6, score = 600
// 8d4e10 | lea ecx, [esi + 0x10]
// e8???????? |
// 8d4e1c | lea ecx, [esi + 0x1c]
// e8???????? |
// 8d4e28 | lea ecx, [esi + 0x28]
// e8???????? |
condition:
7 of them and filesize < 229376
}
rule win_eternal_petya_auto {
meta:
description= "Detect the risk of Ransomware Petya Rule 2"
strings:
$sequence_0 = { 8bec 51 57 68000000f0 }
// n = 4, score = 400
// 8bec | mov ebp, esp
// 51 | push ecx
// 57 | push edi
// 68000000f0 | push 0xf0000000
$sequence_1 = { 68f0000000 6a40 ff15???????? 8bd8 }
// n = 4, score = 400
// 68f0000000 | push 0xf0
// 6a40 | push 0x40
// ff15???????? |
// 8bd8 | mov ebx, eax
$sequence_2 = { 57 68000000f0 6a18 33ff }
// n = 4, score = 400
// 57 | push edi
// 68000000f0 | push 0xf0000000
// 6a18 | push 0x18
// 33ff | xor edi, edi
$sequence_3 = { 53 8d4644 50 53 6a02 }
// n = 5, score = 400
// 53 | push ebx
// 8d4644 | lea eax, [esi + 0x44]
// 50 | push eax
// 53 | push ebx
// 6a02 | push 2
$sequence_4 = { 40 49 75f9 56 ff15???????? }
// n = 5, score = 400
// 40 | inc eax
// 49 | dec ecx
// 75f9 | jne 0xfffffffb
// 56 | push esi
// ff15???????? |
$sequence_5 = { 53 6a21 8d460c 50 }
// n = 4, score = 400
// 53 | push ebx
// 6a21 | push 0x21
// 8d460c | lea eax, [esi + 0xc]
// 50 | push eax
$sequence_6 = { 50 8d8594f9ffff 50 894dac }
// n = 4, score = 300
// 50 | push eax
// 8d8594f9ffff | lea eax, [ebp - 0x66c]
// 50 | push eax
// 894dac | mov dword ptr [ebp - 0x54], ecx
$sequence_7 = { ff75f8 8945fc ff15???????? 56 56 6a02 56 }
// n = 7, score = 300
// ff75f8 | push dword ptr [ebp - 8]
// 8945fc | mov dword ptr [ebp - 4], eax
// ff15???????? |
// 56 | push esi
// 56 | push esi
// 6a02 | push 2
// 56 | push esi
$sequence_8 = { ff7608 03c1 50 ff15???????? }
// n = 4, score = 300
// ff7608 | push dword ptr [esi + 8]
// 03c1 | add eax, ecx
// 50 | push eax
// ff15???????? |
$sequence_9 = { 0fb7044a 6685c0 7412 0fb7444584 66890c47 0fb7044a 66ff444584 }
// n = 7, score = 300
// 0fb7044a | movzx eax, word ptr [edx + ecx*2]
// 6685c0 | test ax, ax
// 7412 | je 0x14
// 0fb7444584 | movzx eax, word ptr [ebp + eax*2 - 0x7c]
// 66890c47 | mov word ptr [edi + eax*2], cx
// 0fb7044a | movzx eax, word ptr [edx + ecx*2]
// 66ff444584 | inc word ptr [ebp + eax*2 - 0x7c]
$sequence_10 = { 83e001 89412c 8b4320 c7403001000000 }
// n = 4, score = 300
// 83e001 | and eax, 1
// 89412c | mov dword ptr [ecx + 0x2c], eax
// 8b4320 | mov eax, dword ptr [ebx + 0x20]
// c7403001000000 | mov dword ptr [eax + 0x30], 1
$sequence_11 = { 8b4d0c 0fb71441 8955f0 3bd3 0f862fffffff 8b45cc }
// n = 6, score = 300
// 8b4d0c | mov ecx, dword ptr [ebp + 0xc]
// 0fb71441 | movzx edx, word ptr [ecx + eax*2]
// 8955f0 | mov dword ptr [ebp - 0x10], edx
// 3bd3 | cmp edx, ebx
// 0f862fffffff | jbe 0xffffff35
// 8b45cc | mov eax, dword ptr [ebp - 0x34]
$sequence_12 = { 2bc1 d1f8 8d440002 50 6a08 ffd6 50 }
// n = 7, score = 300
// 2bc1 | sub eax, ecx
// d1f8 | sar eax, 1
// 8d440002 | lea eax, [eax + eax + 2]
// 50 | push eax
// 6a08 | push 8
// ffd6 | call esi
// 50 | push eax
$sequence_13 = { 83e001 894304 8bc2 83e003 83e800 }
// n = 5, score = 300
// 83e001 | and eax, 1
// 894304 | mov dword ptr [ebx + 4], eax
// 8bc2 | mov eax, edx
// 83e003 | and eax, 3
// 83e800 | sub eax, 0
$sequence_14 = { 75f5 2bcf d1f9 8d1409 8bce 85d2 }
// n = 6, score = 200
// 75f5 | jne 0xfffffff7
// 2bcf | sub ecx, edi
// d1f9 | sar ecx, 1
// 8d1409 | lea edx, [ecx + ecx]
// 8bce | mov ecx, esi
// 85d2 | test edx, edx
$sequence_15 = { 50 ffd6 85c0 0f8480000000 8b95f4fdffff 8d8df8fdffff }
// n = 6, score = 200
// 50 | push eax
// ffd6 | call esi
// 85c0 | test eax, eax
// 0f8480000000 | je 0x86
// 8b95f4fdffff | mov edx, dword ptr [ebp - 0x20c]
// 8d8df8fdffff | lea ecx, [ebp - 0x208]
condition:
7 of them and filesize < 851968
}
rule win_eternal_petya_w0 {
meta:
description= "Detect the risk of Ransomware Petya Rule 3"
strings:
$encrypt_file = { 55 8B EC 83 EC ?? 53 56 57 8B 7D ?? 8B 4F ?? 33 DB 8D 45 ?? 50 53 53 51 89 5D ?? 89 5D ?? 89 5D ?? FF 15 ?? ?? ?? ?? 85 C0 0F 84 ?? ?? ?? ?? 8B 55 ?? 53 53 6A ?? 53 53 68 ?? ?? ?? ?? 52 FF 15 ?? ?? ?? ?? 8B F0 83 FE ?? 0F 84 ?? ?? ?? ?? 8D 45 ?? 50 8D 4D ?? 51 57 8B CE E8 ?? ?? ?? ?? 83 C4 ?? 85 C0 0F 84 ?? ?? ?? ?? 39 5D ?? 0F 84 ?? ?? ?? ?? 39 5D ?? 0F 84 ?? ?? ?? ?? 8D 55 ?? 52 56 FF 15 ?? ?? ?? ?? 8B 4F ?? 8B 45 ?? 83 C1 ?? 2B C1 19 5D ?? 89 45 ?? 89 5D ?? 78 ?? 7F ?? 3D ?? ?? ?? ?? 76 ?? B8 ?? ?? ?? ?? EB ?? C7 45 ?? ?? ?? ?? ?? 53 50 53 6A ?? 53 8B F8 56 89 45 ?? 89 7D ?? FF 15 ?? ?? ?? ?? 8B D8 85 DB 74 ?? 8B 55 ?? 52 6A ?? 6A ?? 6A ?? 53 FF 15 ?? ?? ?? ?? 8B F8 85 FF 74 ?? 8B 4D ?? 8B 55 ?? 8D 45 ?? 50 57 6A ?? 51 6A ?? 52 FF 15 ?? ?? ?? ?? 85 C0 74 ?? 8B 45 ?? 50 57 FF 15 ?? ?? ?? ?? 8B 4D ?? 51 68 ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 C4 ?? 57 FF 15 ?? ?? ?? ?? 53 FF 15 ?? ?? ?? ?? 8B 7D ?? 8B 45 ?? 3B C7 73 ?? 2B F8 EB ?? 33 FF 8B 55 ?? 8B 42 ?? 8D 4C 38 ?? 6A ?? 51 E8 ?? ?? ?? ?? 8B 7D ?? 83 C4 ?? 33 DB 56 FF 15 ?? ?? ?? ?? 8B 55 ?? 52 FF 15 ?? ?? ?? ?? 39 5D ?? 74 ?? 39 5D ?? 75 ?? 8B 47 ?? 8B 35 ?? ?? ?? ?? 50 FF D6 8B 7F ?? 3B FB 74 ?? 57 FF D6 5F 5E 5B 8B E5 5D C3 }
$main_encrypt = { 55 8B EC 56 6A ?? 6A ?? 6A ?? 6A ?? FF 15 ?? ?? ?? ?? 8B 75 ?? 89 46 ?? 85 C0 0F 84 ?? ?? ?? ?? 53 8B 1D ?? ?? ?? ?? 57 68 ?? ?? ?? ?? 6A ?? 6A ?? 6A ?? 8D 7E ?? 57 FF D3 85 C0 75 ?? FF 15 ?? ?? ?? ?? 3D ?? ?? ?? ?? 75 ?? 6A ?? 6A ?? 6A ?? 6A ?? 57 FF D3 85 C0 74 ?? 8B 07 8D 5E ?? 53 50 8B 46 ?? E8 ?? ?? ?? ?? 83 C4 ?? 85 C0 74 ?? 8B C6 E8 ?? ?? ?? ?? 85 C0 74 ?? E8 ?? ?? ?? ?? 85 C0 74 ?? 56 8D 4E ?? 6A ?? 51 E8 ?? ?? ?? ?? 8B 56 ?? 83 C4 ?? 52 FF 15 ?? ?? ?? ?? 8B 46 ?? 50 FF 15 ?? ?? ?? ?? 8B 0B 51 FF 15 ?? ?? ?? ?? 8B 17 6A ?? 52 FF 15 ?? ?? ?? ?? 8B 46 ?? 50 FF 15 ?? ?? ?? ?? 5F 5B B9 ?? ?? ?? ?? 8D 46 ?? 8B FF C6 00 ?? 40 49 75 ?? 56 FF 15 ?? ?? ?? ?? 33 C0 5E 5D C2 ?? ?? }
$encryption_loop = { 8B 7C 24 ?? 6A ?? 6A ?? 8D 43 ?? 50 33 C0 39 43 ?? 0F 95 C0 40 50 FF 15 ?? ?? ?? ?? 85 C0 0F 84 ?? ?? ?? ?? 83 F8 ?? 0F 84 ?? ?? ?? ?? 83 F8 ?? 0F 84 ?? ?? ?? ?? B9 ?? ?? ?? ?? 8D 44 24 ?? 66 8B 10 66 3B 11 75 ?? 66 85 D2 74 ?? 66 8B 50 ?? 66 3B 51 ?? 75 ?? 83 C0 ?? 83 C1 ?? 66 85 D2 75 ?? 33 C0 EB ?? 1B C0 83 D8 ?? 85 C0 0F 84 ?? ?? ?? ?? B9 ?? ?? ?? ?? 8D 44 24 ?? 8D 64 24 ?? 66 8B 10 66 3B 11 75 ?? 66 85 D2 74 ?? 66 8B 50 ?? 66 3B 51 ?? 75 ?? 83 C0 ?? 83 C1 ?? 66 85 D2 75 ?? 33 C0 EB ?? 1B C0 83 D8 ?? 85 C0 0F 84 ?? ?? ?? ?? 8D 4C 24 ?? 51 57 8D 94 24 ?? ?? ?? ?? 52 FF 15 ?? ?? ?? ?? 85 C0 74 ?? 8B 44 24 ?? A8 ?? 74 ?? A9 ?? ?? ?? ?? 75 ?? 8D BC 24 ?? ?? ?? ?? E8 ?? ?? ?? ?? 85 C0 75 ?? 8B 45 ?? 53 48 50 8B CF 51 E8 ?? ?? ?? ?? 83 C4 ?? EB ?? 8D 54 24 ?? 52 FF 15 ?? ?? ?? ?? 8D 4C 24 ?? 8D 71 ?? 90 66 8B 11 83 C1 ?? 66 85 D2 75 ?? 2B CE D1 F9 8D 4C 4C ?? 3B C1 74 ?? 50 E8 ?? ?? ?? ?? 83 C4 ?? 85 C0 74 ?? 8D 94 24 ?? ?? ?? ?? 53 52 E8 ?? ?? ?? ?? 83 C4 ?? 8B 74 24 ?? 8D 44 24 ?? 50 56 FF 15 ?? ?? ?? ?? 85 C0 0F 85 ?? ?? ?? ??}
condition:
$encrypt_file and $main_encrypt and $encryption_loop
}
rule Petya_Ransomware {
meta:
description= "Detect the risk of Ransomware Petya Rule 4"
hash = "26b4699a7b9eeb16e76305d843d4ab05e94d43f3201436927e13b3ebafa90739"
strings:
$a1 = "<description>WinRAR SFX module</description>" fullword ascii
$s1 = "BX-Proxy-Manual-Auth" fullword wide
$s2 = "<!--The ID below indicates application support for Windows 10 -->" fullword ascii
$s3 = "X-HTTP-Attempts" fullword wide
$s4 = "@CommandLineMode" fullword wide
$s5 = "X-Retry-After" fullword wide
condition:
uint16(0) == 0x5a4d and filesize < 500KB and $a1 and 3 of ($s*)
}
rule Ransom_Petya {
meta:
description= "Detect the risk of Ransomware Petya Rule 5"
strings:
$a1 = { C1 C8 14 2B F0 03 F0 2B F0 03 F0 C1 C0 14 03 C2 }
$a2 = { 46 F7 D8 81 EA 5A 93 F0 12 F7 DF C1 CB 10 81 F6 }
$a3 = { 0C 88 B9 07 87 C6 C1 C3 01 03 C5 48 81 C3 A3 01 00 00 }
condition:
all of them
}

113
yaraRules/Ransom.Phobos.yar Normal file
View File

@@ -0,0 +1,113 @@
rule MALWARE_Win_Phobos {
meta:
description = "Detect the risk of Ransomware Phobos Rule 1"
strings:
$x1 = "\\\\?\\UNC\\\\\\e-" fullword wide
$x2 = "\\\\?\\ :" fullword wide
$x3 = "POST" fullword wide
$s1 = "ELVL" fullword wide
$s2 = /SUP\d{3}/ fullword wide
$s3 = { 41 31 47 ?? 41 2b }
condition:
uint16(0) == 0x5a4d and all of ($x*) and 1 of ($s*)
}
rule win_phobos_auto {
meta:
description = "Detect the risk of Ransomware Phobos Rule 2"
strings:
$sequence_0 = { 57 ff15???????? 8906 3bc7 7427 57 ff36 }
// n = 7, score = 100
// 57 | push edi
// ff15???????? |
// 8906 | mov dword ptr [esi], eax
// 3bc7 | cmp eax, edi
// 7427 | je 0x29
// 57 | push edi
// ff36 | push dword ptr [esi]
$sequence_1 = { 59 6a14 8d4304 50 57 e8???????? }
// n = 6, score = 100
// 59 | pop ecx
// 6a14 | push 0x14
// 8d4304 | lea eax, [ebx + 4]
// 50 | push eax
// 57 | push edi
// e8???????? |
$sequence_2 = { ff7508 ffd0 ff75f8 57 e8???????? 59 }
// n = 6, score = 100
// ff7508 | push dword ptr [ebp + 8]
// ffd0 | call eax
// ff75f8 | push dword ptr [ebp - 8]
// 57 | push edi
// e8???????? |
// 59 | pop ecx
$sequence_3 = { 0f85b3000000 57 8d44242c 50 be08020000 56 }
// n = 6, score = 100
// 0f85b3000000 | jne 0xb9
// 57 | push edi
// 8d44242c | lea eax, [esp + 0x2c]
// 50 | push eax
// be08020000 | mov esi, 0x208
// 56 | push esi
$sequence_4 = { 8945e4 85c0 0f84c2000000 bf???????? be04010000 }
// n = 5, score = 100
// 8945e4 | mov dword ptr [ebp - 0x1c], eax
// 85c0 | test eax, eax
// 0f84c2000000 | je 0xc8
// bf???????? |
// be04010000 | mov esi, 0x104
$sequence_5 = { 8b450c 83c414 85c0 7408 8b0e 8b4c3908 }
// n = 6, score = 100
// 8b450c | mov eax, dword ptr [ebp + 0xc]
// 83c414 | add esp, 0x14
// 85c0 | test eax, eax
// 7408 | je 0xa
// 8b0e | mov ecx, dword ptr [esi]
// 8b4c3908 | mov ecx, dword ptr [ecx + edi + 8]
$sequence_6 = { eb05 ff74bc3c 4f ff15???????? 3bfb 75f1 }
// n = 6, score = 100
// eb05 | jmp 7
// ff74bc3c | push dword ptr [esp + edi*4 + 0x3c]
// 4f | dec edi
// ff15???????? |
// 3bfb | cmp edi, ebx
// 75f1 | jne 0xfffffff3
$sequence_7 = { 333c95d0b14000 8b55fc c1ea08 c1eb10 23d0 8b1495d0ad4000 23d8 }
// n = 7, score = 100
// 333c95d0b14000 | xor edi, dword ptr [edx*4 + 0x40b1d0]
// 8b55fc | mov edx, dword ptr [ebp - 4]
// c1ea08 | shr edx, 8
// c1eb10 | shr ebx, 0x10
// 23d0 | and edx, eax
// 8b1495d0ad4000 | mov edx, dword ptr [edx*4 + 0x40add0]
// 23d8 | and ebx, eax
$sequence_8 = { e8???????? be???????? 8d7c2428 a5 a5 a5 }
// n = 6, score = 100
// e8???????? |
// be???????? |
// 8d7c2428 | lea edi, [esp + 0x28]
// a5 | movsd dword ptr es:[edi], dword ptr [esi]
// a5 | movsd dword ptr es:[edi], dword ptr [esi]
// a5 | movsd dword ptr es:[edi], dword ptr [esi]
$sequence_9 = { 7703 83c020 c3 55 8bec 57 ff7508 }
// n = 7, score = 100
// 7703 | ja 5
// 83c020 | add eax, 0x20
// c3 | ret
// 55 | push ebp
// 8bec | mov ebp, esp
// 57 | push edi
// ff7508 | push dword ptr [ebp + 8]
condition:
7 of them and filesize < 139264
}

View File

@@ -0,0 +1,12 @@
rule Ransom_Povlsomware {
meta:
description= "Detect the risk of Ransomware Povlsomware Rule 1"
strings:
$Guid = {00002901002466653064356161372D353338662D343266362D396563652D623134313536306637373831}
$op1 = {0316326505D00?00000228?700000A28?800000AA50?0000020A067B??0000041F5C2E3E067B??0000041F5B2E34067B??0000041F09330E02067B??00000428??0000062D1C067B??0000041F1B331928?900000A20000002005F200000020033071728?A00000A2A027B0?00000403040528??0000062A}
$s1 = "Decrypting... Please wait" fullword wide
$s2 = "Please decrypt them!" fullword wide
condition:
uint16(0) == 0x5a4d and
any of them
}

View File

@@ -0,0 +1,16 @@
rule Ransom_QNAPCrypt {
meta:
description= "Detect the risk of Ransomware QNAPCrypt Rule 1"
hash1 = "039a997681655004aed1cc4c6ee24bf112d79e4f3b823ccae96b4a32c5ed1b4c"
hash2 = "0b851832f9383df7739cd28ccdfd59925e9af7203b035711a7d96bba34a9eb04"
hash3 = "19448f9aa1fe6c07d52abc59d1657a7381cfdb4a4fa541279097cc9e9412964b"
hash4 = "2fe577fd9c77d3bebdcf9bfc6416c3f9a12755964a8098744519709daf2b09ce"
hash5 = "36cfb1a7c971041c9483e4f4e092372c9c1ab792cd9de7b821718ccd0dbb09c1"
strings:
$s1 = "1st.3ds.3fr.4db.4dd.602.a4p.a5w.abf.abw.act.adr.aep.aes.aex.aim.alx.ans.apk.apt.arj" ascii
$s2 = ".arw.asa.asc.ase.asp.asr.att.aty.awm.awp.awt.aww.axd.bak.bar.bat.bay.bc6.bc7.big.bik.bin.bit.bkf.bkp.bml.bok.bpw.bsa.bwp.bz2.c++" ascii
$s3 = ".swz.sxc.t12.t13.tar.tax.tbl.tbz.tcl.tgz.tib.tif.tor.tpl.txt.ucf.upk.url.vbd.vbo.vbs.vcf.vdf.vdi.vdw.vlp.vlx.vmx.vpk.vrt.vtf.w3x" ascii
$s4 = "README_FOR_DECRYPT.txt" ascii
condition:
uint16(0) == 0x457f and any of them
}

View File

@@ -0,0 +1,12 @@
rule Ransom_Sarbloh
{
meta:
description= "Detect the risk of Ransomware Sarbloh Rule 1"
strings:
$note_path = {25005500530045005200500052004F00460049004C00450025000000250073005C004400650073006B0074006F0070005C0052004500410044004D0045005F0053004100520042004C004F0048002E007400780074}
$key_end = {410067004D0042004100410045003D002D002D002D002D002D0045004E00440020005000550042004C004900430020004B00450059002D002D002D002D002D00}
$key_start = {4B00450059002D002D002D002D002D004D004900490042004900540041004E00420067006B007100}
$note = {59004F00550052002000460049004C00450053002000410052004500200047004F004E0045002100210021}
condition:
uint16(0) == 0x5a4d and any of them
}

Some files were not shown because too many files have changed in this diff Show More