Neo23x0 / Raccine

A Simple Ransomware Vaccine
The Unlicense
942 stars 123 forks source link

yara64 errors out every second after installation with VCRUNTIME140.dll missing. #87

Closed atlantsecurity closed 3 years ago

atlantsecurity commented 3 years ago

yara64 errors out every second after installation with VCRUNTIME140.dll missing. Windows 10 (latest), Raccine 1.2.1

JohnLaTwC commented 3 years ago

Can you see if installing the latest VC runtime solves the problem?

https://www.microsoft.com/en-us/download/details.aspx?id=52685

JohnLaTwC commented 3 years ago

Or maybe try this one. It seems to be the latest: https://aka.ms/vs/16/release/VC_redist.x64.exe, per https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads

JohnLaTwC commented 3 years ago

we could change the installer to check for the presence of the VC runtime.

IF NOT EXIST C:\Windows\System32\vcruntime140.dll explorer https://aka.ms/vs/16/release/vc_redist.x64.exe

or point to the website to pick the appropriate architecture: https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads

Neo23x0 commented 3 years ago

Ah, wow - a Windows 10 without the VC++ Runtime! I thought that would be pre-installed. Okay.

I think, since the installer already runs in the admin context, we could simply do something like:

vcredist_x64.exe /q /norestart
Neo23x0 commented 3 years ago

I hope that this will do the job

IF NOT EXIST C:\Windows\System32\vcruntime140.dll start vc_redist.x64.exe /q /norestart`

image

Neo23x0 commented 3 years ago

The build_dist.bat will now also download YARA and the VC++ runtime library and prepare the whole dist folder

image

atlantsecurity commented 3 years ago

https://aka.ms/vs/16/release/VC_redist.x64.exe fixed it. However manually deleting shadows using vssadmin does not get my command prompt killed - it just executes.

Neo23x0 commented 3 years ago
vssadmin delete shadows

?

Execute and provide output please.

REG QUERY "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\vssadmin.exe" /v Debugger
atlantsecurity commented 3 years ago

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\vssadmin.exe Debugger REG_SZ C:\Program Files\Raccine\Raccine.exe

atlantsecurity commented 3 years ago

`PS C:\Windows\system32> wmic shadowcopy call create Volume=c:\ Executing (Win32_ShadowCopy)->create() Method execution successful. Out Parameters: instance of __PARAMETERS { ReturnValue = 0; ShadowID = "{20D08C0D-62EE-4E26-8C54-5A740995BF22}"; };

PS C:\Windows\system32> vssadmin delete shadows /all vssadmin 1.1 - Volume Shadow Copy Service administrative command-line tool (C) Copyright 2001-2013 Microsoft Corp.

Do you really want to delete 3 shadow copies (Y/N): [N]? y

Successfully deleted 3 shadow copies. PS C:\Windows\system32>`

Neo23x0 commented 3 years ago

Can confirm - if started from powershell, it doesn't generate an alert Screenshot 2020-11-02 134833

JohnLaTwC commented 3 years ago

The issue is in this line (https://github.com/Neo23x0/Raccine/blob/f0b17453d61761773dc2f81070eeba2652ba02ac/source/RaccineLib/raccine.cpp#L162):

For this bit of code:

    if (program == L"vssadmin.exe" || program == L"vssadmin") {
        bVssadmin = true;
    }

Instead of program being set to vssadmin.exe, Powershell passes in c:\windows\system32\vssadmin.exe

Replace the above line with:

    const std::wstring program = utils::getFileName(utils::to_lower(command_line[0]));

And add the following code to Utils.cpp:

std::wstring getFileName(const std::wstring& s) 
{
    wchar_t sep = '/';

#ifdef _WIN32
    sep = '\\';
#endif

    size_t i = s.rfind(sep, s.length());
    if (i != std::wstring::npos) 
    {
        return(s.substr(i + 1, s.length() - i));
    }

    return(L"");
}

Add the following to Utils.h:

std::wstring getFileName(const std::wstring& s);
Neo23x0 commented 3 years ago

I had to change it a bit, since it worked for the invocation from PowerShell but broke all other executions. e.g. vssadmin delete shadows. The values has been empty in these cases.

I changed it so that it doesn't return an empty value in case it cannot find and return an element but the original command_line[0] as s.

std::wstring getFileName(const std::wstring& s) 
{
    wchar_t sep = '/';

#ifdef _WIN32
    sep = '\\';
#endif

    size_t i = s.rfind(sep, s.length());
    if (i != std::wstring::npos) 
    {
        return(s.substr(i + 1, s.length() - i));
    }

    return(s);
}

https://github.com/Neo23x0/Raccine/pull/99/files#diff-332617e92d102cdbe84becf24520dfe62682aeed620878dd9debcaa64ea7ce12R452