Заменить параметры командной строки процесса
От: Аноним  
Дата: 30.09.11 07:00
Оценка:
Доброго времени суток!

Приложение получает в командной строке критичный параметр:
myprogram.exe -param somecriticalvalue

Проблема в том, что через тот же taskmanager можно подсмотреть этот параметр.
Попытки записи в переменную lpCmdLine из WinMain успеха не дали, равно как и такой наивный код:

LPTSTR lpCmdLine=GetCommandLine();
strcpy(lpCmdLine, _T("myprogram.exe -param hidden"));

Есть ли возможность реализовать задуманное и если да, то как ?
Re: Заменить параметры командной строки процесса
От: ononim  
Дата: 30.09.11 07:07
Оценка: 8 (1)
...есть одно но — писать надо и в анси версию командлайна и в юникод. То есть
*GetCommandLineA() = 0 ;
*GetCommandLineW() = 0 ;
Как много веселых ребят, и все делают велосипед...
Re[2]: Заменить параметры командной строки процесса
От: Аноним  
Дата: 30.09.11 07:24
Оценка:
Здравствуйте, ononim, Вы писали:

O>...есть одно но — писать надо и в анси версию командлайна и в юникод. То есть

O>
O>*GetCommandLineA() = 0 ;
O>*GetCommandLineW() = 0 ;
O>


Попробовал — не помогает. Taskmanager из Win7 показывает оригинальную командную строку.
Re: Заменить параметры командной строки процесса
От: acDev Россия  
Дата: 30.09.11 07:26
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Доброго времени суток!


А>Приложение получает в командной строке критичный параметр:

А>myprogram.exe -param somecriticalvalue
А>Проблема в том, что через тот же taskmanager можно подсмотреть этот параметр.

Установи ProcessMonitor (или аналог) и всё равно увидишь этот параметр)))
Вообще идиотическое решение проблемы!
О шифровании somecriticalvalue вообще думали? (command + current_time + hash)
Re: Заменить параметры командной строки процесса
От: De-Bugger  
Дата: 30.09.11 07:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Проблема в том, что через тот же taskmanager можно подсмотреть этот параметр.

Проблема только в желании удалять гланды через анус.
А ежели еще тебе сказать, что можно написать перехватчик CreateProcess и прочитать твой сикрет-парамс...?

Короче, шифруй командную строку.
Re[3]: Заменить параметры командной строки процесса
От: ononim  
Дата: 30.09.11 07:44
Оценка: +1
O>>...есть одно но — писать надо и в анси версию командлайна и в юникод. То есть
O>>
O>>*GetCommandLineA() = 0 ;
O>>*GetCommandLineW() = 0 ;
O>>

А>Попробовал — не помогает. Taskmanager из Win7 показывает оригинальную командную строку.
Попробовал — у меня помогает. Ни таскманагер ни процессэксплорер не показывают. Кстати, перезапустите таскманагер — он ведь мог запомнить строку на запуске проги, пока не стереть не успели аргумент.
Как много веселых ребят, и все делают велосипед...
Re[2]: Заменить параметры командной строки процесса
От: dcb-BanDos Россия  
Дата: 04.10.11 12:59
Оценка:
Здравствуйте, De-Bugger, Вы писали:

DB>Здравствуйте, Аноним, Вы писали:


А>>Проблема в том, что через тот же taskmanager можно подсмотреть этот параметр.

DB>Проблема только в желании удалять гланды через анус.
DB>А ежели еще тебе сказать, что можно написать перехватчик CreateProcess и прочитать твой сикрет-парамс...?

DB>Короче, шифруй командную строку.


это все прекрасно до тех пор, пока не нужно вызывать стороннюю утилиту с сикрет-парамс
Ничто не ограничивает полет мысли программиста так, как компилятор.
Re[3]: Заменить параметры командной строки процесса
От: Banned by IT  
Дата: 04.10.11 14:14
Оценка: +1
Здравствуйте, dcb-BanDos, Вы писали:

DB>>Короче, шифруй командную строку.

DB>это все прекрасно до тех пор, пока не нужно вызывать стороннюю утилиту с сикрет-парамс
Тут ситуация такая, что коммандлайн элементарно перехватывается готовыми и распространёнными утилитами (ProcMon) ещё когда вызываемая программа даже загрузиться не успела. Так что "потом затереть" уже вообще никак.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[2]: Заменить параметры командной строки процесса
От: watch-maker  
Дата: 04.10.11 16:55
Оценка:
Здравствуйте, De-Bugger, Вы писали:

