dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.43k stars 4.76k forks source link

/p:PublishTrimmed=true activates Windows Defender with a false-positive. #33745

Open 616E64726173 opened 4 years ago

616E64726173 commented 4 years ago

On NET.Core 3.1, Windows 10, VS 2019: /p:PublishTrimmed=true will cause Windows Defender to go berserk on my machine. /p:PublishTrimmed=false does not trigger any unexpected behavior.

I do not have a spare machine at the moment to try it with, but I am almost certain I don't have any malware hijacking the build process.

In C# zipping the output with System.IO.Compression results in System.IO.IOException: 'Operation did not complete successfully because the file contains a virus or potentially unwanted software.' which is how I caught this to begin with because my deployment process zips the publishing folder. No warnings are triggered if I do not zip anything - so I don't know whose at fault here - Windows Defender or Tools.Trimming; but I don't think WD has a Github to make an issue on.

Dependencies in my project as follows, and are all common packages:

<PackageReference Include="akavache" Version="6.10.4" />
<PackageReference Include="Avalonia" Version="0.9.3" />
<PackageReference Include="Avalonia.Desktop" Version="0.9.3" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.9.3" />
<PackageReference Include="Microsoft.Packaging.Tools.Trimming" Version="1.1.0-preview1-26619-01" />
<PackageReference Include="Microsoft.Win32.Registry" Version="4.7.0" />
<PackageReference Include="MonoMac.NetStandard" Version="0.0.4" />
<PackageReference Include="ReactiveUI" Version="11.1.23" />
<PackageReference Include="System.Resources.Extensions" Version="4.7.0" />

The detected virus is "Trojan:Win32/Sprisky.U!cl".

Any ideas? Turning off PublishTrimmed alleviates the issue and googling PublishTrimmed+virus gives me nothing of value. If a Microsoft employee gets in contact with me I could provide the project source and executables; but this is customer owned code and can't be otherwise published & shared.

Pinging @ViktorHofer @ericstj @safern @Anipik as per area owners guidelines.

Dotnet-GitSync-Bot commented 4 years ago

I couldn't add an area label to this Issue.

Checkout this page to find out which area owner to ping, or please add exactly one area label to help train me in the future.

Symbai commented 4 years ago

To submit a false report of Windows Defender visit https://www.microsoft.com/en-us/wdsi/filesubmission where you can submit your code in private. This is probably the wrong place.

616E64726173 commented 4 years ago

I would argue that it is meaningful to bring this to light. Roslyn is obviously producing code that is being flagged as a virus by Windows Defender, so it's likely it will be flagged by others as well.

xPaw commented 2 years ago

This still happens on .NET 6.

Build command: dotnet publish --configuration Release -p:PublishSingleFile=true -p:PublishTrimmed=true --self-contained --runtime win-x64 --framework net6.0

Gets blocked as Trojan:Script/Wacatac.B!ml.

safern commented 2 years ago

cc: @agocke

giggio commented 2 years ago

I just got it with .NET 7 RC1. image I was just following Microsoft's blog post and got it: https://devblogs.microsoft.com/dotnet/performance_improvements_in_net_7/#native-aot

ViktorHofer commented 2 years ago

cc @MichalStrehovsky

MichalStrehovsky commented 2 years ago

@giggio can you share the project you were compiling by any chance?

Looks like both https://github.com/dotnet/runtime/issues/33745#issuecomment-1003622426 and https://github.com/dotnet/runtime/issues/33745#issuecomment-1255584316 got detected as the same type of malware even though the executables are vastly different (there's absolutely nothing that is similar between the outputs of the two commands). That's odd.

giggio commented 2 years ago

@MichalStrehovsky yes, I had made a sample for a presentation I'm doing today. It's this one: https://github.com/giggio-samples/nativeaot-net7 The defender alert happened when I copied the file through File Explorer, and even when I did it with PowerShell. But I was able to run it in place, from the bin folder without issues.

giggio commented 2 years ago

@MichalStrehovsky I have uploaded the executable to onedrive: https://1drv.ms/u/s!AtCP7KJVgsELx4gqVEThMt62XaQNHQ?e=dTJvJD This is happening in a Release compilation, I did not test debug.

MichalStrehovsky commented 2 years ago

Doesn't repro for me with the EXE and Windows Defender

Rast1234 commented 2 years ago

Just spent 3 hours on this. Here is my repro:

https://github.com/Rast1234/SyncFaction/releases/tag/v4 - exe download is fine https://github.com/Rast1234/SyncFaction/releases/tag/v5 - flagged as virus

code changed between releases is very small: renamed a variable and used one instead of another. https://github.com/Rast1234/SyncFaction/compare/v4...v5

i did not update dotnet sdk, windows, chrome, rider or whatever between these releases, unless they updated themselves silently. now i can't publish v4 again because dotnet publish fails (output dll/exe gets blocked by defender).

i tried removing parts of my code, resources and references and pinned down to a minimal app with no user code whatsoever. removing <PublishSingleFile>true</PublishSingleFile> from csproj helped.


while i was writing this post, minimal app with PublishSingleFile stopped being flagged as false positive. no wonder people can't reproduce this, defender just does random things!


