feat(d-eyes): init
This commit is contained in:
132
basicinfo/info/ExchangeServerOWASSRF_windows.go
Normal file
132
basicinfo/info/ExchangeServerOWASSRF_windows.go
Normal 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
|
||||
}
|
||||
59
basicinfo/info/autorun_linux.go
Normal file
59
basicinfo/info/autorun_linux.go
Normal 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)
|
||||
}
|
||||
59
basicinfo/info/autorun_windows.go
Normal file
59
basicinfo/info/autorun_windows.go
Normal 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
27
basicinfo/info/base.go
Normal 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)
|
||||
|
||||
}
|
||||
111
basicinfo/info/contab_windows.go
Normal file
111
basicinfo/info/contab_windows.go
Normal 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")
|
||||
}
|
||||
}
|
||||
81
basicinfo/info/crontab_linux.go
Normal file
81
basicinfo/info/crontab_linux.go
Normal 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
|
||||
}
|
||||
109
basicinfo/info/network_linux.go
Normal file
109
basicinfo/info/network_linux.go
Normal 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
|
||||
}
|
||||
103
basicinfo/info/network_windows.go
Normal file
103
basicinfo/info/network_windows.go
Normal 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
|
||||
}
|
||||
70
basicinfo/info/summary_linux.go
Normal file
70
basicinfo/info/summary_linux.go
Normal 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
|
||||
}
|
||||
74
basicinfo/info/summary_windows.go
Normal file
74
basicinfo/info/summary_windows.go
Normal 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
77
basicinfo/info/top.go
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
42
basicinfo/info/users_linux.go
Normal file
42
basicinfo/info/users_linux.go
Normal 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
|
||||
}
|
||||
38
basicinfo/info/users_windows.go
Normal file
38
basicinfo/info/users_windows.go
Normal 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
|
||||
}
|
||||
18
basicinfo/utils/autoruns.go
Normal file
18
basicinfo/utils/autoruns.go
Normal 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()
|
||||
}
|
||||
111
basicinfo/utils/autoruns_linux.go
Normal file
111
basicinfo/utils/autoruns_linux.go
Normal 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
|
||||
}
|
||||
276
basicinfo/utils/autoruns_windows.go
Normal file
276
basicinfo/utils/autoruns_windows.go
Normal 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() {
|
||||
|
||||
// }
|
||||
16
basicinfo/utils/stringutil.go
Normal file
16
basicinfo/utils/stringutil.go
Normal 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
|
||||
}
|
||||
110
configcheck/check/CheckTrigger.go
Normal file
110
configcheck/check/CheckTrigger.go
Normal 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")
|
||||
}
|
||||
89
configcheck/check/check_alias_conf.go
Normal file
89
configcheck/check/check_alias_conf.go
Normal 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
|
||||
}
|
||||
79
configcheck/check/crontab_check.go
Normal file
79
configcheck/check/crontab_check.go
Normal 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})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
34
configcheck/check/empytpasswd.go
Normal file
34
configcheck/check/empytpasswd.go
Normal 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
330
configcheck/check/env.go
Normal 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
|
||||
}
|
||||
126
configcheck/check/history.go
Normal file
126
configcheck/check/history.go
Normal 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
33
configcheck/check/log.go
Normal 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
1093
configcheck/check/rootkit.go
Normal file
File diff suppressed because it is too large
Load Diff
48
configcheck/check/setuid.go
Normal file
48
configcheck/check/setuid.go
Normal 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
51
configcheck/check/ssh.go
Normal 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
223
configcheck/check/sshlog.go
Normal 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
|
||||
}
|
||||
27
configcheck/check/sshserver.go
Normal file
27
configcheck/check/sshserver.go
Normal 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
33
configcheck/check/sudo.go
Normal 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
|
||||
}
|
||||
117
configcheck/common/common.go
Normal file
117
configcheck/common/common.go
Normal 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
291
deyes_linux.go
Normal 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
337
deyes_windows.go
Normal 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
56
filedetection/file.go
Normal 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
54
filedetection/filescan.go
Normal 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
|
||||
|
||||
}
|
||||
68
filedetection/filesystemScanner_linux.go
Normal file
68
filedetection/filesystemScanner_linux.go
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
61
filedetection/filesystemScanner_windows.go
Normal file
61
filedetection/filesystemScanner_windows.go
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
236
filedetection/filesystem_linux.go
Normal file
236
filedetection/filesystem_linux.go
Normal 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
|
||||
}
|
||||
203
filedetection/filesystem_windows.go
Normal file
203
filedetection/filesystem_windows.go
Normal 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
87
filedetection/hashes.go
Normal 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
172
filedetection/iterator.go
Normal 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
43
go.mod
Normal 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
41
logo/logo_linux.go
Normal 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
60
logo/logo_windows.go
Normal 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
6
output/result.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package output
|
||||
|
||||
type Result struct {
|
||||
Risk string
|
||||
RiskPath string
|
||||
}
|
||||
50
process/controller/init_linux.go
Normal file
50
process/controller/init_linux.go
Normal 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()
|
||||
}
|
||||
51
process/controller/init_windows.go
Normal file
51
process/controller/init_windows.go
Normal 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()
|
||||
}
|
||||
216
process/models/models_linux.go
Normal file
216
process/models/models_linux.go
Normal 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)
|
||||
|
||||
}
|
||||
214
process/models/models_windows.go
Normal file
214
process/models/models_windows.go
Normal 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)
|
||||
|
||||
}
|
||||
298
process/scanner/scanner_linux.go
Normal file
298
process/scanner/scanner_linux.go
Normal 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
|
||||
|
||||
}
|
||||
309
process/scanner/scanner_windows.go
Normal file
309
process/scanner/scanner_windows.go
Normal 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
27
process/utils/iputil.go
Normal 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
29
process/utils/readfile.go
Normal 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
|
||||
}
|
||||
53
yaraRules/Botnet.BlackMoon.yar
Normal file
53
yaraRules/Botnet.BlackMoon.yar
Normal 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
|
||||
}
|
||||
11
yaraRules/Botnet.Festi.yar
Normal file
11
yaraRules/Botnet.Festi.yar
Normal 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
272
yaraRules/Botnet.Gafgyt.yar
Normal 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
|
||||
}
|
||||
24
yaraRules/Botnet.Kelihos.yar
Normal file
24
yaraRules/Botnet.Kelihos.yar
Normal 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
|
||||
}
|
||||
27
yaraRules/Botnet.Mykings.yar
Normal file
27
yaraRules/Botnet.Mykings.yar
Normal file
File diff suppressed because one or more lines are too long
14
yaraRules/CoinMiner.CryptoELF.yar
Normal file
14
yaraRules/CoinMiner.CryptoELF.yar
Normal 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
|
||||
}
|
||||
88
yaraRules/CoinMiner.Monero.yar
Normal file
88
yaraRules/CoinMiner.Monero.yar
Normal 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*)
|
||||
}
|
||||
138
yaraRules/CoinMiner.Trojan.yar
Normal file
138
yaraRules/CoinMiner.Trojan.yar
Normal 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*)
|
||||
)
|
||||
}
|
||||
36
yaraRules/CoinMiner.Wannamine.yar
Normal file
36
yaraRules/CoinMiner.Wannamine.yar
Normal 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
|
||||
}
|
||||
215
yaraRules/CoinMiner.givemexyz.yar
Normal file
215
yaraRules/CoinMiner.givemexyz.yar
Normal 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
|
||||
}
|
||||
2198
yaraRules/Malicious.tools.yar
Normal file
2198
yaraRules/Malicious.tools.yar
Normal file
File diff suppressed because it is too large
Load Diff
5276
yaraRules/Malicious.webshells.yar
Normal file
5276
yaraRules/Malicious.webshells.yar
Normal file
File diff suppressed because it is too large
Load Diff
29
yaraRules/Malware.FiveSys.yar
Normal file
29
yaraRules/Malware.FiveSys.yar
Normal 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
|
||||
}
|
||||
31
yaraRules/Malware.Mikey.yar
Normal file
31
yaraRules/Malware.Mikey.yar
Normal 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"
|
||||
|
||||
}
|
||||
48
yaraRules/Malware.Rekoobe.yar
Normal file
48
yaraRules/Malware.Rekoobe.yar
Normal 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"
|
||||
|
||||
}
|
||||
18
yaraRules/Ransom.BCrypt.yar
Normal file
18
yaraRules/Ransom.BCrypt.yar
Normal 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
|
||||
}
|
||||
31
yaraRules/Ransom.Babuk.yar
Normal file
31
yaraRules/Ransom.Babuk.yar
Normal 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*))
|
||||
}
|
||||
112
yaraRules/Ransom.BadEncript.yar
Normal file
112
yaraRules/Ransom.BadEncript.yar
Normal 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
|
||||
}
|
||||
39
yaraRules/Ransom.BadRabbit.yar
Normal file
39
yaraRules/Ransom.BadRabbit.yar
Normal 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 )
|
||||
}
|
||||
9
yaraRules/Ransom.BlackMatter.yar
Normal file
9
yaraRules/Ransom.BlackMatter.yar
Normal 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
133
yaraRules/Ransom.Cerber.yar
Normal 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
|
||||
}
|
||||
|
||||
14
yaraRules/Ransom.Chaos.yar
Normal file
14
yaraRules/Ransom.Chaos.yar
Normal 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 )
|
||||
}
|
||||
30
yaraRules/Ransom.ChupaCabra.yar
Normal file
30
yaraRules/Ransom.ChupaCabra.yar
Normal 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
101
yaraRules/Ransom.Common.yar
Normal 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
200
yaraRules/Ransom.Conti.yar
Normal 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
|
||||
}
|
||||
15
yaraRules/Ransom.Cryakl.yar
Normal file
15
yaraRules/Ransom.Cryakl.yar
Normal 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
|
||||
}
|
||||
41
yaraRules/Ransom.CryptoLocker.yar
Normal file
41
yaraRules/Ransom.CryptoLocker.yar
Normal 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*)))
|
||||
}
|
||||
265
yaraRules/Ransom.DarkSide.yar
Normal file
265
yaraRules/Ransom.DarkSide.yar
Normal file
File diff suppressed because one or more lines are too long
29
yaraRules/Ransom.Fonix.yar
Normal file
29
yaraRules/Ransom.Fonix.yar
Normal 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*)
|
||||
}
|
||||
101
yaraRules/Ransom.GandCrab.yar
Normal file
101
yaraRules/Ransom.GandCrab.yar
Normal 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"
|
||||
}
|
||||
162
yaraRules/Ransom.Globeimposter.yar
Normal file
162
yaraRules/Ransom.Globeimposter.yar
Normal 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"
|
||||
}
|
||||
30
yaraRules/Ransom.Henry217.yar
Normal file
30
yaraRules/Ransom.Henry217.yar
Normal 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"
|
||||
}
|
||||
32
yaraRules/Ransom.HiddenTear.yar
Normal file
32
yaraRules/Ransom.HiddenTear.yar
Normal 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
|
||||
}
|
||||
78
yaraRules/Ransom.House.yar
Normal file
78
yaraRules/Ransom.House.yar
Normal 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*) )
|
||||
}
|
||||
29
yaraRules/Ransom.LockBit.yar
Normal file
29
yaraRules/Ransom.LockBit.yar
Normal 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
185
yaraRules/Ransom.Locky.yar
Normal 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
|
||||
}
|
||||
28
yaraRules/Ransom.MBRLocker.yar
Normal file
28
yaraRules/Ransom.MBRLocker.yar
Normal 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)
|
||||
}
|
||||
16
yaraRules/Ransom.Magniber.yar
Normal file
16
yaraRules/Ransom.Magniber.yar
Normal 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
174
yaraRules/Ransom.Makop.yar
Normal 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
|
||||
}
|
||||
18
yaraRules/Ransom.MedusaLocker.yar
Normal file
18
yaraRules/Ransom.MedusaLocker.yar
Normal 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
189
yaraRules/Ransom.Nemty.yar
Normal file
File diff suppressed because one or more lines are too long
20
yaraRules/Ransom.NoCry.yar
Normal file
20
yaraRules/Ransom.NoCry.yar
Normal 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
273
yaraRules/Ransom.Petya.yar
Normal 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
113
yaraRules/Ransom.Phobos.yar
Normal 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
|
||||
}
|
||||
12
yaraRules/Ransom.Povlsomware.yar
Normal file
12
yaraRules/Ransom.Povlsomware.yar
Normal 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
|
||||
}
|
||||
16
yaraRules/Ransom.QNAPCrypt.yar
Normal file
16
yaraRules/Ransom.QNAPCrypt.yar
Normal 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
|
||||
}
|
||||
12
yaraRules/Ransom.Sarbloh.yar
Normal file
12
yaraRules/Ransom.Sarbloh.yar
Normal 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
Reference in New Issue
Block a user