MinerSearch 1.4.9.6: пожелания
Спасибо за утилиту, карантин и Threat Review сделаны удобно. Несколько идей:
- Подпись кода. Exe и DLL не подписаны (Authenticode), из-за этого SmartScreen и антивирусы реагируют настороженно, а пользователь не может проверить подлинность. Для open source есть бесплатный вариант, например SignPath Foundation.
- Хеши и обновления. hashes.txt лежит внутри самого архива и подмену не выявит. Лучше публиковать хеши в релизе на GitHub и подписывать version.txt, иначе взлом домена позволит подсунуть вредоносную версию.
- Прозрачная отправка логов. Судя по файлам, лог уходит на сервер вместе с идентификатором устройства. Хорошо бы показывать, что именно отправляется, маскировать имя пользователя в путях, не привязывать ID к железу и добавить в настройки «никогда не отправлять».
- Эвристики по поведению. Соединения с майнинг-пулами (Stratum, порты 3333/4444/14444), высокая нагрузка в простое, запуск из %TEMP%/AppData. Это поможет находить переупакованные майнеры, которые обходят сигнатуры.
- Сигнатуры отдельным файлом. Сейчас база зашита в dbase.dll. Отдельный подписанный файл позволил бы пополнять её без нового релиза
1. Маскирование имени пользователя в логе перед отправкой
csharp
using System.Text.RegularExpressions;
static string MaskLog(string log)
{
// C:\Users\Ivan\AppData -> C:\Users\<user>\AppData
log = Regex.Replace(log, @"(?i)(\\Users\\)[^\\]+", "$1<user>");
// имя компьютера
return Regex.Replace(log, Regex.Escape(Environment.MachineName), "<host>", RegexOptions.IgnoreCase);
}
2. Идентификатор устройства без привязки к железу
csharp
using System.Security.Cryptography;
// salt = случайные 32 байта, генерируются один раз и хранятся в конфиге
static string AnonymousDeviceId(byte[] salt)
{
using (var h = new HMACSHA256(salt))
return BitConverter.ToString(h.ComputeHash(Encoding.UTF8.GetBytes(Environment.MachineName)))
.Replace("-", "").Substring(0, 16);
}
3. Проверка подписи version.txt перед использованием
csharp
using System.Security.Cryptography;
// publicKeyXml вшит в программу, подпись лежит рядом как version.txt.sig
static bool VerifyManifest(byte[] data, byte[] signature, string publicKeyXml)
{
using (var rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(publicKeyXml);
return rsa.VerifyData(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
}
Автор подписывает файл своим закрытым ключом при выпуске релиза. Если подпись не сходится, обновление игнорируется.
4. Эвристика по пулам. Её можно сделать на уже существующем TcpTableClass из Win32Wrapper: брать TCP-соединения с PID, фильтровать порты 3333, 4444, 5555, 7777, 14444 и сопоставлять с путём процесса (%TEMP%, AppData). Это отдельный анализатор по образцу IThreatAnalyzer. Без исходников писать его вслепую не буду, чтобы не получилось мусора.