by the way at one moment while i was removing code, i found a source file where, if i add TRAILING NEWLINE AT END OF FILE, it lets me compile. if i remove this newline back, it does not compile because resulting file gets blocked. unbelievable.


right now my previously flagged releases become OK: v5 and v6. but not v7 at the moment.


by the way i can't even build v7 now. it was possible before couple hours ago. removing PublishSingleFile helps. here is relevant info: image

dotnet --info ```bash C:\vault\rfg\SyncFaction>dotnet --info .NET SDK (reflecting any global.json): Version: 6.0.301 Commit: 43f9b18481 Runtime Environment: OS Name: Windows OS Version: 10.0.19044 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\6.0.301\ Host (useful for support): Version: 6.0.6 Commit: 7cca709db2 .NET SDKs installed: 2.2.207 [C:\Program Files\dotnet\sdk] 6.0.201 [C:\Program Files\dotnet\sdk] 6.0.301 [C:\Program Files\dotnet\sdk] .NET runtimes installed: Microsoft.AspNetCore.All 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] To install additional .NET runtimes or SDKs: https://aka.ms/dotnet-download ```
DanteMarshal commented 9 months ago

Any updates on this ? We're shipping self-contained .exe file to our customer and they can't run it because of this. And defender blocks the files randomly. At first I thought it was because my assemblies were not signed, But I signed them and the problem still exists. We had like 40 customers last week out of whom about 30 couldn't use our app because of this disaster. We're considering finding a way to automatically exclude the files on customer's computer somehow.

p.s. We're using .Net 8.0, and I tried both Native AOT and simple self contained publishes, happens almost randomly with both. p.s. It never happened on my development laptop, but I could reproduce it on some other desktops in our office. Here's my related .csproj properties :

        <SelfContained>true</SelfContained>
        <PublishSingleFile>true</PublishSingleFile>
        <PublishReadyToRun>true</PublishReadyToRun>
        <IncludeNativeLibrariesForSelfExtract>false</IncludeNativeLibrariesForSelfExtract>
        <TrimmerSingleWarn>false</TrimmerSingleWarn>
        <ApplicationIcon>res/Icon.ico</ApplicationIcon>
        <SignAssembly>True</SignAssembly>
        <AssemblyOriginatorKeyFile>Private.snk</AssemblyOriginatorKeyFile>
MichalStrehovsky commented 9 months ago

I suggest you submit this through the antivirus vendor false positive channel. Each antivirus vendor has their own channel for false positives. If this is Defender, it was linked above, but to save you from looking: https://www.microsoft.com/en-us/wdsi/filesubmission.

DanteMarshal commented 9 months ago

I suggest you submit this through the antivirus vendor false positive channel. Each antivirus vendor has their own channel for false positives. If this is Defender, it was linked above, but to save you from looking: https://www.microsoft.com/en-us/wdsi/filesubmission.

When I was looking up for solutions I saw some people with similar problems having to submit their binaries every single time they have a new publish. Is this the same thing ?

MichalStrehovsky commented 9 months ago

I suggest you submit this through the antivirus vendor false positive channel. Each antivirus vendor has their own channel for false positives. If this is Defender, it was linked above, but to save you from looking: https://www.microsoft.com/en-us/wdsi/filesubmission.

When I was looking up for solutions I saw some people with similar problems having to submit their binaries every single time they have a new publish. Is this the same thing ?

I cannot give you a statement on this because I don't remember the last time I've seen output of native AOT or single file compilation flagged by Defender.

I do remember dotnet.exe (this is a C++ executable generated by the C++ compiler) being flagged at least twice in the past 2 years (for daily builds of .NET). We had to submit dotnet.exe through the above website several times already to clear it. (The detection rules that were triggering for dotnet.exe are very unlikely to be related to the native AOT/single file one because each dotnet.exe/single file/native AOT are very different executables doing different things.)

xPaw commented 8 months ago

Are we going to need to keep submitting exes to Microsoft every time we release because this is seemingly not going to be fixed?

We just made a release (which is built on github actions), and it's once again getting detected as Trojan:Script/Wacatac.B!ml.

a1batross commented 8 months ago

IMHO Microsoft Defender team should just fix their software first.

This is not the first time I see wacatac.b!ml on random harmless binaries, would they be written in .NET or in C or C++.

JMPZ11 commented 5 months ago

This is still the case, btw. What a disgrace. It has been four years and several releases. How in the he** have you not fixed this yet?

I have to rewrite my app in c++ because not everybody has the stupid runtime. I think I may be officially done with dotnet. It is not an improvement on the full framework. It is barely cross platform. The performance is terrible, and it has become nothing but harder to work with.

Then, after investing my time and effort into it... most virus scanners think it's a virus, including Defender.

It's as if you don't even test the thing.

henning-krause commented 4 months ago

I'm currently struggling with this as well. Our program is just a launcher for a third-party app, runs as a service and makes sure that the external process keeps running (e.g. restarts it if its closed). If the service is stopped, the external process is also shut down.

This program (.net 8, AOT on) is flagged as malicious by 14 AV engines (this time not by Microsoft Defender).

