tags: malware - android
Малварь на Xamarin
Введение
Как-то раз я наткнулся на статью об андроид малваре от McAfee - Stealth Backdoor “Android/Xamalicious” Actively Infecting Devices. В ней меня заинтриговала строчка о динамически загружаемом Assembly:
Дело в том, что эта техника активно используется в .NET малваре, но под Windows. Использование же такого подхода под андроид меня удивило. Я стал копать в этом направлении. Для начала освежим в памяти суть техники. Чтобы оставаться незаметной, малваре требуется находиться в памяти, не трогая диск. В .NET есть понятие Assembly (сборка). Грубо говоря - это exe/dll, который исполняется в CLR (Common Language Runtime). Мы можем динамически загрузить сборку, которая содержит вредоносный функционал.
Малварь в статье была написана с использованием фреймворка Xamarin
.
Это сделано для того, чтобы затруднить анализ/реверс APK, так как она будет содержать кучу вспомогательных библиотек. Изучив вопросик узнал, что Xamarin устарел и заменен на .NET MAUI
Сухое определение:
` .NET MAUI - это многоплатформенный фреймворк для создания нативных настольных и мобильных приложений с помощью C# и XAML (Extensible Application Markup Language). Используя .NET MAUI (Multi-platform Application User Interface), вы можете разрабатывать мобильные приложения, которые могут работать на Windows, Android, iOS, iPadOS и macOS. `
Setup
Приступим к подготовке проекта, представляющего собой Android приложение на .NET MAUI, которое динамически загружает (Reflective Loading) вредоносную .NET Assembly и запускает ее. Для разработки я использовал Ubuntu 24 LTS
и Visual Studio Code. Для начала установим .NET SDK в Ubuntu. В Ubuntu нам нужно это сделать именно с помощью Microsoft package repository!
После установки SDK
ставим workload MAUI:
sudo dotnet workload install maui-android
Если все прошло удачно, вы должны увидеть андроид в списке:
Выполняем инструкцию по созданию проекта:
Устанавливаем Android SDK
sudo apt install -y unzip
mkdir -p ~/.android-sdk/cmdline-tools
cd ~/.android-sdk/cmdline-tools
wget https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip -O tools.zip
unzip tools.zip
mv cmdline-tools latest
cd latest
./sdkmanager --install "platform-tools" "platforms;android-33" "build-tools;33.0.2"
И прописываем его в Settings
расширения MAUI
.
Устанавливаем Microsoft OpenJDK
:
sudo apt update
sudo apt install -y wget apt-transport-https
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc
sudo add-apt-repository https://packages.microsoft.com/ubuntu/$(lsb_release -rs)/prod
sudo apt update
sudo apt install msopenjdk-17
Проверяем, что установилось правильно
/usr/lib/jvm/msopenjdk-17-amd64/bin/java -version
Теперь выберите Microsoft OpenJDK
в качестве Java
по умолчанию:
sudo update-alternatives --config java
Теперь создаем приложение MAUI по инструкции. Выполняем команду:
dotnet new maui
также создайте переменную:
export ANDROID_SDK_ROOT=/home/test/.android-sdk
Открываем файл app.csproj
и из TargetFramework
удаляем ios
и macos
. Эти параметры будут вызывать ошибку при сборке в Linux. На этом шаге у нас есть болванка готового проекта. Если мы хотим собрать его в APK, будем выполнять три последовательных действия. Первое, очищаем следы предыдущего билда:
dotnet clean
Затем выполняем сборку проекта командой, с указанием путей к Android SDK и JDK:
dotnet build -t:InstallAndroidDependencies -f:net8.0-android -p:AndroidSdkDirectory="/home/test/.android-sdk" -p:JavaSdkDirectory="/usr/lib/jvm/msopenjdk-17-amd64" -p:AcceptAndroidSDKLicenses=True
Если не находится workload и есть ошибки, то выполняем:
sudo dotnet workload restore [app.csproj::TargetFramework=net8.0-android] --project app.csproj
В конце публикуем:
dotnet publish -p:AndroidSdkDirectory="/home/test/.android-sdk" -f net8.0-android -c Release
И загружаем на девайс:
adb install xamarin/app/bin/Release/net8.0-android/publish/com.companyname.app-Signed.apk
Теперь мы готовы к разработке!
Создаем PoC
Первым делом создадим вредоносный Assembly. По аналогии создаем новый проект со следующей структурой:
У нас будет интерфейс IPlugin.cs
:
public class Class1: IPlugin
{
public string Name => "Sample Plugin";
public void Execute()
{
Log.Info("MyAppTag", "Sample Plugin Executed!");
}
}
И основной класс с вредоносным функционалом Class1.cs
:
public class Class1: IPlugin
{
public string Name => "Sample Plugin";
public void Execute()
{
Log.Info("MyAppTag", "Sample Plugin Executed!");
}
}
Собираем проект. У нас должен появиться DLL в папке Release с именем SamplePlugin.dll
. Копируем ее в основной проект. В основном проекте прописываем путь к SamplePlugin.dll
в app.csproj
. Она должна будет лежать в папке assets
, в конечной апк:
<AndroidAsset Include="xamarin/app/SamplePlugin.dll" />
У нас есть главный класс MainPage.xaml.cs
, который содержит основную логику. Для начала нам надо скопировать SamplePlugin.dll
из папки assets
в другое место:
public static string ExtractLibrary(Android.Content.Context context, string libraryName)
{
// Путь, куда будет извлечена библиотека
string destinationPath = Path.Combine(context.FilesDir.AbsolutePath, libraryName);
AssetManager assets = context.Assets;
using (Stream inputStream = assets.Open(libraryName))
using (FileStream outputStream = new FileStream(destinationPath, FileMode.Create))
{
inputStream.CopyTo(outputStream);
}
return destinationPath; // Возвращаем полный путь к библиотеке
}
Контекст мы можем получить так:
var context = Android.App.Application.Context;
После копирования библиотеки, загружаем ее в память:
var assembly = Assembly.LoadFrom(libPath);
И вызываем вредоносный метод:
var method = type.GetMethod("Execute");
method.Invoke(instance, null);
Вот и все! Проект загружен на гитхаб, вы можете использовать его как шаблон для своих идей.
Вверх