DB>Короче, шифруй командную строку.


Вообще, не нужно шифровать командную строку, передавайте секреты через файловые потоки! Уж их содержимое подсмотреть не проще чем напрямую достать секрет из памяти процесса, а саму передачу делать не сильно сложнее чем передачу через командную строку.

Кстати, была такая утилита sshpass, которая передавала ssh-клиенту заданный ранее пароль. Разумеется, это уже не очень хорошо с точки зрения безопасности, так как в таком случае нужно использовать ключи доступа, а не пароли. Но иногда бывает ситуация, что ключей нет, но есть пароль, а вручную его вводить в каждой ssh-сессии накладно (ибо, как известно, опять же в целях безопасновти, ssh-клинет требует именно ручного ввода пароля, и игнорирует его, если он, скажем, просто пришел в stdin).
Так вот, в sshpass есть несколько способов передать пароль:
Используй pipe.
Re[4]: Заменить параметры командной строки процесса
От: ononim  
Дата: 04.10.11 22:46
Оценка:
BBI>Тут ситуация такая, что коммандлайн элементарно перехватывается готовыми и распространёнными утилитами (ProcMon) ещё когда вызываемая программа даже загрузиться не успела. Так что "потом затереть" уже вообще никак.
ой да ладно, извратиться завсегда мона (x86 only):
#include "windows.h"
#include "malloc.h"

BOOL StartProcessSecretly(const WCHAR *image, const WCHAR *cmdline, DWORD flags, LPSTARTUPINFOW si, LPPROCESS_INFORMATION pi)
{
    if (!::CreateProcessW(image, 0, 0, 0, 0, flags|CREATE_SUSPENDED, 0, 0, si, pi))
        return FALSE;

    ::QueueUserAPC((PAPCFUNC)&SuspendThread, pi->hThread, (ULONG_PTR)-2);
    for (;;)
    {
        ::ResumeThread(pi->hThread);
        if (::SuspendThread(pi->hThread)==1)
        {
            ::ResumeThread(pi->hThread);
            break;
        }

        if (::WaitForSingleObject(pi->hThread, 0)==WAIT_OBJECT_0)
        {
            DWORD excode = -1;
            ::GetExitCodeThread(pi->hThread, &excode);
            ::TerminateProcess(pi->hProcess, excode);
            ::CloseHandle(pi->hProcess);
            ::CloseHandle(pi->hThread);
            ::SetLastError(excode);
            return FALSE;
        }

        ::Sleep(0);
    }
    size_t l = wcslen(cmdline) + 1;
    char *ansi = (char *)alloca(l);
    ::WideCharToMultiByte(CP_ACP, 0, cmdline, l, ansi, l, 0, 0);
    PWCHAR p = (PWCHAR)::VirtualAllocEx(pi->hProcess, 0, l*sizeof(WCHAR)+l, MEM_COMMIT, PAGE_READWRITE);
    SIZE_T sz;
#include <PshPack1.h>
    struct 
    {
        BYTE mov_eax;
        ULONG ptr;
        BYTE ret;
    } code_w = {0xB8, (ULONG)p, 0xc3};
    struct 
    {
        BYTE mov_eax;
        ULONG ptr;
        BYTE ret;
    } code_a = {0xB8, (ULONG)(p+l), 0xc3};
#include <PopPack.h>
    if (!p || !::WriteProcessMemory(pi->hProcess, p, cmdline, l*sizeof(WCHAR), &sz ) 
        || !::WriteProcessMemory(pi->hProcess, p+l, ansi, l, &sz )
        || !::WriteProcessMemory(pi->hProcess, &::GetCommandLineW, &code_w, sizeof(code_w), &sz )
        || !::WriteProcessMemory(pi->hProcess, &::GetCommandLineA, &code_a, sizeof(code_a), &sz ))
    {
        ::TerminateProcess(pi->hProcess, ::GetLastError());
        ::CloseHandle(pi->hProcess);
        ::CloseHandle(pi->hThread);
        return FALSE;
    }

    if (!(flags&CREATE_SUSPENDED)) ::ResumeThread(pi->hThread);
    return TRUE;
}

