С чем у вас ассоциируется язык Golang? Сети, микросервисы, облака и... милый синий суслик. Но за этой маской скрывается мощнейший инструмент, который всё чаще выбирают APT-группировки и разработчики Ransomware.
Данная статья ориентирована на новичков, мы разберемся, какие языки программирования чаще всего используют для написания малварь, и что из себя представляет язык Go.
На чем пишут вирусы в 2025 году?
Я задал вопрос Perplexity AI о топ-5 языках для вредоносного ПО. Ответ показателен:- C/C++ (70-80%): Короли нативного кода и руткитов.
- C# (15-25%): Родной дом для атак на Windows и Active Directory.
- Python (5-10%): Язык скрипт-кидди и быстрой автоматизации.
- Golang (2-5%): Растущий сегмент элитного вредоносного ПО.
Как вы могли заметить, даже C# с его зависимостями (.NET) оказался в несколько раз популярнее Go, но почему?
Потому что на Windows нет проблем с зависимостями для C#.
Начиная с Windows 7 (и тем более 10/11), .NET Framework предустановлен в системе. Это часть ОС.
Windows для C# — это его родной дом, самые известные инструменты для атак на Active Directory (BloodHound, SharpHound, Rubeus) написаны на C#,
потому что они идеально взаимодействуют с Windows API.
Значит ли это, что C# лучше подходит для написания вирусов чем Go? Категорически нет.
Но почему? ведь 90% корпоративных компьютеров работают на windows, с которым C# отлично справляется, зачем учить другой язык? Зачем атаковать другую ОС?
Это очень частое заблуждение. Да, 90% корпоративных компьютеров работают на windows, НО, какая главная цель хакера? Компьютер одного сотрудника или же целый сервер?
Суть в том, что подавляющее большинство всех серверов, баз данных, облаков и контейнеров — это linux, для хакера взлом компьютера сотрудника на windows это лишь первый шаг,
основная его цель — сервер на линуксе, в которой и лежат все данные, а C# из-за своей привязанности к windows здесь практически бесполезен.
Идём дальше, почему Python выше Go?
Низкий порог входа порождает тысячи однотипных стиллеров. Но их качество оставляет желать лучшего: огромный вес (30Мб+ после PyInstaller) и моментальный детект антивирусами из-за предсказуемых паттернов. Это «шум», а не серьезное оружие.
Python — это язык для массового и быстрого прототипирования, который проигрывает Go в скрытности и производительности.
Что касается C/C++, процент полностью оправдан.
C/C++ обеспечивают низкоуровневый контроль над системными ресурсами, памятью и оборудованием, что критично для создания компактных, быстрых и незаметных эксплойтов, руткитов и анализаторов malware.
Так зачем нам Go, в то время как есть C/C++ ?
Первый плюс в сторону Go — Кроссплатформенность.
Для распространения вируса, его способность функционировать в разных операционных системах критично важна.
Создание единой версии продукта экономит время и ресурсы, к тому же на всех устройствах он будет функционировать единым образом.
Вот как на Go можно получить исполняемые файлы для разных платформ:
Bash:
GOOS=windows GOARCH=amd64 go build -o malware.exe
GOOS=linux GOARCH=amd64 go build -o malware_linux
GOOS=darwin GOARCH=arm64 go build -o malware_macos
# Даже для Android!
GOOS=android GOARCH=arm64 go build -o malware_android
Всё это достигается за счёт автономной стандартной библиотеки и среды выполнения Go, которая не полагается на системные библиотеки хоста, в отличие от C/C++.
Второе важное преимущество: Сложность анализа и реверс-инжиниринга
Go-бинарники выглядят непривычно для анализаторов, вот простой пример:
C-подобный:
package main
import "fmt"
func main() {
fmt.Println("Hello, malware analyst!")
}
С виду просто, но реверсер увидит здесь огромную таблицу pclntab, множество runtime-структур и нестандартных вызовов функций:
Код:
; Функция main.main
public main_main
main_main proc near
; --- ПРОЛОГ (Проверка стека - визитная карточка Go) ---
cmp rsp, [r14+10h] ; Проверка, достаточно ли стека (r14 - текущая горутина)
jbe short loc_morestack ; Если мало, прыгаем на расширение стека
sub rsp, 18h ; Выделяем место в стеке
mov [rsp+10h], rbp ; Сохраняем frame pointer
lea rbp, [rsp+10h]
; --- ТЕЛО ФУНКЦИИ ---
; Подготовка аргументов для fmt.Println
; Строка "Hello, malware analyst!" на самом деле структура (ptr, len)
lea rax, go_string_data ; Указатель на строку в секции .rodata
mov [rsp], rax ; Кладём указатель в стек (или регистр в новых версиях Go ABI)
mov qword ptr [rsp+8], 17h ; Длина строки (23 символа)
call fmt_Println
; --- ЭПИЛОГ ---
mov rbp, [rsp+10h]
add rsp, 18h
retn
; --- Хелпер расширения стека ---
loc_morestack:
call runtime_morestack_noctxt
jmp main_main
main_main endp
Обратите внимание, даже без обфускации Go-бинарники сложны для анализа.
Обфускация в Go — стандартная практика, он имеет встроенные инструменты для усложнения анализа:
Bash:
go build -ldflags="-s -w" # Удаление debug info и символов
strip malware.exe # Дополнительная очистка
# Продвинутая обфускация с garble:
garble build -o malware.exe # Переименование всех символов, удаление строк, модификация AST
После garble:
1. Все имена функций преварщаются в бессмысленные символы a, b, c...
2. Строки зашифрованы/разделены.
3. Логика потока управления искажена.
Но программа работает как прежде!
Что касается C, его компилятор даёт почти «голый» код: стек, вызовы библиотек, минимум служебных структур.
Go — наоборот: Менеджер горутин, планировщик (M, G, P), сборщик мусора, система таймеров, большой набор функций runtime и т.д.
Даже пустая программа на Go содержит тысячи строк машинного кода, которые не относятся к логике разработчика.
И наконец, главный козырь Go — встроенная конкурентность (горутины + каналы)
Возьмём для примера такой код:
C-подобный:
var gorutinesCount int = 200000
func main() {
for i := 0; i < gorutinesCount; i++ {
go worker() // 200,000 одновременных атакующих агентов!
}
}
func worker() {
// так как здесь пусто, скрипт быстро завершится
}
В функции worker может быть что угодно, например ботнеты посылающие запросы на определенный сайт, вот тебе и DDOS атака.
Как видите, в Go создание огромного количества почти одновременно работающих горутин происходит интуитивно.
Горутины и каналы — это не просто "фича языка". Это новая парадигма для создания распределенных систем. И malware-разработчики первыми поняли её потенциал.
Зачем тогда C/C++ ?
Из простоты языка Go вытекает пожалуй его главная проблема (с точки зреня создания вирусов) — он высокоуровневый.В Go вы не можете свободно управлять памятью, у него автоматический GC, он далек от системных API (WinAPI, POSIX изначально на C) и вы сильно ограничены возможностями языка.
Взглянем на таблицу, в которой сравнивается всё, что можно сделать на С, чего нельзя в Go.
Большинство вирусов, и 99% всех 0-day эксплойтов — это именно низкоуровневый код.
Но в то же время, писать ботнеты, С2, и множество других сетевых инструментов на C/C++, в то время как есть Go, не самая разумная трата времени.
Вывод — нужно их комбинировать.
Но что выбрать в связке с Go, C или C++ ?
На мой субъективный взгляд, логичнее будет выбрать C, и вот несколько аргументов:1. Меньше накладных расходов — нет исключений, RTTI, виртуальных таблиц по умолчанию
2. Более предсказуемый бинарный результат — проще контролировать итоговый ассемблер
3. Ближе к системным API — WinAPI, POSIX изначально на C
4. Идеален для shellcode — минимальный, компактный, предсказуемый
5. Все сложные malware/эксплойты пишутся на C (ядро руткитов, эксплойты нулевого дня для браузеров или ядра ОС, буткиты, файловые вирусы-заразители)
Как их комбинировать?
Возьмём в пример CGo, CGo — это не отдельная библиотека, а встроенная функция Go для взаимодействия с C. Она позволяет с легкостью вызывать методы написанные на С через Go.Таким образом, "проблема" высокого уровня Go отпадает, теперь, у нас есть два замечательных языка при помощи которых мы можем создать малварь любой сложности, с этой поры, всё ограничивается вашими навыками.
Важная информация!
Спасибо за прочитанную статью, если у вас остались вопросы или вы хотелибы продолжить развиваться в этой теме, приглашаю вас в нашу телеграмм группу, куда я с радостью набираю всех, кто только начинает погружаться в мир кибербезопасности. Будем помогать друг другу и вместе изучать новое!
Ссылка: NHNH – Public