On VirusTotal, the scanners reported these "suspicious":

Execution TA0002 Command and Scripting Interpreter T1059 Sample might require command line arguments, analyze it with the command line cookbook Sample may offer command line options, please run it with the command line option cookbook (it's possible that the command line switches require additional characters like)

Shared Modules T1129 Link function at runtime on Windows

Persistence TA0003 Windows Service T1543.003 Creates or modifies windows services

DLL Side-Loading T1574.002 Tries to load missing DLLs

Privilege Escalation TA0004 Access Token Manipulation T1134 Modify access privileges

Windows Service T1543.003 Creates or modifies windows services

DLL Side-Loading T1574.002 Tries to load missing DLLs

Defense Evasion TA0005 Obfuscated Files or Information T1027 Decode data using Base64 via dword translation table

Reference Base64 string

Access Token Manipulation T1134 Modify access privileges

Virtualization/Sandbox Evasion T1497 Allocates memory with a write watch (potentially for evading sandboxes)

System Checks T1497.001 Reference anti-VM strings targeting Xen

DLL Side-Loading T1574.002 Tries to load missing DLLs

Discovery TA0007 Query Registry T1012 Query or enumerate registry key

Process Discovery T1057 Queries a list of all running processes

System Information Discovery T1082 Reads software policies Queries the volume information (name, serial number etc) of a device Query environment variable Get memory capacity Get system information on Windows

An adversary may attempt to get detailed information about the operating system and hardware, including version, patches, hotfixes, service packs, and architecture.

File and Directory Discovery T1083 Get common file path

Virtualization/Sandbox Evasion T1497 Allocates memory with a write watch (potentially for evading sandboxes)

System Checks T1497.001 Reference anti-VM strings targeting Xen

Security Software Discovery T1518.001 May try to detect the virtual machine to hinder analysis (VM artifact strings found in memory)

AV process strings found (often used to terminate AV products)

System Location Discovery T1614 Get geographical location

Command and Control TA0011 Application Layer Protocol T1071 Adversaries may communicate using application layer protocols to avoid detection/network filtering by blending in with existing traffic.

aiqinxuancai commented 4 months ago

From a logical standpoint, this should be an issue with antivirus software, rather than a problem with the software developer or a specific language or compilation method. Even the empty window program of C++ 6.0 MFC used to be considered a virus by many antivirus programs, and it is likely that some antivirus programs would still misreport it today.

The cycle of killing and being killed is endless, but it should be the responsibility of the antivirus software to advance and correct this. However, in reality, they are often very, very lazy.

The term "bypass antivirus" used to be a term in the gray industry, referring to techniques that prevent antivirus software from recognizing viruses and illegal remote control executables. Nowadays, however, this is something that many developers should pay attention to, as my legitimate programs also need to "bypass antivirus".

If you are serving a company, you should purchase a digital certificate to sign your executable. This way, most antivirus software will consider you safe.

If you are an individual developer, you cannot submit false positive feedback to each antivirus software for every version. Therefore, you can only persuade your users to temporarily disable their antivirus software and explain that this is a false positive and that your program is safe.

mrhelmut commented 3 months ago

This indeed is a Windows Defender issue.

We're making games with NativeAOT builds that are built on Github Actions and directly uploaded to Steam, so that should be an okay source for Windows Defender (wacatac is typically detected from apps downloaded as zip from the web, but Steam is considered a trusted source), but just recently Windows Defender has started to flag those Steam-downloaded builds too.

This happens with most of our games, but it never happened with Steam-downloaded builds, and that's a huge concern because it's millions of users (and the risk to be suspended by Steam).

It's detected as multiple variants, not just B!ml, but also H!ml and other.

The main problem is that the long term solution is indeed to CodeSign everything we produce (because uploading builds to their false-positive site is unrealistic for games with frequent updates), but that's another problem: CodeSign certificates can be expansive, and it doesn't make anything more secure. It's just a mafia-like system saying "you paid for our protection, so you're now whitelisted".

It would be cool if the Windows Defender team could be poked because it's exhausting that whenever anti-virus are involved, we always have to go into the same certificate-mafia-like thing and nothing ever gets fixed at the source.

MichalStrehovsky commented 3 months ago

I've reached out to someone I know on the Windows Defender side. No promises, but at least someone will look whether there is a problem (e.g. is this really more prevalent for native AOT?) and whether it's fixable.

Frostchi commented 1 month ago

Yup, lots of false positives coming from AOT binaries.

Compiling the same code non-AOT yields no hits on VirusTotal.

MichalStrehovsky commented 1 month ago

Yup, lots of false positives coming from AOT binaries.

Compiling the same code non-AOT yields no hits on VirusTotal.

I made a fix in .NET 9 that seems to significantly reduce the number of false positives with native AOT with certain antivirus vendors of snake oil qualities.

If you're still on .NET 8. you can apply the .NET 9 fix locally by adding this to your csproj:

<ItemGroup>
  <LinkerArg Include="/merge:.managedcode=.text" />
</ItemGroup>

(Might want to condition this for Windows-only, since it won't work on Linux)