int main(int argc, char* argv[])
{
    STARTUPINFOW si = {sizeof(STARTUPINFOW), 0};
    PROCESS_INFORMATION pi = {0};
    WCHAR image[MAX_PATH+1] = {0};
    ::ExpandEnvironmentStringsW(L"%WINDIR%\\System32\\cmd.exe", image, MAX_PATH);
    if (StartProcessSecretly(image, L"cmd /K @echo Secret!", CREATE_NEW_CONSOLE, &si, &pi))
    {
        printf("Success\n");
        ::CloseHandle(pi.hProcess);
        ::CloseHandle(pi.hThread);
    }
    else
        printf("Error %u\n", GetLastError());
    
    return 0;
}
Как много веселых ребят, и все делают велосипед...
Re[5]: Заменить параметры командной строки процесса
От: Banned by IT  
Дата: 04.10.11 23:09
Оценка: +1
Здравствуйте, ononim, Вы писали:

BBI>>Тут ситуация такая, что коммандлайн элементарно перехватывается готовыми и распространёнными утилитами (ProcMon) ещё когда вызываемая программа даже загрузиться не успела. Так что "потом затереть" уже вообще никак.

O>ой да ладно, извратиться завсегда мона (x86 only):

Боюсь что проблем тут создастся больше чем решится.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[6]: Заменить параметры командной строки процесса
От: ononim  
Дата: 04.10.11 23:23
Оценка:
BBI>>>Тут ситуация такая, что коммандлайн элементарно перехватывается готовыми и распространёнными утилитами (ProcMon) ещё когда вызываемая программа даже загрузиться не успела. Так что "потом затереть" уже вообще никак.
O>>ой да ладно, извратиться завсегда мона (x86 only):
BBI>Боюсь что проблем тут создастся больше чем решится.
Если target процесс юзает GetCommandLine — никаких проблем, а если не юзает — нифига не сработает, — вполне детерминированное поведение
Впрочем, есть одно но — надо чтобы в нашем процессе GetCommandLine/SuspendThread Не были захуканы патчем IAT каким нить 3rd party инжектором и указывали по честному во внутренности kernel32. Но и это решаемо использованием своего парсера PE хедера (он у меня даже есть под рукой, но не все же сразу )
Как много веселых ребят, и все делают велосипед...
Re[7]: Заменить параметры командной строки процесса
От: Banned by IT  
Дата: 04.10.11 23:32
Оценка:
Здравствуйте, ononim, Вы писали:

BBI>>>>Тут ситуация такая, что коммандлайн элементарно перехватывается готовыми и распространёнными утилитами (ProcMon) ещё когда вызываемая программа даже загрузиться не успела. Так что "потом затереть" уже вообще никак.

O>>>ой да ладно, извратиться завсегда мона (x86 only):
BBI>>Боюсь что проблем тут создастся больше чем решится.
O>Если target процесс юзает GetCommandLine — никаких проблем, а если не юзает — нифига не сработает, — вполне детерминированное поведение
O>Впрочем, есть одно но — надо чтобы в нашем процессе GetCommandLine/SuspendThread Не были захуканы патчем IAT каким нить 3rd party инжектором и указывали по честному во внутренности kernel32. Но и это решаемо использованием своего парсера PE хедера (он у меня даже есть под рукой, но не все же сразу )

В общем для конечного решения надо написать ещё полтонны хаков.
А не дай б-г у юзера окажется антивирь...
Ну и кроме того есть опасения что ASRL может подгадить, тоже надо будет по длинному пути добывать адрес.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[8]: Заменить параметры командной строки процесса
От: ononim  
Дата: 05.10.11 06:37
Оценка:
BBI>А не дай б-г у юзера окажется антивирь...
ничего страшного, CreateProcess сам внутри себя (в kernel32.dll) юзает WriteProcessMemory, антивири обычно не заморачиваются с отслеживанием стектрейса вызова и просто разрешают парентовому процессу писаь в память дочернего.

BBI>Ну и кроме того есть опасения что ASRL может подгадить, тоже надо будет по длинному пути добывать адрес.

ASLR не нагадит.
Как много веселых ребят, и все делают велосипед...
Re[5]: Заменить параметры командной строки процесса
От: Аноним  
Дата: 06.10.11 10:48
Оценка:
Здравствуйте, ononim, Вы писали:

А можно прокомментировать немного код? Вот конкретно этот участок:

