Skip to content

Commit

Permalink
Support disabling of protected services #74
Browse files Browse the repository at this point in the history
Add new ways to disable Defender on Windows:
  1. Disable through renaming required files
  2. Disable using registry changes
  3. Disable using TrustedInstaller user

Add support for running code as TrustedInstaller 🥳. It allows running
commands in OS-protected areas. It is written in PowerShell and it uses
PowerShell syntax like backticks that are inlined in special way. So the
commit extends inlining support and allows writing PowerShell using:
  - Comments
  - Here-strings
  - Backticks

Add disabling of more Defender service

Improve documentation and categorization of services.
  • Loading branch information
undergroundwires committed Oct 20, 2021
1 parent e6152fa commit ab8bce7
Show file tree
Hide file tree
Showing 5 changed files with 843 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,101 @@ import { IPipe } from '../IPipe';

export class InlinePowerShell implements IPipe {
public readonly name: string = 'inlinePowerShell';
public apply(raw: string): string {
return raw
?.split(/\r\n|\r|\n/)
public apply(code: string): string {
if (!code || !hasLines(code)) {
return code;
}
code = replaceComments(code);
code = mergeLinesWithBacktick(code);
code = mergeHereStrings(code);
const lines = getLines(code)
.map((line) => line.trim())
.filter((line) => line.length > 0)
.filter((line) => line.length > 0);
return lines
.join('; ');
}
}

function hasLines(text: string) {
return text.includes('\n') || text.includes('\r');
}

/*
Line comments using "#" are replaced with inline comment syntax <# comment.. #>
Otherwise single # comments out rest of the code
*/
function replaceComments(code: string) {
return code.replaceAll(/#(?<!<#)(?![<>])(.*)$/gm, (_$, match1 ) => {
const value = match1?.trim();
if (!value) {
return '<##>';
}
return `<# ${value} #>`;
});
}

function getLines(code: string) {
return (code.split(/\r\n|\r|\n/) || []);
}

/*
Merges inline here-strings to a single lined string with Windows line terminator (\r\n)
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_quoting_rules#here-strings
*/
function mergeHereStrings(code: string) {
const regex = /@(['"])\s*(?:\r\n|\r|\n)((.|\n|\r)+?)(\r\n|\r|\n)\1@/g;
return code.replaceAll(regex, (_$, quotes, scope) => {
const newString = getHereStringHandler(quotes);
const escaped = scope.replaceAll(quotes, newString.escapedQuotes);
const lines = getLines(escaped);
const inlined = lines.join(newString.separator);
const quoted = `${newString.quotesAround}${inlined}${newString.quotesAround}`;
return quoted;
});
}
interface IInlinedHereString {
readonly quotesAround: string;
readonly escapedQuotes: string;
readonly separator: string;
}
// We handle @' and @" differently so single quotes are interpreted literally and doubles are expandable
function getHereStringHandler(quotes: string): IInlinedHereString {
const expandableNewLine = '`r`n';
switch (quotes) {
case '\'':
return {
quotesAround: '\'',
escapedQuotes: '\'\'',
separator: `\'+"${expandableNewLine}"+\'`,
};
case '"':
return {
quotesAround: '"',
escapedQuotes: '`"',
separator: expandableNewLine,
};
default:
throw new Error(`expected quotes: ${quotes}`);
}
}

/*
Input ->
Get-Service * `
Sort-Object StartType `
Format-Table Name, ServiceType, Status -AutoSize
Output ->
Get-Service * | Sort-Object StartType | Format-Table -AutoSize
*/
function mergeLinesWithBacktick(code: string) {
/*
The regex actually wraps any whitespace character after backtick and before newline
However, this is not always the case for PowerShell.
I see two behaviors:
1. If inside string, it's accepted (inside " or ')
2. If part of a command, PowerShell throws "An empty pipe element is not allowed"
However we don't need to be so robust and handle this complexity (yet), so for easier regex
we wrap it anyway
*/
return code.replaceAll(/ +`\s*(?:\r\n|\r|\n)\s*/g, ' ');
}
2 changes: 1 addition & 1 deletion src/application/Parser/Script/Syntax/BatchFileSyntax.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ILanguageSyntax } from '@/domain/ScriptCode';


const BatchFileCommonCodeParts = [ '(', ')', 'else' ];
const BatchFileCommonCodeParts = [ '(', ')', 'else', '||' ];
const PowerShellCommonCodeParts = [ '{', '}' ];

export class BatchFileSyntax implements ILanguageSyntax {
Expand Down
Loading

0 comments on commit ab8bce7

Please sign in to comment.