Syed Aslam Basha here. I am a tester on the Information Security Tools team and responsible for testing CAT.NET. You can run CAT.NET as;
Here am going to describe using CAT.NET as an MSBUILD custom task.
First you will need to create an MSBUILD project as shown below;
CATNET.csproj
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <CATNETPath>C:\Program Files\Microsoft\CAT.NET\CATNetCmd.exe</CATNETPath> </PropertyGroup> <PropertyGroup> <ReportLocation>D:\CATNET\report.xml</ReportLocation> </PropertyGroup> <ItemGroup> <ScanFiles Include="D:\CATNET\WebSite2_deploy.dll" /> </ItemGroup> <UsingTask AssemblyFile="D:\CATNET\CATNETCustomTask.dll" TaskName="CATNETScan"/> <Target Name="Default"> <Message Text=" "/> <Message Text=" "/> <Message Text="Testing CAT.NET Scan"/> <Message Text="------------------"/> <Message Text=" "/> <CATNETScan ScannedFiles="@(ScanFiles)" CATNETPath="$(CATNETPath)" ReportLocation="$(ReportLocation)"/> </Target> </Project>
Where CATNETPath is CATNETCmd.exe path, ReportLocation is path to report along with the filename, scanfiles is the file/s you want to scan using CAT.NET, UsingTaskAssemblyFile is the assembly(DLL) from the below code.
Create a class library solution “CATNETCustomTask.sln”, add a class and copy paste the below code and build it to generate “CATNETCustomTask.dll”.
(Add references, Microsoft.Build.Framework, Microsoft.Build.Tasks and Microsoft.Build.Utilities.v.3.5)
using System; using System.Collections.Generic; using System.Text; using Microsoft.Build.Tasks; using Microsoft.Build.Utilities; using Microsoft.Build.Framework; using System.IO; using System.Reflection; using System.Diagnostics; using System.Xml; namespace CustomTask { public class CATNETScan : ToolTask { private string _catnetPath; // The [Required] attribute indicates a required property. // If a project file invokes this task without passing a value // to this property, the build will fail immediately. [Required] public string CATNETPath { get { return _catnetPath; } set { _catnetPath = value; } } private string _scannedFiles; [Required] public string ScannedFiles { get { return _scannedFiles; } set { _scannedFiles = value; } } private string _reportLocation; [Required] public string ReportLocation { get { return _reportLocation; } set { _reportLocation = value; } } public override bool Execute() { try { int numIssues = 0; bool successStatus = base.Execute(); if (!successStatus) { return successStatus; } using (FileStream xmlFileStream = new FileStream(this.ReportLocation, FileMode.Open)) { XmlTextReader catnetReport = new XmlTextReader(xmlFileStream); while (catnetReport.Read()) { if (catnetReport.LocalName == "Issue" && catnetReport.NodeType == XmlNodeType.Element) { successStatus = false; numIssues++; } } if (!successStatus) { Log.LogError("Found {0} CATNET warnings, see {1} for more details", numIssues, xmlFileStream.Name); } return successStatus; } } catch (Exception e) { Log.LogErrorFromException(e); return false; } } protected override string GenerateFullPathToTool() { return CATNETPath; } protected override string GenerateCommandLineCommands() { CommandLineBuilder builder = new CommandLineBuilder(); if (ScannedFiles != null) { builder.AppendSwitch("/file:" + ScannedFiles); } else { Log.LogWarning("CATNET Task requires TargetAssembly"); } if (ReportLocation != null) { builder.AppendSwitch("/report:" + ReportLocation); } return builder.ToString(); } protected override string ToolName { get { return "CATNETcmd.exe"; } } } }
At command prompt run msbuild as
D:\CATNET>msbuild catnet.csproj /filelogger
This generates report.xml, msbuild.log and report.html file
CATNET folder has CATNETCustomTask.dll, WebSite2_deploy.dll and catnet.csproj
Report.html shows the list of security flaws identified by the CAT.NET.
You can add more property groups such as “Rule”,”config” etc.
<PropertyGroup> <ConfigPath>C:\Program Files\Microsoft\CAT.NET\Config\config.xml</ConfigPath> </PropertyGroup> <PropertyGroup> <RulePath>C:\Program Files\Microsoft\CAT.NET\Rules\</RulePath> </PropertyGroup>
The CATNETScan will change;
<CATNETScan ScannedFiles="@(ScanFiles)" CATNETPath="$(CATNETPath)" RulePath="$(RulePath)" ConfigPath="$(ConfigPath)" ReportLocation="$(ReportLocation)"/>
The code will also change accordingly;
private string _configPath; [Required] public string ConfigPath { get { return _configPath; } set { _configPath = value; } } private string _rulePath; [Required] public string RulePath { get { return _rulePath; } set { _rulePath = value; } } protected override string GenerateCommandLineCommands() { CommandLineBuilder builder = new CommandLineBuilder(); if (ScannedFiles != null) { builder.AppendSwitch("/file:" + ScannedFiles); } else { Log.LogWarning("CATNET Task requires TargetAssembly"); } if (ConfigPath!= null) { builder.AppendSwitch("/config:" + ConfigPath); } if (RulePath != null) { builder.AppendSwitch("/rules:" + RulePath); } if (ReportLocation != null) { builder.AppendSwitch("/report:" + ReportLocation); } return builder.ToString(); }
That’s it!