O>
O>BOOL StartProcessSecretly(const WCHAR *image, const WCHAR *cmdline, DWORD flags, LPSTARTUPINFOW si, LPPROCESS_INFORMATION pi)
O>{
O>    if (!::CreateProcessW(image, 0, 0, 0, 0, flags|CREATE_SUSPENDED, 0, 0, si, pi))
O>        return FALSE;

O>    ::QueueUserAPC((PAPCFUNC)&SuspendThread, pi->hThread, (ULONG_PTR)-2);
O>    for (;;)
O>    {
O>        ::ResumeThread(pi->hThread);
O>        if (::SuspendThread(pi->hThread)==1)
O>        {
O>            ::ResumeThread(pi->hThread);
O>            break;
O>        }

O>        if (::WaitForSingleObject(pi->hThread, 0)==WAIT_OBJECT_0)
O>        {
O>            DWORD excode = -1;
O>            ::GetExitCodeThread(pi->hThread, &excode);
O>            ::TerminateProcess(pi->hProcess, excode);
O>            ::CloseHandle(pi->hProcess);
O>            ::CloseHandle(pi->hThread);
O>            ::SetLastError(excode);
O>            return FALSE;
O>        }

O>        ::Sleep(0);
O>    }
O>


Понятно, что это синхронизация, не очень понятно так ли она здесь нужна? Разве не достаточно того, что поток заморожен? (Все примеры что видел до этого, просто делали CreateProcess(CREATE_SUSPENDED) и патчили что надо). Ещё вопрос: APC выполниться до первой строчки в цикле или нет? Поток ведь вроде сразу alertable. Если не сложно, прокомментируй плиз как меняется счетчик suspend/resume треды в цикле. И ещё, в этой синхронизации есть какая-то специфика, связанная с коммандной строчкой (и её использованием) или её (синхронизацию) можно использовать в произвольном "патчере"?
Re[6]: Заменить параметры командной строки процесса
От: ononim  
Дата: 06.10.11 11:03
Оценка:
А>Понятно, что это синхронизация, не очень понятно так ли она здесь нужна? Разве не достаточно того, что поток заморожен? (Все примеры что видел до этого, просто делали CreateProcess(CREATE_SUSPENDED) и патчили что надо). Ещё вопрос: APC выполниться до первой строчки в цикле или нет? Поток ведь вроде сразу alertable.
Не достаточно. Когда процесс создан в suspended состоянии в его АП есть тока его ntdll, образ его .exe PEB, USER_PROCESS_PARAMETERS, стек и TEB главного потока, и немного мути, относящейся к shimeng.dll и SXS. Ну может еще кто-нить чего-нить набросает, но не сцуть важно. Важно то, что kernel32.dll (и kernelbase.dll в семерке) там еще нету. А появляется он когда его вгружает ntdll!LdrpInitializeProcess (что он делает для всех win32 процессов, неважно надо она им или нет) когда процесс начнет исполняться. После этого LdrpInitializeProcess вгружает статик длл на которые залинкован процесс, и потом, в самом конце, зовет NtTestAlert и вот тут то и приходит наша APC. Ну если какая нить статически прилинкованная длл тоже позовет его или alertable wait — ничего страшного, главное — kernel32.dll уже на месте. Я не говорю что это самый красивый способ, зато он юзает минимум кодогенерации и даже ничего недокументированного вобщем-то не юзает, не считая того что загрузчик зовет NtTestAlert после загрузки kernel32.dll но это так начиная с самых древних NTей и вроде заканчивая восьмеркой.

А>Если не сложно, прокомментируй плиз как меняется счетчик suspend/resume треды в цикле. И ещё, в этой синхронизации есть какая-то специфика, связанная с коммандной строчкой (и её использованием) или её (синхронизацию) можно использовать в произвольном "патчере"?

Как меняется счетчик описано в MSDN в статьях про Suspend/ResumeThread.
Как много веселых ребят, и все делают велосипед...
Re[7]: Заменить параметры командной строки процесса
От: Аноним  
Дата: 06.10.11 12:13
Оценка:
Спасибо, теперь вроде в голове устаканилось.
Re[8]: Заменить параметры командной строки процесса
От: ononim  
Дата: 06.10.11 13:10
Оценка:
А>Спасибо, теперь вроде в голове устаканилось.
Вот ща подумалось — мона ведь запускать другой процесс вообще под дебагером, и патчить kernel32 непосредственно в момент его загрузки, если захочется чтобы остальные, статически прилинкованные длл, тоже увидели правильных командлайн (впрочем, то что они его сейчас не видят на этапе загрузки — может быть и фичей, там ведь и длл спайвара может какая инжектиться, которая командлайны подло тырит ).
Как много веселых ребят, и все делают велосипед...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.