Есть компьютер с чистой копией Windows, без доступа в интернет и без каких‑либо установленных средств разработки. Только одна чистая пользовательская «венда». Не поверите, но даже в таких спартанских условиях возможно написать и запустить полноценную программу. И сейчас я расскажу как.
![Ради этого скриншота я честно развернул пользовательскую версию Windows 11 в виртуальной машине. Чего не сделаешь ради искусства! Ради этого скриншота я честно развернул пользовательскую версию Windows 11 в виртуальной машине. Чего не сделаешь ради искусства!](https://habrastorage.org/getpro/habr/upload_files/fe5/80d/ba6/fe580dba685bd8bb82eaa625cbfbd7d7.png)
Ужасы познания
На самом деле в ОС семейства Windows с самого их начала было внутри столько всякого интересного, что никакой статьи не хватит описать, так что выпусков будет много ;)
Но почему-то мало кто об этом знает даже из разработчиков, особенно современных.
Спросите ради интереса знакомых разработчиков, возможно ли программировать на «чистой» пользовательской Windows без установки Visual Studio — удивитесь ответам.
Ну и разумеется насаждаемый «пользовательский» подход самой Microsoft, которая ковыряние во внутренностях своих продуктов мягко говоря никогда не поощряла, создал эдакий ареол простоты и надежности, без необходимости разбираться как оно внутри устроено.
Поэтому описанное ниже наверное вызовет определенный ужас как у обычных пользователей так и некоторых разработчиков — особенно если они обучались по видеокурсам ничего не знают об истории ОС Windows.
Начну с цитаты из одной интересной статьи:
Over the past few months, I've received several variations on this question for other operating systems and all of the released versions of the .NET Framework. When the .NET Framework is installed as a part of the OS, it does not appear in the Programs and Features (or Add/Remove Programs) control panel. The following is a complete list of which version of the .NET Framework is included in which version of the OS
И ниже длинный такой список с версиями. А вот еще один если вдруг первого оказалось недостаточно.
Ну казалось бы и.. что? Чего тут такого?
Про .NET SDK все и так знают, временами его необходимо установить «для запуска игор», временами он сам ставится в виде зависимой библиотеки и никому не мешает.
Все так, да.
Только что-то мне подсказывает внутрь вы не заглядывали, правда? Поэтому на что эта штука на самом деле способна не представляете.
А я представляю и сейчас расскажу.
Заходите в папку Windows на вашем компьютере, вот сюда:
![Этот снимок из Windows 10, в нем используется системная .NET SDK 3.5, в Windows 11 будет уже 4.0 Этот снимок из Windows 10, в нем используется системная .NET SDK 3.5, в Windows 11 будет уже 4.0](https://habrastorage.org/getpro/habr/upload_files/6ad/7ff/8c5/6ad7ff8c589e0ff86484014f2647034a.png)
Файлт csc.exe — самый настоящий компилятор, фактически портал в ад на вашем обычном домашнем компьютере.
Почему все так страшно?
Потому что через какое-то время вы обнаружите себя сильно заросшим, с бородой и красными глазами, проводящим ночи за компьютером и медленно мутирующим в программиста.
Шучу.
А если серьезно:
появляется возможность создания нативных программ сразу на вашем компьютере, минуя стадию проверки электронной подписи, проверки антивирусом, проверки электронного письма и так далее.
В отличие от VB или PowerShell-скриптов, которые анализируются перед запуском любым приличным антивирусом, антивирусы не анализируют исходный код программ на C# и куда лояльнее относятся к программам собранным локально на этой же машине.
Так что веселье начинается.
Простой пример
Для начала будет простой пример, который просто показывает стандартный диалог с сообщением. Именно его в запущенном виде вы можете видеть на заглавной картинке в статье.
Весь процесс от кода до запуска я записал на видео:
Исходный код тут казалось бы максимально простой, но с одним интересным нюансом про который ниже:
using System;
using System.Runtime.InteropServices;
namespace yoba
{
class Program
{
// импортирование нативной WinAPI функции MessageBox.
[DllImport("user32.dll")]
public static extern int MessageBox(IntPtr hWnd, string lpText, string lpCaption, uint uType);
static void Main(string[] args)
{
//вызываем и показываем диалог
MessageBox(IntPtr.Zero, "Йоу!", "Добро пожаловать в разработку!", 0);
}
}
}
Сохраняете этот текст обычным «блокнотом» в файл yoba.cs и запускаете сборку:
c:\Windows\Microsoft.NET\Framework\v3.5\csc.exe yoba.cs
Таким образом я запускал сборку на Windows 10, но имейте ввиду что версия системного .NET SDK может отличаться и например в Windows 11 уже будет:
c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe yoba.cs
После сборки рядом с исходным файлом yoba.cs появится и запускабельный бинарник yoba.exe, который вы сможете запустить.
А теперь про нюанс.
Нюанс
Существует определенное предубеждение по отношению к managed‑языкам вроде Java и С# — они не подходят для серьезных дел вроде написания эксплоитов, использования 0day‑уязвимостей и пенетрации ядра.
Что все подобные вещи творят
в глубокой тайнена чистом Си, в крайнем случае на C++ а все эти ваши Java/C# не более чем «погремушки для детей», не достойные даже косого взгляда серьезного профессионала.
Вот тут и начинается нюанс, посмотрите на эту радость:
[DllImport("user32.dll")]
public static extern int MessageBox(IntPtr hWnd,
string lpText, string lpCaption, uint uType);
Это мои дорогие читатели, ни что иное как вызов нативного WinAPI, с помощью которого творили всякое нехорошее в далекие 90е.
C# и .NET имеет оооочень глубокую интеграцию с Windows, несмотря на всю свою «безопасность» и управляемость, поэтому легко и просто может заменить собой и Си и С++ в качестве инструмента для нехороших дел.
И оно живет на вашем компьютере, дома и в офисе, с постоянной пропиской и регистрацией.
Но разумеется столь простого примера несколько мало для осознания глубины проблемы, поэтому я подготовил кое-что более серьезное.
Сложный пример: выключаем Windows
Итак, это будет относительно небольшое приложение на C#, выключающее компьютер без предупреждения и подтверждения пользователя. И само собой без прав администратора.
Просто так, внезапно.
Последствия думаю каждый из читателей сможет оценить для себя сам.
Весь процесс на видео (разумеется это виртуальная машина):
А теперь код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security;
using System.Diagnostics;
using System.Management;
using System.Security.Permissions;
using System.Runtime.InteropServices;
namespace yoba
{
// See http://www.developmentnow.com/g/33_2004_12_0_0_33290/Access-Denied-on-ManagementEventWatcher-Start.htm
// Calling this code on backup/restore seems to enable BCD
public class TokenHelper
{
// PInvoke stuff required to set/enable security privileges
[DllImport("advapi32", SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
static extern int OpenProcessToken(
System.IntPtr ProcessHandle, // handle to process
int DesiredAccess, // desired access to process
ref IntPtr TokenHandle // handle to open access token
);
[DllImport("kernel32", SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
static extern bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
static extern int AdjustTokenPrivileges(
IntPtr TokenHandle,
int DisableAllPrivileges,
IntPtr NewState,
int BufferLength,
IntPtr PreviousState,
ref int ReturnLength);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
static extern bool LookupPrivilegeValue(
string lpSystemName,
string lpName,
ref LUID lpLuid);
[StructLayout(LayoutKind.Sequential)]
internal struct LUID
{
internal int LowPart;
internal int HighPart;
}
[StructLayout(LayoutKind.Sequential)]
struct LUID_AND_ATTRIBUTES
{
LUID Luid;
int Attributes;
}
[StructLayout(LayoutKind.Sequential)]
struct _PRIVILEGE_SET
{
int PrivilegeCount;
int Control;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=1)] // ANYSIZE_ARRAY = 1
LUID_AND_ATTRIBUTES [] Privileges;
}
[StructLayout(LayoutKind.Sequential)]
internal struct TOKEN_PRIVILEGES
{
internal int PrivilegeCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]
internal int[] Privileges;
}
const int SE_PRIVILEGE_ENABLED = 0x00000002;
const int TOKEN_ADJUST_PRIVILEGES = 0X00000020;
const int TOKEN_QUERY = 0X00000008;
const int TOKEN_ALL_ACCESS = 0X001f01ff;
const int PROCESS_QUERY_INFORMATION = 0X00000400;
public static bool SetPrivilege (string lpszPrivilege, bool
bEnablePrivilege )
{
bool retval = false;
int ltkpOld = 0;
IntPtr hToken = IntPtr.Zero;
TOKEN_PRIVILEGES tkp = new TOKEN_PRIVILEGES();
tkp.Privileges = new int[3];
TOKEN_PRIVILEGES tkpOld = new TOKEN_PRIVILEGES();
tkpOld.Privileges = new int[3];
LUID tLUID = new LUID();
tkp.PrivilegeCount = 1;
if (bEnablePrivilege)
tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
else
tkp.Privileges[2] = 0;
if(LookupPrivilegeValue(null , lpszPrivilege , ref tLUID))
{
Process proc = Process.GetCurrentProcess();
if(proc.Handle != IntPtr.Zero)
{
if (OpenProcessToken(proc.Handle, TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
ref hToken) != 0)
{
tkp.PrivilegeCount = 1;
tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
tkp.Privileges[1] = tLUID.HighPart;
tkp.Privileges[0] = tLUID.LowPart;
const int bufLength = 256;
IntPtr tu = Marshal.AllocHGlobal( bufLength );
Marshal.StructureToPtr(tkp, tu, true);
if(AdjustTokenPrivileges(hToken, 0, tu, bufLength, IntPtr.Zero, ref
ltkpOld) != 0)
{
// successful AdjustTokenPrivileges doesn't mean privilege could be changed
if (Marshal.GetLastWin32Error() == 0)
{
retval = true; // Token changed
}
}
TOKEN_PRIVILEGES tokp = (TOKEN_PRIVILEGES) Marshal.PtrToStructure(tu,
typeof(TOKEN_PRIVILEGES) );
Marshal.FreeHGlobal( tu );
}
}
}
if (hToken != IntPtr.Zero)
{
CloseHandle(hToken);
}
return retval;
}
}
class ShutDown
{
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool ExitWindowsEx(int flg, int rea);
internal const int EWX_FORCE = 0x00000004;
internal const int EWX_POWEROFF = 0x00000008;
static void Main(string[] args)
{
TokenHelper.SetPrivilege("SeShutdownPrivilege",true);
ExitWindowsEx(EWX_FORCE | EWX_POWEROFF, 0);
}
}
}
Обращаю внимание что это не эксплоит, не дыра, не баг и не уявимость а вполне себе стандартный функционал. Просто так получилось что о нем мало кто знает.
Собирается по аналогии с предыдущим примером:
c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe Shutdown.cs
После запуска компьютер практически немедленно выключится:
проверено и в виртуальной машине и на железе, на 10й и 11й Windows.
Рассказываю как это работает.
Ключевая функция — ExitWindowsEx, которая и отвечает за завершение работы ОС. Эта функция очень старая и известная, существует еще со времен Windows 95.
Но для ее вызова нужны «привилегии», которые и выставляет программно класс TokenHelper.
Константы ниже:
internal const int EWX_FORCE = 0x00000004;
internal const int EWX_POWEROFF = 0x00000008;
используются вместе с "побитовым или" для указания на требуемое действие.
Вот еще допустимые варианты:
internal const int EWX_LOGOFF = 0x00000000;
internal const int EWX_SHUTDOWN = 0x00000001;
internal const int EWX_REBOOT = 0x00000002;
internal const int EWX_FORCEIFHUNG = 0x00000010;
Описание их всех находится все там же — в официальном руководстве, не поверите.
Теперь давайте разбираться как же работает столь жесткое забивание на систему защиты еще и стандартными средствами:
TokenHelper.SetPrivilege("SeShutdownPrivilege",true);
И начнем мы с импортов.
Первое что импортируется это функция OpenProcessToken:
[DllImport("advapi32", SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
static extern int OpenProcessToken(
System.IntPtr ProcessHandle, // handle to process
int DesiredAccess, // desired access to process
ref IntPtr TokenHandle // handle to open access token
);
Функция отвечает за получение данных о наборе «привилегий», связанных с конкретным процессом. Собственно набор таких привилегий и называется «токеном».
Вот как эта функция вызывается:
if (OpenProcessToken(proc.Handle, TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
ref hToken) != 0)
{
..
Тут надо отметить передачу по ссылке в стиле Си (ref hToken), когда в функцию передается ссылка на объект C#, дальше функция этот объект заполняет данными. А возвращает она просто true или false — статус выполнения, отработала функция или нет.
Дальше импортируется простая и банальная функция освобождения ресурсов:
[DllImport("kernel32", SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
static extern bool CloseHandle(IntPtr handle);
Вызывается она в самом конце, после всей логики и нужна только для освобождения использованной памяти под токен привилегий:
if (hToken != IntPtr.Zero)
{
CloseHandle(hToken);
}
Наконец главная функция, непосредственно отвечающая за переключение привилегий:
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
static extern int AdjustTokenPrivileges(
IntPtr TokenHandle,
int DisableAllPrivileges,
IntPtr NewState,
int BufferLength,
IntPtr PreviousState,
ref int ReturnLength);
Вот весь ключевой блок логики смены привилегий:
if (OpenProcessToken(proc.Handle, TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
ref hToken) != 0)
{
tkp.PrivilegeCount = 1;
tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
tkp.Privileges[1] = tLUID.HighPart;
tkp.Privileges[0] = tLUID.LowPart;
const int bufLength = 256;
IntPtr tu = Marshal.AllocHGlobal( bufLength );
Marshal.StructureToPtr(tkp, tu, true);
if(AdjustTokenPrivileges(hToken, 0, tu, bufLength, IntPtr.Zero, ref
ltkpOld) != 0)
{
// successful AdjustTokenPrivileges doesn't mean privilege could be changed
if (Marshal.GetLastWin32Error() == 0)
{
retval = true; // Token changed
}
}
TOKEN_PRIVILEGES tokp = (TOKEN_PRIVILEGES) Marshal.PtrToStructure(tu,
typeof(TOKEN_PRIVILEGES) );
Marshal.FreeHGlobal( tu );
}
Как видите вызов достаточно сложный, используется Сишный процедурный подход к заполнению полей структуры и передачи его по ссылке в вызываемую функцию.
После вызова проверяется наличие ошибки, также в стиле Си:
if (Marshal.GetLastWin32Error() == 0)
{
retval = true; // Token changed
}
0 это код возрата для успешного вызова, если он есть — считается что операция смены привилегий была выполнена успешно.
Наконец последняя функция, про которую стоит рассказать:
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
static extern bool LookupPrivilegeValue(
string lpSystemName,
string lpName,
ref LUID lpLuid);
Она отвечает за поиск привилегии по имени, полагаю ведь заметили что мы передаем некое кодовое наименование при вызове TokenHelper:
TokenHelper.SetPrivilege("SeShutdownPrivilege",true);
Именно эта функция отвечает за поиск конкретной привилегии по названию «SeShutdownPrivilege», вот так выглядит ее вызов:
if (bEnablePrivilege)
tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
else
tkp.Privileges[2] = 0;
if(LookupPrivilegeValue(null , lpszPrivilege , ref tLUID))
{
..
Переменная bEnablePrivilege булевая, это и есть то самое true передаваемое в качестве второго аргумента, а блок:
if (bEnablePrivilege)
tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
else
tkp.Privileges[2] = 0;
отвечает за формирование правильного вызова с использованием системных констант (SE_PRIVILEGE_ENABLED).
При вызове также передается ссылка (ref tLUID) на объект LUID, который будет содержать после вызова указание на найденную привилегию.
Вот такие дела.
Итого
Все описанное не призыв к немедленным действиям, а лишь повод к размышлению о смысле бытия. Ну там насчет надежности, безопасности и всего такого — что вам продает большая иностранная корпорация.
Задумайтесь, если увидите любимую венду на атомной станции или военном объекте — без всяких ЦРУ и хакеров в ОС Windows адова гора функционала, который легко и просто можно использовать во вред.
Я много еще чего могу рассказать про мир Windows и его внутренее устройство, так что будут еще статьи на эту тему. И надеюсь хоть кто-то задумается, сделает выводы и поймет что «массовому» продукту не место в серьезных местах, где нужна настоящая защита и настоящая безопасность.
Это немного отцезурированная версия моей статьи, оригинал доступен в нашем блоге. Сейчас готовится вторая часть этой статьи, где будет рассказ про современную веб‑разработку в таких же условиях — следите за анонсами!
0x08 Software
Мы небольшая команда ветеранов ИТ‑индустрии, создаем и дорабатываем самое разнообразное программное обеспечение, наш софт автоматизирует бизнес‑процессы на трех континентах, в самых разных отраслях и условиях.
Оживляем давно умершее, чиним никогда не работавшее и создаем невозможное — затем рассказываем об этом в своих статьях.
Комментарии (44)
aaoo
21.08.2024 12:37а разве скомпилированный экзешник не будет проверен антивирем? всё равно что содержит cs файл, главное во что он скомпилируется и какое подозрение вызовет. в чём прикол такого использования? по заголовку статьи: "разработка без всего" - ну ок, в составе винды есть компиль и дальше что? писать в блокноте? я думаю я не один такой, который пользуется студией, потому что в ней куча утилит ускоряющих работу, а не невозможность программирования без неё в принципе.
uuger
21.08.2024 12:37+4Задумайтесь, если увидите любимую венду на атомной станции
Так получилось, что я видел. Все компьютеры, которые управляли хоть чем-то "интересным" работали в отдельных сетях, физически отвязанных даже от внутреннего интранета
И даже на "офисных" компах туториал обрывался бы на "Заходите в папку Windows"
alex0x08 Автор
21.08.2024 12:37Надеюсь что виденные объекты располагались далеко от Ленинградской области или Москвы с подмосковьем.
uuger
21.08.2024 12:37а какой потенциально опасный сценарий вы видите при работе на ПК с windows под пользователем, ограниченным в правах вплоть до белых списков ПО и с полным отсутствием доступа к системному диску, в плане влияния на соседний компьютер АСУТП, подключенного к другому не то, что ЛВС, а а даже к источнику 220?
alex0x08 Автор
21.08.2024 12:37а какой потенциально опасный сценарий
если на машине есть работающий компилятор, любой пользователь вне зависимости от прав и уровня доступа всегда может натворить дел.
Не существует защищенного окружения по определению и всегда можно выйти за рамки песочницы.
Кстати насчет системного диска: обычной (не embedded) Windows для работы нужен доступ на запись в системный диск, это не отключается и не настраивается в принципе.
А если есть такой доступ, то ограничение остается лишь на уровне вызовов API - через описанный в статье механизм привилегий и соответственно всегда остается возможность эскалации.
saboteur_kiev
21.08.2024 12:37Не существует защищенного окружения по определению и всегда можно выйти за рамки песочницы.
Существует, и компилятор тут не причем.
любой пользователь вне зависимости от прав и уровня доступа всегда может натворить дел.
Так можно сразу взять топор и по реактору...
alex0x08 Автор
21.08.2024 12:37Существует, и компилятор тут не причем.
"Блажен кто верует", лишь скромно надеюсь что вы не имеете отношения к РВСН и вообще далеко от Питера и Москвы :)
maikuss
21.08.2024 12:37+1Ну, вам как бы стоило бы взглянуть на ник пользователя, которому вы написали про РВСН и расстояния.
alex0x08 Автор
21.08.2024 12:37Ну а вам бы стоило хоть раз по делу написать, хоть один комментарий про разбор логики работы, про код и внутренее устройство.
Было бы гораздо лучше, честное слово.
maikuss
21.08.2024 12:37Да вам и без меня уже всё написали, разве ещё что-то не понятно? Впрочем, уверен, однажды вы станете автором интересного и полезного сообществу материала.
alex0x08 Автор
21.08.2024 12:37Без вас к сожалению получается как обычно: два сообщения (с натяжкой) по делу, что крайне печалит с учетом сложности статьи.
Так что все также жду чего-то по делу.
aaoo
21.08.2024 12:37+3ерунда. если уж сильно хочется натворить дел на такой машине, то и компилятор не нужен. опкоды в зубы и погнали в блокноте накидывать. уязвимости тут нет
alex0x08 Автор
21.08.2024 12:37Если покажете "Hello world" набитый опкодами в блокноте - пожму руку. Честно.
aaoo
21.08.2024 12:37т.е. вы хотите сказать, что это невозможно? :) вы разве не видите в подходе с компилятором, что проблема вовсе не в компиляторе?
alex0x08 Автор
21.08.2024 12:37Возможно, но я хочу на это поглядеть )
aaoo
21.08.2024 12:37+1ну вот смотрите. я не программист на ассемблере, и максимум что до этого на нём делал - это как раз хеллоуворлд, но вот вам PoC.
допустим вы хотите сделать что-то на аэс паловерде в арканзасе. это довольно серьёзно и у вас очень сильная мотивация, а значит трудности вас не остановят.
вы подготовили сначала программу, например вот такую: http://blog.code-cop.org/2015/07/hello-world-windows-32-assembly.html
скомпилировали у себя на машине (по ссылке есть описание как сделать). готовый экзешник занимает приблизительно 5 кило.
вы старательно, используя стеганографию, естественно, записываете все значения байт на листочки А4, в блокнот или просто запоминаете. (вы же не забыли, что миссия у вас очень ответственная)
затем на рабочем месте вы используете скажем команду echo:
echo 4D5A90000300000004000000FFFF > in.hex
если нужно, то куски объединяете при помощи copy.
или просто вот так текстом накидываете в блокнот. да не быстро, но это возможно и не сложно даже не особо подготовленному плохишу.
затем попробуете, скажем, вот такую команду в cmd:
certutil -decodehex in.hex hello.exe
и внезапно у вас рабочий бинарник.
данная инфа была собрана гуглежом и испробована меньше чем за 15 минут (естественно без учёта набора байтиков).
а теперь представьте, что вы действительно занимаетесь такими серьёзными вещами на аэс в арканзасе. разве наличие и отсутствие компилятора как-то повлияет на этот процесс?
Байты текстом умещаются на один экран
Zenitchik
21.08.2024 12:37любой пользователь вне зависимости от прав и уровня доступа всегда может натворить дел
И куда он после этого денется?
В подобных местах - пропускной режим. Кто работает за каким рабочим местом - все знают.
В таких условиях некому "натворить дел".
Ukrainskiy
21.08.2024 12:37+2А ведь в современных Linux-дистрибутивах компиляторы и утилиты для разработки не всегда поставляются. Windows 1 — 0 Linux.
codecity
21.08.2024 12:37утилиты для разработки не всегда поставляются
Если есть возможность запускать скрипты - то ведь можно запустить и apt-get install -y build-essential
alex0x08 Автор
21.08.2024 12:37Если речь про Ubuntu где из базового дистрибутива убрали gcc - наверное да, но вообще для Linux всегда было характерным иметь в базовой системе все средства разработки вплоть до IDE. Уж emacs какой-нибудь точно был всегда.
saboteur_kiev
21.08.2024 12:37То есть?
Баш, перл, питон, awk, sed, hexdump и другие - доступны из коробки
Да, gcc может отсутствовать, так он и не нужен в рантайме. Тут тогда вопросы к безопасности виндовс.
codecity
21.08.2024 12:37Основной вопрос, может я пропустил - а как же мне на чужом компе запустить скрипт на сборку чего-либо?
MountainGoat
21.08.2024 12:37+1Например, воткнуть в USB порт девайс, представившийся клавиатурой, который откроет шелл и набъёт команды. Если подключение внешних дисков отключают часто, то вот подключение новой клавиатуры - далеко не всегда.
alex0x08 Автор
21.08.2024 12:37+2Вообще это первая часть и тут речь про один только голый компилятор csc.exe.
В качестве спойлера для второй части скажу, что нашелся и msbuild (те самые скрипты сборки) и реляционная СУБД и парсеры JSON/XML и HTTP-сервер с вебсокетами - все это внутри обычной пользовательской венды.
Так что дальше будет веселее.
qark
21.08.2024 12:37Что помешало написать это в одной статье? Сейчас статья сводится к твиту "в Windows предустановлен компилятор C#".
saboteur_kiev
И видим установленный FAR ;)
А по поводу использованию штатной библиотеки из нормального полноценного языка "нативного" для винды С#n - не совсем понятно в чем должно быть удивление..
Полноценная работа с WindowsAPI возможно наверное из любого утюга. Тот же poweshell вполне умеет это делать, можно накатать скрипт, выполнить его в повершелле и обратиться к функциям ОС
Что касается уязвимостей, мне кажется что там вообще не столько привязка к каким-то языка программирования, сколько к пониманию архитектуры, и писать код можно почти на чем угодно.
alex0x08 Автор
PowerShell это все же про скрипты, а тут полноценный компилятор, который выдает .exe с интересным функционалом.
Если описанного про выключение мало, представьте эту же логику, только запускаемую в фоне со случайным промежутком и прописыванием в автозагрузку у пользователя.
Работаете себе, через 15 минут компьютер выключается. Перезапускаете - выключается через полчаса.
lair
А что представлять-то? Обычный пранк, я таких много помню. Не понимаю, что тут уникально интересного.
alex0x08 Автор
У разных людей сильно разное отношение с реальностью, как и осознание происходящего с ними. А у описанного в статье «внезапного выключения» есть предыстория:
Единственное чего я не ожидал так это последствий: одногруппник тогда разбил свой компьютер об стену, выкинул системный блок из окна а сам уехал отдыхать в дурку с острым психозом.
Несмотря на то что считался «компьютерным специалистом» и вообще был на хорошем счету.
Так что кому пранк а кому шиза — все зависит от восприятия реальности.
lair
Мы вроде на техническом сайте, так что лично меня интересуют технические аспекты, а не то, как люди реагируют на издевательства.
alex0x08 Автор
Ну тогда рад что столь сложная техническая статья, материал для которой я собирал не один год оказалась для вас не более чем "пранком".
lair
Вы "не один год" собирали материал о том, что в любой современной инсталляции винды есть
csc
?alex0x08 Автор
Угу, но разумеется столь крутой профессионал как вы сможет написать что-то покруче. Так что ждем ваших статей.
saboteur_kiev
Так если даже из скрипта можно обратиться к нативной библиотеке, понятно что из компилируемого, еще и нативного для винды С# это можно сделать.
Таким образом суть статьи в том, что оказывается простой компилятор С# входит в поставку винды?
Что же касается выключения компьютера, у меня есть некоторые сомнения, что данное возможно от regular пользователя у которого нет прав на выключение компа, то есть там нет никаких специальных "повышений привилегий".
Если права есть, есть и штатная утилита shutdown.exe, которую тоже можно вызвать по расписанию, и которая вдобавок подписанная ключом от MS, не будет вызывать лишних вопросов у антивирусов.
MonkAlex
Лет 15 назад я это решал батником
И оно всё ещё работает. Зачем вам C#, компилятор и прочее?
ПС: ну и если злоумышленник может писать в систему (чтобы создать файл исходников) и запускать компиляцию, то наличие или отсутствие компилятора никого не остановит. А антивирус проверяет всё, что внешние файлы, что созданные в системе.
alex0x08 Автор
15 лет назад еще выпускался журнал "Хакер" и все было несколько проще в плане компьютерной безопасности.
Если я вам перешлю готовый бинарник, то при попытке запуска появится окно с подтверждением и сообщением о "доверенном источнике". Если вы соберете этот же бинарник локально и затем запустите - такого сообщения не будет.
Все тоже самое с антивирусом, локально собранные бинарники он пропустит, даже если внутри будет эскалация привилегий или эксплоит, по той простой причине что эвристика осталась видимо только у Касперского а все остальные работают по сигнатурам бинарной сборки - т.е тупо по слепкам бинарников.
Очевидно что слепок локально собранного будет отличаться.
MonkAlex
Кто-то вас обманул. Время от времени разработчики жалуются, что у них один и тот же код на разных базах антивируса начинает выдавать срабатывания. Прямо при билде, на их машинах.
И чаще всего речь как раз про касперского, т.к. он у нас самый популярный в России.
alex0x08 Автор
Ну да, вы описали как раз работу эвристического алгоритма, я и написал что по ощущениям такое осталось только у Касперского - "визжит свиньей" по поводу и без только он один.
MonkAlex
Накидал на C# код, который портит exe файлы. При попытке тронуть этот файл в проводнике получил от защитника виндовс такую маркировку вируса:
После чего дефендер файл удалил.
Так что дело не только в касперском. Могли бы и сами проверить, а не просто кидаться своими догадками.
alex0x08 Автор
Тут сложно что-то сказать не видя код, судя по поиску эта сигнатура какая-то сильно общая и срабатывает на много чего.
А проверять я вообщем-то проверял, но статья-то как-бы не об этом ))
MonkAlex
А о чём статья? Вы же пишите, что если взять и скомпилировать "вредносный код" на чужой машине, то антивирус не заметит.
Я отмечаю, что заметит - вы мне в ответ, что статья не о том.
alex0x08 Автор
Ну не буду же я блин постить на Хабре серьезный работающий зловред - это уже перебор ))
Поэтому озвучиваю лишь идеи и риски, не более того.
Что с этой информацией делать решать читателям. Кому надо тот поймет.
Статья писалась прежде всего из спортивного интереса самой возможности разработки на чистой ОС и без установленных средств, описанное про антивирус не более чем возможный побочный эффект.