{"id":15021196,"url":"https://github.com/purp1ew0lf/blue-team-notes","last_synced_at":"2025-10-06T22:59:48.349Z","repository":{"id":40199168,"uuid":"359216482","full_name":"Purp1eW0lf/Blue-Team-Notes","owner":"Purp1eW0lf","description":"You didn't think I'd go and leave the blue team out, right? ","archived":false,"fork":false,"pushed_at":"2025-10-03T12:23:52.000Z","size":1901,"stargazers_count":1695,"open_issues_count":0,"forks_count":247,"subscribers_count":57,"default_branch":"main","last_synced_at":"2025-10-03T14:33:48.165Z","etag":null,"topics":["blueteam","cybersecurity","dfir","infosec","powershell"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Purp1eW0lf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-04-18T17:58:06.000Z","updated_at":"2025-10-03T12:23:55.000Z","dependencies_parsed_at":"2024-01-14T06:54:04.273Z","dependency_job_id":"95992f4e-2c12-4b21-98c3-f16d494baa32","html_url":"https://github.com/Purp1eW0lf/Blue-Team-Notes","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Purp1eW0lf/Blue-Team-Notes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Purp1eW0lf%2FBlue-Team-Notes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Purp1eW0lf%2FBlue-Team-Notes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Purp1eW0lf%2FBlue-Team-Notes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Purp1eW0lf%2FBlue-Team-Notes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Purp1eW0lf","download_url":"https://codeload.github.com/Purp1eW0lf/Blue-Team-Notes/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Purp1eW0lf%2FBlue-Team-Notes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278692925,"owners_count":26029406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blueteam","cybersecurity","dfir","infosec","powershell"],"created_at":"2024-09-24T19:56:16.222Z","updated_at":"2025-10-06T22:59:48.328Z","avatar_url":"https://github.com/Purp1eW0lf.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"f\u003cp align=\"center\"\u003e\n  \u003cimg width=\"450\" height=\"450\" src=\"https://user-images.githubusercontent.com/44196051/120006585-f0dc3c00-bfd0-11eb-98d9-da3eb59edbda.png\"\u003e\n\u003c/p\u003e\n\n# Blue Team Notes\nA collection of one-liners, small scripts, and some useful tips for blue team work. \n\nI've included screenshots where possible so you know what you're getting. \n\n## Contact me\nIf you see a mistake, or have an easier way to run a command then you're welcome to hit me up on [Twitter](https://twitter.com/Purp1eW0lf) or commit an issue here. \n\nIf you want to contribute I'd be grateful for the command and a screenshot. I'll of course add you as a contributor\n\nIf you want to find me elsehwere, for reasons(?), searching 'Dray Agha' on the internets should find whatever it is you're looking for. \n\n## Did the Notes help?\n\nI hope the Blue Team Notes help you catch an adversary, thwart an attack, or even just helps you learn.\nIf you've benefited from the Blue Team Notes, would you kindly consider making a donation to one or two charities. \n\nDonate as much or little money as you like, of course. I have some UK charities you could donate to: [Great Ormond Street - Children's hospital](https://www.gosh.org/_donate/?amount=3\u0026frequency=single\u0026campaign=1284), [Cancer Research](https://donate.cancerresearchuk.org/support-us/your-donation?type=single\u0026amount=3), and [Feeding Britain - food charity](https://feedingbritain.org/donate/)\n\n## Table of Contents\n- [Shell Style](#shell-style)\n- [Windows](#Windows)\n  * [OS Queries](#os-queries)\n  * [Account Queries](#account-queries)\n  * [Service Queries](#service-queries)\n  * [Network Queries](#network-queries)\n  * [Remoting Queries](#remoting-queries)\n  * [Firewall Queries](#firewall-queries)\n  * [SMB Queries](#smb-queries)\n  * [Process Queries](#process-queries)\n  * [Recurring Task Queries](#recurring-task-queries)\n  * [File Queries](#file-queries)\n  * [Registry Queries](#registry-queries)\n  * [Driver Queries](#driver-queries)\n  * [DLL Queries](#dll-queries)\n  * [AV Queries](#AV-Queries)\n  * [Log Queries](#log-queries)\n  * [Powershell Tips](#powershell-tips)\n- [Linux](#linux)\n  * [Bash History](#bash-history)\n  * [Grep and Ack](#grep-and-ack)\n  * [Processes and Networks](#processes-and-networks)\n  * [Files](#files)\n  * [Bash Tips](#bash-tips)\n- [macOS](#macOS)\n  * [Reading .plist files](#Reading-.plist-files)\n  * [Quarantine Events](#Quarantine-Events)\n  * [Install History](Install-History)\n  * [Most Recently Used (MRU)](#Most-Recently-Used-(MRU))\n  * [Audit Logs](#Audit-Logs)\n  * [Command line history](#Command-line-history)\n  * [WHOMST is in the Admin group](#WHOMST-is-in-the-Admin-group) \n  * [Persistence locations](#Persistence-locations) \n  * [Transparency, Consent, and Control (TCC)](#Transparency,-Consent,-and-Control-(TCC))\n  * [Built-In Security Mechanisms](#Built-In-Security-Mechanisms)\n- [Malware](#Malware)\n  * [Rapid Malware Analysis](#rapid-malware-Analysis)\n  * [Unquarantine Malware](#Unquarantine-Malware)\n  * [Process Monitor](#process-monitor)\n  * [Hash Check Malware](#hash-check-malware)\n  * [Decoding Powershell](#decoding-powershell)\n- [SOC](#SOC)\n  * [Sigma Converter](#sigma-converter)\n  * [SOC Prime](#soc-prime)\n- [Honeypots](#honeypots)\n  * [Basic Honeypots](#basic-honeypots) \n- [Network Traffic](#network-traffic)\n  * [Capture Traffic](#capture-traffic)\n  * [TShark](#tshark)\n  * [Extracting Stuff](#extracting-stuff)\n  * [PCAP Analysis IRL](#pcap-analysis-irl)\n- [Digital Forensics](#Digital-Forensics) \n  * [Volatility](#volatility)\n  * [Quick Forensics](#quick-forensics)\n  * [Chainsaw](#chainsaw)\n  * [Browser History](#browser-history)\n  * [Which logs to pull in an incident](#Which-logs-to-pull-in-an-incident)\n  * [USBs](#USBs)\n  * [Reg Ripper](#reg-ripper)\n  * [Winget](#winget)\n\n---\n\nAs you scroll along, it's easy to lose orientation. Wherever you are in the Blue Team Notes, if you look to the top-left of the readme you'll see a little icon. This is a small table of contents, and it will help you figure out where you are, where you've been, and where you're going\n\n![image](https://user-images.githubusercontent.com/44196051/122612244-b834fd00-d07a-11eb-9281-e4d93f4f6059.png)\n\nAs you go through sections, you may notice the arrowhead that says 'section contents'. I have nestled the sub-headings in these, to make life a bit easier.\n\n![image](https://user-images.githubusercontent.com/44196051/124335025-d4fc2500-db90-11eb-86cc-80fc8db2c193.png)\n\n---\n\n# Shell Style\n\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n\n  + [Give shell timestamp](#give-shell-timestamp)\n    - [CMD](#cmd)\n    - [Pwsh](#pwsh)\n    - [Bash](#bash)\n\n\u003c/details\u003e\n\n### Give shell timestamp\nFor screenshots during IR, I like to have the date, time, and sometimes the timezone in my shell\n#### CMD\n```bat\nsetx prompt $D$S$T$H$H$H$S$B$S$P$_--$g\n:: all the H's are to backspace the stupid microsecond timestamp\n:: $_ and --$g seperate the date/time and path from the actual shell\n:: We make the use of the prompt command: https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/prompt\n:: setx is in fact the command line command to write variables to the registery\n:: We are writing the prompt's new timestamp value in the cmd line into the reg so it stays, otherwise it would not stay in the cmdline when we closed it.\n```\n![image](https://user-images.githubusercontent.com/44196051/119978466-97b0e000-bfb1-11eb-83e1-022efba7dc96.png)\n\n#### Pwsh\n```powershell\n###create a powershell profile, if it doesnt exist already\nNew-Item $Profile -ItemType file –Force\n##open it in notepad to edit\nfunction prompt{ \"[$(Get-Date)]\" +\" | PS \"+ \"$(Get-Location) \u003e \"}\n##risky move, need to tighten this up. Change your execution policy or it won't\n#run the profile ps1\n#run as powershell admin\nSet-ExecutionPolicy RemoteSigned\n```\n![image](https://user-images.githubusercontent.com/44196051/119978226-486aaf80-bfb1-11eb-8e9e-52eabf2cde4c.png)\n\n#### Bash\n```bash\n##open .bashrc\nsudo nano .bashrc\n#https://www.howtogeek.com/307701/how-to-customize-and-colorize-your-bash-prompt/\n##date, time, colour, and parent+child directory only, and -\u003e promptt\nPS1='\\[\\033[00;35m\\][`date  +\"%d-%b-%y %T %Z\"]` ${PWD#\"${PWD%/*/*}/\"}\\n\\[\\033[01;36m\\]-\u003e \\[\\033[00;37m\\]'\n      ##begin purple  #year,month,day,time,timezone #show last 2 dir #next line, cyan,-\u003eprompt #back to normal white text\n#restart the bash source\nsource ~/.bashrc\n```\n![image](https://user-images.githubusercontent.com/44196051/119981537-a7cabe80-bfb5-11eb-8b7e-1e5ba7f5ba99.png)\n---\n# Windows\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n  \n  + [OS Queries](#os-queries)\n  + [Account Queries](#account-queries)\n  + [Service Queries](#service-queries)\n  + [Network Queries](#network-queries)\n  + [Remoting Queries](#remoting-queries)\n  + [Firewall Queries](#firewall-queries)\n  + [SMB Queries](#smb-queries)\n  + [Process Queries](#process-queries)\n  + [Recurring Task Queries](#recurring-task-queries)\n  + [File Queries](#file-queries)\n  + [Registry Queries](#registry-queries)\n  + [Driver Queries](#driver-queries)\n  + [DLL Queries](#dll-queries)\n  + [Log Queries](#log-queries)\n  + [Powershell Tips](#powershell-tips)\n\n\n\u003c/details\u003e\n \nI've generally used these Powershell queries with [Velociraptor](https://www.velocidex.com), which can query thousands of endpoints at once.\n\n## OS Queries\n\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n\n  + [Get Fully Qualified Domain Name](#get-fully-qualified-domain-name)\n  + [Get OS and Pwsh info](#get-os-and-pwsh-info)\n    - [Hardware Info](#hardware-info)\n  + [Time info](#time-info)\n    - [Human Readable](#human-readable)\n    - [Machine comparable](#machine-comparable)\n    - [Compare UTC time from Local time](#compare-utc-time-from-local-time)\n  + [Update Info](#update-info)\n    - [Get Patches](#get-patches)\n    - [Manually check if patch has taken](#manually-check-if-patch-has-taken)\n      * [Microsoft Support Page](#microsoft-support-page)\n      * [On Host](#on-host)\n      * [Discrepencies](#discrepencies)\n\n\u003c/details\u003e\n\n## Get Fully Qualified Domain Name\n```powershell\n([System.Net.Dns]::GetHostByName(($env:computerName))).Hostname\n\n# Get just domain name\n(Get-WmiObject -Class win32_computersystem).domain\n```\n![image](https://user-images.githubusercontent.com/44196051/123553586-ef3e9900-d773-11eb-9207-af279dc2b3e3.png)\n  \n### Get OS and Pwsh info\nThis will print out the hostname, the OS build info, and the powershell version\n```powershell\n$Bit = (get-wmiobject Win32_OperatingSystem).OSArchitecture ; \n$V = $host | select-object -property \"Version\" ; \n$Build = (Get-WmiObject -class Win32_OperatingSystem).Caption ; \nwrite-host \"$env:computername is a $Bit $Build with Pwsh $V\n```\n![image](https://user-images.githubusercontent.com/44196051/120313634-2be0b700-c2d2-11eb-919f-5792169a1dba.png)\n\n#### Hardware Info\n\nIf you want, you can get Hardware, BIOS, and Disk Space info of a machine\n\n```powershell\n#Get BIOS Info\ngcim -ClassName Win32_BIOS | fl Manufacturer, Name, SerialNumber, Version;\n#Get processor info\ngcim -ClassName Win32_Processor | fl caption, Name, SocketDesignation;\n#Computer Model\ngcim -ClassName Win32_ComputerSystem | fl Manufacturer, Systemfamily, Model, SystemType\n#Disk space in Gigs, as who wants bytes?\ngcim  -ClassName Win32_LogicalDisk |\nSelect -Property DeviceID, DriveType, @{L='FreeSpaceGB';E={\"{0:N2}\" -f ($_.FreeSpace /1GB)}}, @{L=\"Capacity\";E={\"{0:N2}\" -f ($_.Size/1GB)}} | fl\n\n## Let's calculate an individual directory, C:\\Sysmon, and compare with disk memory stats\n$size = (gci c:\\sysmon | measure Length -s).sum / 1Gb;\nwrite-host \" Sysmon Directory in Gigs: $size\";\n$free = gcim  -ClassName Win32_LogicalDisk | select @{L='FreeSpaceGB';E={\"{0:N2}\" -f ($_.FreeSpace /1GB)}};\necho \"$free\";\n$cap = gcim  -ClassName Win32_LogicalDisk | select @{L=\"Capacity\";E={\"{0:N2}\" -f ($_.Size/1GB)}} \necho \"$cap\"\n```\n![image](https://user-images.githubusercontent.com/44196051/120922608-0c76cf00-c6c2-11eb-810b-288db6256bba.png)\n\n### Time info\n#### Human Readable\nGet a time that's human readable\n```powershell\nGet-Date -UFormat \"%a %Y-%b-%d %T UTC:%Z\" \n```\n![image](https://user-images.githubusercontent.com/44196051/120298372-f03df100-c2c1-11eb-92ab-d642c26133ab.png)\n\n#### Machine comparable\nThis one is great for doing comparisons between two strings of time\n```powershell\n[Xml.XmlConvert]::ToString((Get-Date).ToUniversalTime(), [System.Xml.XmlDateTimeSerializationMode]::Utc) \n```\n![image](https://user-images.githubusercontent.com/44196051/120314399-1e77fc80-c2d3-11eb-9a75-f9e677153d86.png)\n\n#### Compare UTC time from Local time\n```powershell\n$Local = get-date;$UTC = (get-date).ToUniversalTime();\nwrite-host \"LocalTime is: $Local\";write-host \"UTC is: $UTC\"\n```\n![image](https://user-images.githubusercontent.com/44196051/120301782-1fa22d00-c2c5-11eb-908f-763897fac25f.png)\n\n### Update Info\n\n#### Get Patches\nWill show all patch IDs and their installation date\n```powershell\nget-hotfix|\nselect-object HotFixID,InstalledOn|\nSort-Object  -Descending -property InstalledOn|\nformat-table -autosize\n```\n![image](https://user-images.githubusercontent.com/44196051/120307390-d5bc4580-c2ca-11eb-8ffe-d1a835b1ce40.png)\n\nFind why an update failed\n```powershell\n$Failures = gwmi -Class Win32_ReliabilityRecords;\n$Failures | ? message -match 'failure'  | Select -ExpandProperty message \n```\n\n\n#### Manually check if patch has taken\nThis happened to me during the March 2021 situation with Microsoft Exchange's ProxyLogon. The sysadmin swore blind they had patched the server, but neither `systeminfo` of `get-hotfix` was returning with the correct KB patch.\n\nThe manual workaround isn't too much ballache\n\n##### Microsoft Support Page\nFirst identify the ID number of the patch you want. And then find the dedicated Microsoft support page for it. \n\nFor demonstration purposes, let's take `KB5001078` and it's [corresponding support page](https://support.microsoft.com/en-us/topic/kb5001078-servicing-stack-update-for-windows-10-version-1607-february-12-2021-3e19bfd1-7711-48a8-978b-ce3620ec6362). You'll be fine just googling the patch ID number.\n\n![image](https://user-images.githubusercontent.com/44196051/120308871-7a8b5280-c2cc-11eb-850f-da46727a94ac.png)\n\nThen click into the dropdown relevant to your machine. \n![image](https://user-images.githubusercontent.com/44196051/120309734-7f043b00-c2cd-11eb-9cf6-3a7ca6be6691.png)\n\nHere you can see the files that are included in a particular update. The task now is to pick a handful of the patch-files and compare your host machine. See if these files exist too, and if they do do they have similar / same dates on the host as they do in the Microsoft patch list?\n\n##### On Host\nLet us now assume you don't know the path to this file on your host machine. You will have to recursively search for the file location. It's a fair bet that the file will be in `C:\\Windows\\` (but not always), so lets' recursively look for `EventsInstaller.dll`\n\n```powershell\n$file = 'EventsInstaller.dll'; $directory = 'C:\\windows' ;\ngci -Path $directory -Filter $file -Recurse -force|\nsort-object  -descending -property LastWriteTimeUtc | fl *\n```\nWe'll get a lot of information here, but we're really concerned with is the section around the various *times*. As we sort by the `LastWriteTimeUtc`, the top result should in theory be the latest file of that name...but this is not always true.\n\n![image](https://user-images.githubusercontent.com/44196051/120312109-37cb7980-c2d0-11eb-95e2-8655cd89f9cc.png)\n\n##### Discrepencies\nI've noticed that sometimes there is a couple days discrepency between dates. \n\n![image](https://user-images.githubusercontent.com/44196051/120313127-7d3c7680-c2d1-11eb-8941-e96575a63138.png)\n\nFor example in our screenshot, on the left Microsoft's support page supposes the `EventsInstaller.dll` was written on the 13th January 2021. And yet our host on the right side of the screenshot comes up as the 14th January 2021. This is fine though, you've got that file don't sweat it. \n\n---\n\n## Account Queries\n\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n\n  + [Users recently created in Active Directory](#users-recently-created-in-active-directory)\n  + [Hone in on suspicious user](#hone-in-on-suspicious-user)\n  + [Retrieve local user accounts that are enabled](#retrieve-local-user-accounts-that-are-enabled)\n  + [Find all users currently logged in](#find-all-users-currently-logged-in)\n    - [Find all users logged in across entire AD](#Find-all-users-logged-in-across-entire-AD)\n  + [Evict User](#Evict-User)\n    - [Force user logout](#Force-user-logout)\n    - [Force user new password](#force-user-new-password)\n    - [Disable AD Account](#Disable-ad-account) \n    - [Evict from Group](#evict-from-group) \n  + [Computer / Machine Accounts](#computer---machine-accounts)\n    - [Show machine accounts that are apart of interesting groups.](#show-machine-accounts-that-are-apart-of-interesting-groups)\n    - [Reset password for a machine account.](#reset-password-for-a-machine-account)\n  + [Query Group Policy](#query-group-policy)\n  + [All Users PowerShell History](#All-Users-PowerShell-History)\n\n\u003c/details\u003e\n\n### Users recently created in Active Directory\n*Run on a Domain Controller*.\n\nChange the AddDays field to more or less days if you want. Right now set to seven days.\n\nThe 'when Created' field is great for noticing some inconsistencies. For example, how often are users created at 2am?\n```powershell\nimport-module ActiveDirectory;\n$When = ((Get-Date).AddDays(-7)).Date; \nGet-ADUser -Filter {whenCreated -ge $When} -Properties whenCreated |\nsort whenCreated -descending \n```\n\n![image](https://user-images.githubusercontent.com/44196051/120461945-614cd980-c392-11eb-8352-2141ee42efdf.png)\n\n### Hone in on suspicious user\nYou can use the `SamAccountName` above to filter\n```powershell\nimport-module ActiveDirectory;\nGet-ADUser -Identity HamBurglar -Properties *\n```\n![image](https://user-images.githubusercontent.com/44196051/120328655-f1334a80-c2e2-11eb-97da-653553b7c01a.png)\n\n### Retrieve local user accounts that are enabled\n```powershell\n Get-LocalUser | ? Enabled -eq \"True\"\n```\n![image](https://user-images.githubusercontent.com/44196051/120561793-216f0c00-c3fd-11eb-9738-76e778c79763.png)\n\n### Find all users currently logged in\n```powershell\nqwinsta\n#or\nquser\n```\n#### Find all users logged in across entire AD\nIf you want to find every single user logged in on your Active Directory, with the machine they are also signed in to. \n\nI can reccomend YossiSassi's [Get-UserSession.ps1](https://github.com/YossiSassi/Get-UserSession/blob/master/Get-UserSession.ps1) and [Get-RemotePSSession.ps1](https://github.com/YossiSassi/Get-RemotePSSession/blob/master/Get-RemotePSSession.ps1).\n\nThis will generate a LOT of data in a real-world AD though.\n\n\u003cimg width=\"595\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/154706183-ea6be4ad-a811-42ae-bb53-c1ddbc30524b.png\"\u003e\n\n### Evict User\n\n#### Force user logout\nYou may need to evict a user from a session - perhaps you can see an adversary has been able to steal a user's creds and is leveraging their account to traverse your environment\n\n```powershell\n#show the users' session\nqwinsta\n\n#target their session id\nlogoff 2 /v\n```\n![2021-11-15_15-03](https://user-images.githubusercontent.com/44196051/141804502-65d627b3-137b-483e-a220-701d2e5057df.png)\n\n#### Force user new password\nFrom the above instance, we may want to force a user to have a new password - one the adversary does not have \n\n##### for Active Directory\n```powershell\n$user = \"lizzie\" ; $newPass = \"HoDHSyxkzP-cuzjm6S6VF-7rvqKyR\";\n\n#Change password twice. \n#First can be junk password, second time can be real new password\nSet-ADAccountPassword -Identity $user -Reset -NewPassword (ConvertTo-SecureString -AsPlainText \"6;wB3yj9cI8X\" -Force) -verbose\nSet-ADAccountPassword -Identity $user -Reset -NewPassword (ConvertTo-SecureString -AsPlainText \"$newPass\" -Force) -verbose\n```\n\n![image](https://user-images.githubusercontent.com/44196051/141806623-ee167dfa-5b36-4535-b829-545d21181e95.png)\n\n##### For local non-domain joined machines\n```powershell\n#for local users\nnet user #username #newpass\nnet user frank \"lFjcVR7fW2-HoDHSyxkzP\"\n```\n![image](https://user-images.githubusercontent.com/44196051/141804977-166ac050-ba1d-433d-ab6b-76a1e60627bb.png)\n\n#### Disable AD Account\n\n```powershell\n#needs the SAMAccountName\n$user = \"lizzie\"; \nDisable-ADAccount -Identity \"$user\" #-whatif can be appended\n\n#check its disabled\n(Get-ADUser -Identity $user).enabled\n\n#renable when you're ready\nEnable-ADAccount -Identity \"$user\" -verbose\n```\n![image](https://user-images.githubusercontent.com/44196051/141814376-94716c11-6e8e-4d5b-ad31-51a656095f66.png)\n\n![image](https://user-images.githubusercontent.com/44196051/141814532-da45aa38-623e-4a9e-ab2a-27473350398d.png)\n\n#### Disable local Account\n\n```powershell\n# list accounts with  Get-LocalUser\nDisable-LocalUser -name \"bad_account$\"\n```\n\n\u003cimg width=\"756\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/187993103-1ad5d55a-ab9f-4479-9a46-171f5ed8f30e.png\"\u003e\n\n\n#### Evict from Group\nGood if you need to quickly eject an account from a specific group, like administrators or remote management.\n\n```powershell\n$user = \"erochester\"\nremove-adgroupmember -identity Administrators -members $User -verbose -confirm:$false\n```\n\n![image](https://user-images.githubusercontent.com/44196051/150777790-38409fa8-82f0-4060-aeeb-f95b45de836f.png)\n\n\n### Computer / Machine Accounts\nAdversaries like to use Machine accounts (accounts that have a $) as these often are overpowered AND fly under the defenders' radar\n\n#### Show machine accounts that are apart of interesting groups. \nThere may be misconfigurations that an adversary could take advantadge. \n```powershell\nGet-ADComputer -Filter * -Properties MemberOf | ? {$_.MemberOf}\n```\n![image](https://user-images.githubusercontent.com/44196051/120346984-cac9db00-c2f3-11eb-8ab0-1112aa2183a9.png)\n\n#### Reset password for a machine account. \nGood for depriving adversary of pass they may have got. \nAlso good for re-establishing trust if machine is kicked out of domain trust for reasons(?)\n\n```powershell\nReset-ComputerMachinePassword\n```\n### All Users PowerShell History\n\nDuring an IR, you will want to access other users PowerShell history. However, the get-history command only will retrieve the current shell's history, which isn't very useful.\n\nInstead, [PowerShell in Windows 10 saves the last 4096 commands in a particular file](https://social.technet.microsoft.com/Forums/en-US/7c3cd614-f793-4b99-b826-3dff917ebe88/powershell-commands-history-windows-10-1809-psreadline?forum=win10itprogeneral#:~:text=By%20default%2C%20the%20PowerShell%20in,separately%20for%20PowerShell%20and%20ISE.). On an endpoint, we can run a quick loop that will print the full path of the history file - showing which users history it is showing - and then show the contents of that users' PwSh commands\n\n```powershell\n$Users = (Gci C:\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\PowerShell\\PSReadline\\ConsoleHost_history.txt).FullName\n$Pasts = @($Users);\n\nforeach ($Past in $Pasts) {\n  write-host \"`n----User Pwsh History Path $Past---`n\" -ForegroundColor Magenta; \n  get-content $Past\n}\n\n```\n\n![image](https://user-images.githubusercontent.com/44196051/137767902-e969f32d-5b2d-47ae-a918-abb803117f34.png)\n\nAnd check this one too\n\n```powershell\nc:\\windows\\system32\\config\\systemprofile\\appdata\\roaming\\microsoft\\windows\\powershell\\psreadline\\consolehost_history.txt\n```\n\n---\n\n## Service Queries\n\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n\n  + [Show Services](#Show-Services)\n  + [Hone in on specific Service](#hone-in-on-specific-service)\n  + [Kill a service](#kill-a-service)\n  + [Hunting potential sneaky services](#Hunting-potential-sneaky-services)\n  \n\u003c/details\u003e\n\n### Show Services \n\nLet's get all the services and sort by what's running\n```powershell\nget-service|Select Name,DisplayName,Status|\nsort status -descending | ft -Property * -AutoSize|\nOut-String -Width 4096\n```\n![image](https://user-images.githubusercontent.com/44196051/120901027-354e8400-c630-11eb-8ac8-869864349cf5.png)\n\nNow show the underlying executable supporting that service\n\n```powershell\nGet-WmiObject win32_service |? State -match \"running\" |\nselect Name, DisplayName, PathName, User | sort Name |\nft -wrap -autosize\n```\n\n![image](https://user-images.githubusercontent.com/44196051/150961296-3778e68c-c85d-4310-aa37-865fd3688889.png)\n\n\n### Hone in on specific Service\nIf a specific service catches your eye, you can get all the info for it.  Because the single and double qoutes are important to getting this right, I find it easier to just put the DisplayName of the service I want as a variable, as I tend to fuck up the displayname filter bit\n\n```powershell\n$Name = \"eventlog\"; \ngwmi -Class Win32_Service -Filter \"Name = '$Name' \" | fl *\n\n#or this, but you get less information compared to the one about tbh\nget-service -name \"eventlog\" | fl *   \n```\n![image](https://user-images.githubusercontent.com/44196051/120341774-14fc8d80-c2ef-11eb-8b1d-31db7620b7cb.png)\n\n\n### Kill a service\n```powershell\nGet-Service -DisplayName \"meme_service\" | Stop-Service -Force -Confirm:$false -verbose\n```\n### Hunting potential sneaky services\nI saw a red team tweet regarding [sneaky service install](https://twitter.com/Alh4zr3d/status/1580925761996828672?s=20\u0026t=3IV0LmMvw-ThCCj_kgpjwg). To identify this, you can deploy the following:\n\n```powershell\nGet-ItemProperty -Path \"HKLM:\\System\\CurrentControlSet\\services\\*\" | \nft PSChildName, ImagePath -autosize | out-string -width 800\n\n# Grep out results from System32 to reduce noise, though keep in mind adversaries can just put stuff in there too\nGet-ItemProperty -Path \"HKLM:\\System\\CurrentControlSet\\services\\*\" | \nwhere ImagePath -notlike \"*System32*\" | \nft PSChildName, ImagePath -autosize | out-string -width 800\n\n```\n\u003cimg width=\"1372\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/202874716-ed5d7859-72a0-48c6-8e29-4d8a8168b2ae.png\"\u003e\n\n\n---\n\n## Network Queries\n\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n\n  + [Show TCP connections and underlying process](#Show-TCP-connections-and-underlying-process)\n  + [Find internet established connections, and sort by time established](#find-internet-established-connections--and-sort-by-time-established)\n  + [Sort remote IP connections, and then unique them](#sort-remote-ip-connections--and-then-unique-them)\n    - [Hone in on a suspicious IP](#hone-in-on-a-suspicious-ip)\n  + [Show UDP connections](#show-udp-connections)\n  + [Kill a connection](#kill-a-connection)\n  + [Check Hosts file](#check-Hosts-file)\n    - [Check Host file Time](#Check-Host-file-time)\n  + [DNS Cache](#dns-cache)\n    - [Investigate DNS](#investigate-dns)\n  + [IPv6](#ipv6)\n    - [Disable Priority Treatment of IPv6](#Disable-Priority-Treatment-of-IPv6)\n   + [BITS Queries](#bits-queries)  \n\n\u003c/details\u003e\n\n### Show TCP connections and underlying process\n\nThis one is so important, I have it [listed twice](#Processes-and-TCP-Connections) in the blue team notes\n\nI have a neat one-liner for you. This will show you the local IP and port, the remote IP andport, the process name, and the underlying executable of the process!\n\nYou could just use `netstat -b`, which gives you SOME of this data\n\nBut instead, try this bad boy on for size:\n\n```powershell\nGet-NetTCPConnection |\nselect LocalAddress,localport,remoteaddress,remoteport,state,@{name=\"process\";Expression={(get-process -id $_.OwningProcess).ProcessName}}, @{Name=\"cmdline\";Expression={(Get-WmiObject Win32_Process -filter \"ProcessId = $($_.OwningProcess)\").commandline}} | \nsort Remoteaddress -Descending | ft -wrap -autosize\n\n#### you can search/filter by the commandline process, but it will come out janky. \n##### in the final field we're searching by `anydesk`\nGet-NetTCPConnection |\nselect LocalAddress,localport,remoteaddress,remoteport,state,@{name=\"process\";Expression={(get-process -id $_.OwningProcess).ProcessName}}, @{Name=\"cmdline\";Expression={(Get-WmiObject Win32_Process -filter \"ProcessId = $($_.OwningProcess)\").commandline}} \n|  Select-String -Pattern 'anydesk'\n```\n\n![image](https://user-images.githubusercontent.com/44196051/150955379-872e2b5f-6d88-4b3f-929f-debaa8fd1036.png)\n\n######## **Bound to catch bad guys or your moneyback guaranteed!!!!**\n\n\n### Find internet established connections, and sort by time established\nYou can always sort by whatever value you want really. CreationTime is just an example\n```powershell\nGet-NetTCPConnection -AppliedSetting Internet |\nselect-object -property remoteaddress, remoteport, creationtime |\nSort-Object -Property creationtime |\nformat-table -autosize\n```\n![image](https://user-images.githubusercontent.com/44196051/120314725-73b40e00-c2d3-11eb-9dbf-3b0582a9b2d0.png)\n\n### Sort remote IP connections, and then unique them\nThis really makes strange IPs stand out\n```powershell\n(Get-NetTCPConnection).remoteaddress | Sort-Object -Unique \n```\n![image](https://user-images.githubusercontent.com/44196051/120314835-8dedec00-c2d3-11eb-8469-e658eb743364.png)\n\n#### Hone in on a suspicious IP\nIf you see suspicious IP address in any of the above, then I would hone in on it\n```powershell\nGet-NetTCPConnection |\n? {($_.RemoteAddress -eq \"1.2.3.4\")} |\nselect-object -property state, creationtime, localport,remoteport | ft -autosize\n\n## can do this as well \n Get-NetTCPConnection -remoteaddress 0.0.0.0 |\n select state, creationtime, localport,remoteport | ft -autosize\n ```\n ![image](https://user-images.githubusercontent.com/44196051/120313809-68141780-c2d2-11eb-85ac-5e369715f8ed.png)\n\n### Show UDP connections\nYou can generally filter pwsh UDP the way we did the above TCP\n```powershell\n Get-NetUDPEndpoint | select local*,creationtime, remote* | ft -autosize\n```\n![image](https://user-images.githubusercontent.com/44196051/120562989-7744b380-c3ff-11eb-963b-443cc9176643.png)\n\n\n### Kill a connection\nThere's probably a better way to do this. But essentially, get the tcp connection that has the specific remote IPv4/6 you want to kill. It will collect the OwningProcess. From here, get-process then filters for those owningprocess ID numbers. And then it will stop said process. Bit clunky\n``` powershell\nstop-process -verbose -force -Confirm:$false (Get-Process -Id (Get-NetTCPConnection -RemoteAddress \"1.2.3.4\" ).OwningProcess)\n```\n\n### Check Hosts file\nSome malware may attempt DNS hijacking, and alter your Hosts file\n```powershell\ngc -tail 4 \"C:\\Windows\\System32\\Drivers\\etc\\hosts\"\n\n#the above gets the most important bit of the hosts file. If you want more, try this:\ngc \"C:\\Windows\\System32\\Drivers\\etc\\hosts\"\n```\n#### Check Host file Time\nDon't trust timestamps....however, may be interesting to see if altered recently\n```powershell\ngci \"C:\\Windows\\System32\\Drivers\\etc\\hosts\" | fl *Time* \n\n```\n![image](https://user-images.githubusercontent.com/44196051/120916488-d4f82a80-c6a1-11eb-8551-ac495ce2de68.png)\n\n### DNS Cache\n\nCollect the DNS cache on an endpoint. Good for catching any sneaky communication or sometimes even DNS C2\n\n```powershell\nGet-DnsClientCache | out-string -width 1000\n```\n\n![image](https://user-images.githubusercontent.com/44196051/121901947-c99aa400-cd1e-11eb-8454-093c54dd2086.png)\n\n#### Investigate DNS\n\nThe above command will likely return a lot of results you don't really need about the communication between 'trusted' endpoints and servers. We can filter these 'trusted' hostnames out with regex, until we're left with less common results. \n\nOn the second line of the below code, change up and insert the regex that will filter out your machines. For example, if your machines are generally called WrkSt1001.corp.local, or ServStFAX.corp.local, you can regex out that first poriton so it will exclude any and all machines that share this - so `workst|servst` would do the job. You don't need to wildcard here.\n\nBe careful though. If you are too generic and liberal, you may end up filtering out malicious and important results. It's bettter to be a bit specific, and drill down further to amake sure you aren't filtering out important info. So for example, I wouldn't suggest filtering out short combos of letters or numbers `ae|ou|34|`\n\n```powershell\nGet-DnsClientCache | \n? Entry -NotMatch \"workst|servst|memes|kerb|ws|ocsp\" |\nout-string -width 1000  \n```\n\nIf there's an IP you're sus of, you can always take it to [WHOIS](https://who.is/) or [VirusTotal](https://www.virustotal.com/gui/home/search), as well see for other instances it appears in your network and what's up to whilst it's interacting there.\n\n### IPv6\n\nSince Windows Vitsa, the Windows OS prioritises IPv6 over IPv4. This lends itself to man-in-the-middle attacks, you can find some more info on exploitation [here](https://www.youtube.com/watch?v=zzbIuslB58c)\n\nGet IPv6 addresses and networks\n\n```powershell\nGet-NetIPAddress -AddressFamily IPv6  | ft Interfacealias, IPv6Address\n```\n![image](https://user-images.githubusercontent.com/44196051/121316010-c8bdd880-c900-11eb-92d5-740b38a98a35.png)\n\n#### Disable Priority Treatment of IPv6\n\nYou probably don't want to switch IPv6 straight off. And if you DO want to, then it's probably better at a DHCP level. But what we can do is change how the OS will prioritise the IPv6 over IPv4.\n\n```powershell\n#check if machine prioritises IPv6\nping $env:COMPUTERNAME -n 4 # if this returns an IPv6, the machine prioritises this over IPv4\n\n#Reg changes to de-prioritise IPv6\nNew-ItemProperty “HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters\\” -Name “DisabledComponents” -Value 0x20 -PropertyType “DWord”\n\n#If this reg already exists and has values, change the value\nSet-ItemProperty “HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters\\” -Name “DisabledComponents” -Value 0x20\n\n#you need to restart the computer for this to take affect\n#Restart-Computer\n```\n![image](https://user-images.githubusercontent.com/44196051/121317107-e2135480-c901-11eb-9832-5930a94f80ac.png\n)\n\n### BITS Queries\n\n```powershell\nGet-BitsTransfer| \nfl DisplayName,JobState,TransferType,FileList, OwnerAccount,BytesTransferred,CreationTime,TransferCompletionTime\n \n## filter out common bits jobs in your enviro, ones below are just an example, you will need to add your own context\nGet-BitsTransfer|\n| ? displayname -notmatch \"WU|Office|Dell_Asimov|configjson\" |\nfl DisplayName,JobState,TransferType,FileList, OwnerAccount,BytesTransferred,CreationTime,TransferCompletionTime\n\n## Hunt down BITS transfers that are UPLOADING, which may be sign of data exfil\nGet-BitsTransfer| \n? TransferType -match \"Upload\" | \nfl DisplayName,JobState,TransferType,FileList, OwnerAccount,BytesTransferred,CreationTime,TransferCompletionTime\n```\n\n![image](https://user-images.githubusercontent.com/44196051/141825517-a2f7a6a8-a8c4-4230-b545-fc0d93baad5f.png)\n\n\n## Remoting Queries\n\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n\n  + [Powershell Remoting](#powershell-remoting)\n    - [Remoting Permissions](#remoting-permissions)\n    - [Query WinRM Sessions Deeper](#Query-WinRM-sessions-Deeper)\n    - [Check Constrained Language](#check-constrained-language)\n  + [RDP Settings](#rdp-settings)\n  + [Query RDP Logs](#query-rdp-logs)\n  + [Current RDP Sessions](#current-rdp-sessions) \n  + [Check Certificates](#check-certificates)\n    - [Certificate Dates](#certificate-dates)\n  \n\u003c/details\u003e\n\n### Powershell Remoting\n\nGet Powershell sessions created\n\n```powershell\nGet-PSSession\n```\n\n#### Query WinRM Sessions Deeper\n\nYou can query the above even deeper.\n\n```powershell\nget-wsmaninstance -resourceuri shell -enumerate | \nselect Name, State, Owner, ClientIP, ProcessID, MemoryUsed, \n@{Name = \"ShellRunTime\"; Expression = {[System.Xml.XmlConvert]::ToTimeSpan($_.ShellRunTime)}},\n@{Name = \"ShellInactivity\"; Expression = {[System.Xml.XmlConvert]::ToTimeSpan($_.ShellInactivity)}}\n```\n\n![image](https://user-images.githubusercontent.com/44196051/137759118-6ce2c557-bdea-4569-abe5-4942e82b5daf.png)\n\nThe ClientIP field will show the original IP address that WinRM'd to the remote machine. \nThe times under the Shell fields at the bottom have been converted into HH:MM:SS, so in the above example, the remote PowerShell session has been running for 0 hours, 4 minutes, and 26 seconds.\n\n\n#### Remoting Permissions\n```powershell\nGet-PSSessionConfiguration | \nfl Name, PSVersion, Permission\n```\n\n![image](https://user-images.githubusercontent.com/44196051/137760340-8150b480-6500-4822-9ec2-24168ab9e819.png)\n\n### Check Constrained Language\n\nTo be honest, constrained language mode in Powershell can be trivally easy to mitigate for an adversary. And it's difficult to implement persistently. But anyway. You can use this quick variable to confirm if a machine has a constrained language mode for pwsh.\n\n```powershell\n$ExecutionContext.SessionState.LanguageMode\n```\n\n![image](https://user-images.githubusercontent.com/44196051/121309801-8b564c80-c8fa-11eb-9955-15bf209844e3.png)\n\n### RDP settings\n\nYou can check if RDP capability is permissioned on an endpoint\n```powershell\nif ((Get-ItemProperty \"hklm:\\System\\CurrentControlSet\\Control\\Terminal Server\").fDenyTSConnections -eq 0){write-host \"RDP Enabled\" } else { echo \"RDP Disabled\" }\n```\n\nIf you want to block RDP\n```powershell\nSet-ItemProperty -Path 'HKLM:\\System\\CurrentControlSet\\Control\\Terminal Server' -name \"fDenyTSConnections\" -value 1\n#Firewall it out too\nDisable-NetFirewallRule -DisplayGroup \"Remote Desktop\"\n```\n### Query RDP Logs \nKnowing who is RDPing in your enviroment, and from where, is important. Unfortunately, RDP logs are balllache. [Threat hunting blogs like this one](https://research.nccgroup.com/2021/10/21/detecting-and-protecting-when-remote-desktop-protocol-rdp-is-open-to-the-internet/) can help you narrow down what you are looking for when it comes to RDP \n\nLet's call on one of the RDP logs, and filter for event ID 1149, which means a RDP connection has been made. Then let's filter out any IPv4 addresses that begin with 10.200, as this is the internal IP schema. Perhaps I want to hunt down public IP addresses, as this would suggest the RDP is exposed to the internet on the machine and an adversary has connected with correct credentials!!!\n\n[Two logs of interest](https://www.security-hive.com/post/rdp-forensics-logging-detection-and-forensics)\n* Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational\n* Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx\n\n```powershell\n# if you acquire a log, change this to get-winevent -path ./RDP_log_you_acquired.evtx\nget-winevent -path \"./Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational.evtx\" | \n? id -match 1149 | \nsort Time* -descending | \nfl time*, message\n\nget-winevent -path ./ \"Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx\" | \n? id -match 21 | \nsort Time* -descending | \nfl time*, message\n```\n\n![image](https://user-images.githubusercontent.com/44196051/138730646-0740a2f5-de35-4e2d-8c9a-79323d84f325.png)\n\n\n### Current RDP Sessions\nYou can query the RDP sessions that a [system is currently running](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/qwinsta)\n\n```cmd\nqwinsta\n\n:: get some stats\nqwinsta /counter\n```\n\n![image](https://user-images.githubusercontent.com/44196051/141457332-edf06c5d-9dfa-4ae8-b3c5-ed0a9db4db05.png)\n\nYou can read here about [how to evict](#Evict-Users) a malicious user from a session and change the creds rapidly to deny them future access\n\n### Check Certificates\n\n```powershell\ngci \"cert:\\\" -recurse | fl FriendlyName, Subject, Not* \n```\n\n![image](https://user-images.githubusercontent.com/44196051/121305446-7d51fd00-c8f5-11eb-918b-da6b7f09d2eb.png)\n\n#### Certificate Dates\n\nYou will be dissapointed how many certificates are expired but still in use. Use the `-ExpiringInDays` flag\n\n```powershell\n gci \"cert:\\*\" -recurse -ExpiringInDays 0 | fl FriendlyName, Subject, Not*  \n \n```\n\n## Firewall Queries\n\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n\n  + [Retreieve Firewall profile names](#retreieve-firewall-profile-names)\n    - [Retrieve rules of specific profile](#retrieve-rules-of-specific-profile)\n  + [Filter all firewall rules](#filter-all-firewall-rules)\n  + [Code Red](#code-red)\n    - [Isolate Endpoint](#isolate-endpoint)\n\n\u003c/details\u003e\n\n### Retrieve Firewall profile names\n```powershell\n(Get-NetFirewallProfile).name\n```\n![image](https://user-images.githubusercontent.com/44196051/120560271-53cb3a00-c3fa-11eb-83f7-f60f431d0c7b.png)\n\n#### Retrieve rules of specific profile\nNot likely to be too useful getting all of this information raw, so add plenty of filters\n```powershell\nGet-NetFirewallProfile -Name Public | Get-NetFirewallRule\n##filtering it to only show rules that are actually enabled\nGet-NetFirewallProfile -Name Public | Get-NetFirewallRule | ? Enabled -eq \"true\"\n```\n![image](https://user-images.githubusercontent.com/44196051/120560766-3cd91780-c3fb-11eb-9781-bf933c4b0efa.png)\n\n### Filter all firewall rules\n```powershell\n\n#show firewall rules that are enabled\nGet-NetFirewallRule | ? Enabled -eq \"true\"\n#will show rules that are not enabled\nGet-NetFirewallRule | ? Enabled -notmatch \"true\"\n\n##show firewall rules that pertain to inbound\nGet-NetFirewallRule | ? direction -eq \"inbound\"\n#or outbound\nGet-NetFirewallRule | ? direction -eq \"outbound\"\n\n##stack these filters\nGet-NetFirewallRule | where {($_.Enabled -eq \"true\" -and $_.Direction -eq \"inbound\")}\n#or just use the built in flags lol\nGet-NetFirewallRule -Enabled True -Direction Inbound\n```\n\n### Code Red\n\n#### Isolate Endpoint\nDisconnect network adaptor, firewall the fuck out of an endpoint, and display warning box\n\nThis is a code-red command. Used to isolate a machine in an emergency.\n\nIn the penultimate and final line, you can change the text and title that will pop up for the user\n\n```powershell\nNew-NetFirewallRule -DisplayName \"Block all outbound traffic\" -Direction Outbound -Action Block | out-null; \nNew-NetFirewallRule -DisplayName \"Block all inbound traffic\" -Direction Inbound -Action Block | out-null; \n$adapter = Get-NetAdapter|foreach { $_.Name } ; Disable-NetAdapter -Name \"$adapter\" -Confirm:$false; \nAdd-Type -AssemblyName PresentationCore,PresentationFramework; \n[System.Windows.MessageBox]::Show('Your Computer has been Disconnected from the Internet for Security Issues. Please do not try to re-connect to the internet. Contact Security Helpdesk Desk ',' CompanyNameHere Security Alert',[System.Windows.MessageBoxButton]::OK,[System.Windows.MessageBoxImage]::Information)\n```\n![image](https://user-images.githubusercontent.com/44196051/119979598-0e9aa880-bfb3-11eb-9882-08d02a0d3026.png)\n\n---\n\n\n---\n\n## SMB Queries\n\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n\n  + [List Shares](#list-shares)\n  + [List client-to-server SMB Connections](#list-client-to-server-smb-connections)\n  + [Remove an SMB Share](#remove-an-smb-share)\n\n\u003c/details\u003e\n\n### List Shares\n```powershell\n  Get-SMBShare\n```\n![image](https://user-images.githubusercontent.com/44196051/120796972-5c735b80-c533-11eb-8502-888440c21e94.png)\n\n### List client-to-server SMB Connections\nDialect just means verison. SMB3, SMB2 etc\n\n``` powershell\nGet-SmbConnection\n \n#just show SMB Versions being used. Great for enumeration flaws in enviro - i.e, smb1 being used somewhere\nGet-SmbConnection |\nselect Dialect, Servername, Sharename | sort Dialect   \n```\n![image](https://user-images.githubusercontent.com/44196051/120797516-0eab2300-c534-11eb-9568-7753ad58cdf7.png)\n\n![image](https://user-images.githubusercontent.com/44196051/120797860-795c5e80-c534-11eb-87fb-cc02ca70b4b0.png)\n\n### Remove an SMB Share\n```powershell\nRemove-SmbShare -Name MaliciousShare -Confirm:$false -verbose\n```\n\n---\n\n## Process Queries\n\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n  \n  + [Processes and TCP Connections](#processes-and-tcp-connections)\n  + [Show all processes and their associated user](#show-all-processes-and-their-associated-user)\n  + [Get specific info about the full path binary that a process is running](#get-specific-info-about-the-full-path-binary-that-a-process-is-running)\n  + [Is a specific process a running on a machine or not](#is-a-specific-process-a-running-on-a-machine-or-not)\n  + [Get process hash](#get-process-hash)\n  + [Show all DLLs loaded with a process](#show-all-dlls-loaded-with-a-process)\n  + [Identify process CPU usage](#identify-process-cpu-usage)\n    - [Sort by least CPU-intensive processes](#sort-by-least-cpu-intensive-processes)\n  + [Stop a Process](#stop-a-process)\n  + [Process Tree](#process-tree) \n  \n\u003c/details\u003e\n\n### Processes and TCP Connections\nI have a neat one-liner for you. This will show you the local IP and port, the remote IP andport, the process name, and the underlying executable of the process!\n\nYou could just use `netstat -b`, which gives you SOME of this data\n\n![image](https://user-images.githubusercontent.com/44196051/150956623-7328b24b-4edd-4be7-bf94-f79472650b58.png)\n\n\nBut instead, try this bad boy on for size:\n\n```powershell\nGet-NetTCPConnection |\nselect LocalAddress,localport,remoteaddress,remoteport,state,@{name=\"process\";Expression={(get-process -id $_.OwningProcess).ProcessName}}, @{Name=\"cmdline\";Expression={(Get-WmiObject Win32_Process -filter \"ProcessId = $($_.OwningProcess)\").commandline}} | \nsort Remoteaddress -Descending | ft -wrap -autosize\n```\n\n![image](https://user-images.githubusercontent.com/44196051/150955379-872e2b5f-6d88-4b3f-929f-debaa8fd1036.png)\n\n### Show all processes and their associated user\n\n```powershell\nget-process * -Includeusername\n```\n\n![image](https://user-images.githubusercontent.com/44196051/120329122-70288300-c2e3-11eb-95ef-276ffd556acd.png)\n\n\nTry this one if you're hunting down suspicious processes from users\n\n```powershell\ngwmi win32_process | \nSelect Name,@{n='Owner';e={$_.GetOwner().User}},CommandLine | \nsort Name -unique -descending | Sort Owner | ft -wrap -autosize\n```\n\n![image](https://user-images.githubusercontent.com/44196051/150958834-782846e5-bd2b-4bbc-9305-df3e24021052.png)\n\n\n### Get specific info about the full path binary that a process is running\n```powershell\ngwmi win32_process | \nSelect Name,ProcessID,@{n='Owner';e={$_.GetOwner().User}},CommandLine | \nsort name | ft -wrap -autosize | out-string\n```\n\n![image](https://user-images.githubusercontent.com/44196051/120901193-4350d480-c631-11eb-81c4-41c832d064de.png)\n\n\n### Get specific info a process is running\n```powershell\nget-process -name \"nc\" | ft Name, Id, Path,StartTime,Includeusername -autosize \n```\n![Images](https://user-images.githubusercontent.com/44196051/120901392-78a9f200-c632-11eb-84df-2168226375a7.png)\n\n### Is a specific process a running on a machine or not\n```powershell\n$process = \"memes\";\nif (ps |  where-object ProcessName -Match \"$process\") {Write-Host \"$process successfully installed on \" -NoNewline ; hostname} else {write-host \"$process absent from \" -NoNewline ; hostname}\n```\n\nExample of process that is absent\n![image](https://user-images.githubusercontent.com/44196051/119976215-b1045d00-bfae-11eb-806c-49a62f5aab15.png)\nExample of process that is present\n![image](https://user-images.githubusercontent.com/44196051/119976374-ea3ccd00-bfae-11eb-94cd-37ed4233564d.png)\n\n### Get process hash\nGreat to make malicious process stand out. If you want a different Algorithm, just change it after `-Algorithm` to something like `sha256` \n```powershell\nforeach ($proc in Get-Process | select path -Unique){try\n{ Get-FileHash $proc.path -Algorithm sha256 -ErrorAction stop |\nft hash, path -autosize -HideTableHeaders | out-string -width 800 }catch{}}\n```\n![image](https://user-images.githubusercontent.com/44196051/119976802-8cf54b80-bfaf-11eb-82de-1a92bbcae4f9.png)\n\n### Show all DLLs loaded with a process\n```powershell\nget-process -name \"memestask\" -module \n```\n![image](https://user-images.githubusercontent.com/44196051/119976958-bdd58080-bfaf-11eb-8833-7fdf78045967.png)\n\nAlternatively, pipe `|fl` and it will give a granularity to the DLLs\n\n![image](https://user-images.githubusercontent.com/44196051/119977057-db0a4f00-bfaf-11eb-97ce-1e762088de8e.png)\n\n### Identify process CPU usage \n```powershell\n (Get-Process -name \"googleupdate\").CPU | fl \n```\n![image](https://user-images.githubusercontent.com/44196051/119982198-756d9100-bfb6-11eb-8645-e41cf46116b3.png)\n\nI get mixed results with this command but it's supposed to give the percent of CPU usage. I need to work on this, but I'm putting it in here so the world may bare wittness to my smooth brain. \n```powershell\n$ProcessName = \"symon\" ; \n$ProcessName = (Get-Process -Id $ProcessPID).Name; \n$CpuCores = (Get-WMIObject Win32_ComputerSystem).NumberOfLogicalProcessors; \n$Samples = (Get-Counter \"\\Process($Processname*)\\% Processor Time\").CounterSamples; \n$Samples | Select `InstanceName,@{Name=\"CPU %\";Expression={[Decimal]::Round(($_.CookedValue / $CpuCores), 2)}}\n```\n![image](https://user-images.githubusercontent.com/44196051/119982326-9a620400-bfb6-11eb-9a66-ad5a5661bc8a.png)\n\n### Sort by least CPU-intensive processes\n\nRight now will show the lower cpu-using proccesses...useful as malicious process probably won't be as big a CPU as Chrome, for example. But change first line to `Sort CPU -descending` if you want to see the chungus processes first\n\n```powershell\ngps | Sort CPU |\nSelect -Property ProcessName, CPU, ID, StartTime | \nft -autosize -wrap | out-string -width 800\n```\n\n![image](https://user-images.githubusercontent.com/44196051/120922422-f87e9d80-c6c0-11eb-8901-77ba9c95432c.png)\n\n### Stop a Process\n```powershell\nGet-Process -Name \"memeprocess\" | Stop-Process -Force -Confirm:$false -verbose\n```\n\n### Process Tree\nYou can download the [PsList exe from Sysinternals](https://docs.microsoft.com/en-us/sysinternals/downloads/pslist)\n\nFire it off with the `-t` flag to create a parent-child tree of the processes\n\n![example_of_ps_tree](https://user-images.githubusercontent.com/44196051/151773540-e89e9d9a-92fc-472e-94b9-e1f552dedf4f.png)\n\n\n---\n\n## Recurring Task Queries\n\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n  \n  + [Get scheduled tasks](#get-scheduled-tasks)\n    - [Get a specific schtask](#get-a-specific-schtask)\n    - [To find the commands a task is running](#to-find-the-commands-a-task-is-running)\n    - [To stop the task](#to-stop-the-task)\n    - [All schtask locations](#all-schtask-locations) \n    - [Sneaky Schtasks via the Registry](#Sneaky-Schtasks-via-the-Registry)\n  + [Show what programs run at startup](#show-what-programs-run-at-startup)\n    - [Programs at login](#programs-at-login)\n    - [Programs at PowerShell](#programs-at-powershell) \n  + [Stolen Links](#stolen-links) \n  + [Scheduled Jobs](#scheduled-jobs)\n    - [Find out what scheduled jobs are on the machine](#find-out-what-scheduled-jobs-are-on-the-machine)\n    - [Get detail behind scheduled jobs](#get-detail-behind-scheduled-jobs)\n    - [Kill job](#kill-job)\n  + [Hunt WMI Persistence](#hunt-wmi-persistence)\n    - [Removing it](#removing-it)\n    - [A note on CIM](#a-note-on-cim)\n  + [Run Keys](#Run-Keys)\n    - [What are Run Keys](#what-are-run-keys)\n    - [Finding Run Evil](#Finding-Run-Evil)\n    - [Removing Run Evil](#removing-run-evil)\n    - [Other Malicious Run Locations](#other-malicious-run-locations)\n    - [Evidence of Run Key Execution](#Evidence-of-Run-Key-Execution)\n  + [Screensaver Persistence](#Screensaver-Persistence) \n  + [Query Group Policy](#Query-Group-Policy)\n    - [Query GPO Scripts](#query-gpo-scripts)\n  + [Autoruns](#autoruns)\n\n\u003c/details\u003e\n\n### Get scheduled tasks\nIdentify the user behind a command too. Great at catching out malicious schtasks that perhaps are imitating names, or a process name\n```powershell\nschtasks /query /FO CSV /v | convertfrom-csv |\nwhere { $_.TaskName -ne \"TaskName\" } |\nselect \"TaskName\",\"Run As User\", Author, \"Task to Run\"| \nfl | out-string\n```\n![image](https://user-images.githubusercontent.com/44196051/120901651-27026700-c634-11eb-9aa2-6a4812450ac2.png)\n\n#### Get a specific schtask\n```powershell\nGet-ScheduledTask -Taskname \"wifi*\" | fl *\n```\n![image](https://user-images.githubusercontent.com/44196051/120563312-2d100200-c400-11eb-8f47-cd3e76df4165.png)\n\n#### To find the commands a task is running\nGreat one liner to find exactly WHAT a regular task is doing\n```powershell\n$task = Get-ScheduledTask | where TaskName -EQ \"meme task\"; \n$task.Actions\n```\n![image](https://user-images.githubusercontent.com/44196051/119979087-5f5dd180-bfb2-11eb-9d4d-bbbf66043535.png)\n\nAnd a command to get granularity behind the schtask requires you to give the taskpath. Tasks with more than one taskpath will throw an error here\n```powershell\n$task = \"CacheTask\";\nget-scheduledtask -taskpath (Get-ScheduledTask -Taskname \"$task\").taskpath | Export-ScheduledTask\n#this isn't the way the microsoft docs advise. \n     ##But I prefer this, as it means I don't need to go and get the taskpath when I already know the taskname\n```\n![image](https://user-images.githubusercontent.com/44196051/120563667-18803980-c401-11eb-9b10-621169f38437.png)\n\n#### To stop the task\n```powershell\nGet-ScheduledTask \"memetask\" | Stop-ScheduledTask -Force -Confirm:$false -verbose\n```\n#### All schtask locations\nThere's some major overlap here, but it pays to be thorough. \n\n```\nHKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\Taskcache\\Tree\nHKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\Taskcache\\Tasks\nC:\\Windows\\System32\\Tasks\nC:\\Windows\\Tasks\nC:\\windows\\SysWOW64\\Tasks\\\n```\n\nYou can compare the above for tasks missing from the C:\\Windows directories, but present in the Registry.\n\n```powershell\n# From my man Anthony Smith - https://www.linkedin.com/in/anthony-c-smith/\n\n$Reg=(Get-ItemProperty -path \"HKLM:\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\Taskcache\\tree\\*\").PsChildName\n$XMLs = (ls C:\\windows\\System32\\Tasks\\).Name\nCompare-Object $Reg $XMLs\n```\n\n\u003cimg width=\"1180\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/214910299-a82ec894-7f16-44b8-92a3-b6344a09925d.png\"\u003e\n\n\n#### Sneaky Schtasks via the Registry\nThreat actors have been known to manipulate scheduled tasks in such a way that Task Scheduler no longer has visibility of the recuring task. \n\nHowever, querying the Registry locations `HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\Taskcache\\Tree` and `HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\Taskcache\\Tasks`, can reveal a slice of these sneaky tasks.\n\nShout out to my man [@themalwareguy](https://twitter.com/themalwareguy) for the $fixedstring line that regexes in/out good/bad characters. \n\n```Powershell\n# the schtask for our example\n# schtasks /create /tn \"Find_Me\" /tr calc.exe /sc minute /mo 100 /k\n\n# Loop and parse \\Taskcache\\Tasks Registry location for scheduled tasks\n  ## Parses Actions to show the underlying binary / commands for the schtask\n  ## Could replace Actions with Trigggers on line 10, after ExpandedProperty\n(Get-ItemProperty \"HKLM:\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\Taskcache\\Tasks\\*\").PSChildName | \nForeach-Object {\n  write-host \"----Schtask ID is $_---\" -ForegroundColor Magenta ;\n  $hexstring = Get-ItemProperty \"HKLM:\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\Taskcache\\Tasks\\$_\" | Select -ExpandProperty Actions;\n  $fixedstring = [System.Text.Encoding]::Unicode.GetString($hexstring) -replace '[^a-zA-Z0-9\\\\._\\-\\:\\%\\/\\$ ]', ' '; # Obtaining the Unicode string reduces the chances of getting invalid characters, and the regex will assist in stripping each string of junk\n  write-host $fixedstring\n}\n```\n\u003cimg width=\"1423\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/214888721-8a89b9db-3486-4a76-bd97-446eedc38303.png\"\u003e\n\nIf you don't need to loop to search, because you know what you're gunning for then you can just deploy this\n```powershell\n$hexstring = (Get-ItemProperty \"HKLM:\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\Taskcache\\Tasks\\{ID}\" | \nSelect -ExpandProperty Actions) -join ',' ; $hexstring.Split(\" \")\n## can then go to cyberchef, and convert From Decimal with the comma (,) delimineter \n```\n\u003cimg width=\"1433\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/214889168-91ebdbe5-ac86-41f5-ba44-e5860ed0615a.png\"\u003e\n\nOnce you've deployed the above loop, and zoned in on a binary / one-liner that seems sus, you can query it in the other Registry location\n\n```PowerShell\n# Then for the ID of interest under \\Taskcache\\Tree subkey\n  # Example: $ID = \"{8E350038-3475-413A-A1AE-20711DD11C95}\" ;  \n$ID = \"{XYZ}\" ; \nget-itemproperty -path \"HKLM:\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\Taskcache\\Tree\\*\" | \n? Id -Match \"$ID\" | fl *Name,Id,PsPath\n```\n\n\u003cimg width=\"1325\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/214890947-55f67e6c-7b4b-492d-98c1-8d9ad49e1497.png\"\u003e\n\n\nAnd then eradicating these Registry schtask entries is straight forward via Regedit's GUI, that way you have no permission problems. Delete both:\n* HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\Taskcache\\Tasks\\\\{$ID}\n* HKLM:\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\Taskcache\\Tree\\\\$Name\n\n\u003cimg width=\"1017\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/214887239-8bdcce93-c218-47c4-a346-1498346625a9.png\"\u003e\n\u003cimg width=\"1015\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/214888207-5bb0767b-56f8-4689-8925-9caeae9b5f62.png\"\u003e\n\n\n### Show what programs run at startup\n```powershell\nGet-CimInstance Win32_StartupCommand | Select-Object Name, command, Location, User | Format-List \n```\n![image](https://user-images.githubusercontent.com/44196051/120332890-12963580-c2e7-11eb-9805-feee341140fa.png)\n\nSome direct path locations too can be checked\n```powershell\nHKLM\\software\\classes\\exefile\\shell\\open\\command\nc:\\Users\\*\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\startup\n```\n\nQuerying that last one in more detail, you have some interesting options\n```powershell\n#Just list out the files in each user's startup folder\n(gci \"c:\\Users\\*\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\startup\\*\").fullname\n\n#Extract from the path User, Exe, and print machine name\n(gci \"c:\\Users\\*\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\startup\\*\").fullname | \nforeach-object {$data = $_.split(\"\\\\\");write-output \"$($data[2]), $($data[10]), $(hostname)\"}\n\n#Check the first couple lines of files' contents\n(gci \"c:\\Users\\*\\appdata\\roaming\\microsoft\\windows\\start menu\\programs\\startup\\*\").fullname | \nforeach-object {write-host `n$_`n; gc $_ -encoding byte| fhx |select -first 5}\n```\n\u003cimg width=\"1000\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/216298167-e3a112bf-6d48-43b5-9b2c-fc9d47d50cc8.png\"\u003e\n\n#### Programs at login\nAdversaries can link persistence mechanisms to be activated to a users' login via the registry `HKEY_CURRENT_USER\\Environment -UserInitMprLogonScript`\n\n```powershell\n#Create HKU drive\nmount -PSProvider Registry -Name HKU -Root HKEY_USERS\n\n#list all user's enviros\n(gp \"HKU:\\*\\Environment\").UserInitMprLogonScript\n\n#Collect SID of target user with related logon task\ngp \"HKU:\\*\\Environment\" | FL PSParentPath,UserInitMprLogonScript\n\n# insert SID and convert it into username\ngwmi win32_useraccount | \nselect Name, SID | \n? SID -match \"\" #insert SID between quotes \n```\n\n\u003cimg width=\"949\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/172841004-ba253267-4619-4983-bd61-90c4e1623de0.png\"\u003e\n\nYou can remove this regsistry entry\n\n```powershell\n#confirm via `whatif` flag that this is the right key\nremove-itemproperty \"HKU:\\SID-\\Environment\\\" -name \"UserInitMprLogonScript\" -whatif\n#delete it\nremove-itemproperty \"HKU:\\SID-\\Environment\\\" -name \"UserInitMprLogonScript\" -verbose\n```\n\n\u003cimg width=\"1415\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/172841461-c39ab569-288c-4484-b8e5-59a0ff5b1e8a.png\"\u003e\n\n#### Programs at Powershell\nAdversaries can link their persistence mechanisms to a PowerShell profile, executing their malice every time you start PowerShell\n\n```powershell\n#confirm the profile you are querying\necho $Profile\n#show PowerShell profile contents\ntype $Profile\n```\n![image](https://user-images.githubusercontent.com/44196051/148917480-5c3adfba-e9cd-4e16-9e5b-439de153cc1c.png)\n\nTo fix this one, I'd just edit the profile and remove the persistence (so `notepad $Profile` will be just fine)\n\nYou can get a bit more clever with this if you want\n\n```powershell\n(gci C:\\Users\\*\\Documents\\WindowsPowerShell\\*profile.ps1, C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\*profile.ps1).FullName|\nForeach-Object {\n  write-host \"----$_---\" -ForegroundColor Magenta ; \n  gc $_ # | select-string -notmatch function ## if you want to grep out stuff you don't wanna see, uncomment\n}\n```\n\u003cimg width=\"1223\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/216776621-ab30be1e-583f-45f7-b650-7918bbb73b82.png\"\u003e\n\n\n### Stolen Links\nAdversaries can insert their malice into shortcuts. They can do it in clever ways, so that the application will still run but at the same time their malice will also execute when you click on the application\n\nFor demo purposes, below we have Microsoft Edge that has been hijacked to execute calc on execution. \n\n![image](https://user-images.githubusercontent.com/44196051/148918419-45845f19-84e7-44aa-a8e0-c6310ee4a905.png)\n\nWe can specifically query all Microsoft Edge's shortcuts to find this\n```powershell\nGet-CimInstance Win32_ShortcutFile | \n? FileName -match 'edge' | \nfl FileName,Name,Target, LastModified\n```\n\n![image](https://user-images.githubusercontent.com/44196051/148921262-3a9019ce-3b95-4f95-962f-db41871162fd.png)\n\nThis doesn't scale however, as you will not know the specific shortcut that the adversary has manipulated. So instead, sort by the `LastModified` date\n\n```powershell\nGet-CimInstance Win32_ShortcutFile | \nsort LastModified -desc | \nfl FileName,Name,Target, LastModified\n```\n\n![image](https://user-images.githubusercontent.com/44196051/148921953-725bc874-0d30-4eb1-92c4-86714d947c90.png)\n\n#### Hunt LNKs at scale\n\nThis above will output a LOT, however. You may want to only show results for anything LastModified after a certain date. Lets ask to only see things modified in the year 2022 onwards\n\n```powershell\nGet-CimInstance Win32_ShortcutFile |\nwhere-object {$_.lastmodified -gt [datetime]::parse(\"01/01/2022\")} | \nsort LastModified -desc | fl FileName,Name,Target, LastModified\n```\n\n![image](https://user-images.githubusercontent.com/44196051/148923043-81b092d5-cf05-4ab8-afcc-a662a0e34651.png)\n\n\n### Scheduled Jobs\nSurprisingly, not many people know about [Scheduled Jobs](https://devblogs.microsoft.com/scripting/introduction-to-powershell-scheduled-jobs/). They're not anything too strange or different, they're just scheduled tasks that are specificially powershell. \n\n[I've written about a real life encounter I had during an incident](https://labs.jumpsec.com/powershell-jobs/), where the adversary had leveraged a PowerShell scheduled job to execute their malice at an oppertune time\n\n#### Find out what scheduled jobs are on the machine\n```powershell\n Get-ScheduledJob\n # pipe to | fl * for greater granularity\n```\n![image](https://user-images.githubusercontent.com/44196051/120564374-a7418600-c402-11eb-8b7c-92fd86c9df2f.png)\n\n#### Get detail behind scheduled jobs\n```powershell\nGet-ScheduledJob | Get-JobTrigger | \nFt -Property @{Label=\"ScheduledJob\";Expression={$_.JobDefinition.Name}},ID,Enabled, At, frequency, DaysOfWeek\n#pipe to fl or ft, whatever you like the look of more in the screenshot\n```\n\n![image](https://user-images.githubusercontent.com/44196051/120564784-92192700-c403-11eb-930a-3aa0ba178434.png)\n\n#### Kill job\nThe following all work.\n```powershell\nDisable-ScheduledJob -Name evil_sched\nUnregister-ScheduledJob -Name eviler_sched\nRemove-Job -id 3 \n#then double check it's gone with Get-ScheduledJob\n\n#if persists, tack on to unregister or remove-job\n-Force -Confirm:$false -verbose\n```\n\n### Hunt WMI Persistence\n\nWMIC can do some pretty evil things [1](https://www.fireeye.com/content/dam/fireeye-www/global/en/current-threats/pdfs/wp-windows-management-instrumentation.pdf) \u0026 [2](https://in.security/an-intro-into-abusing-and-identifying-wmi-event-subscriptions-for-persistence/). One sneaky, pro-gamer move it can pull is *persistence*\n\nIn the image below I have included a part of setting up WMI persistence\n\n![image](https://user-images.githubusercontent.com/44196051/122431376-4ed6c080-cf8c-11eb-9538-55f6e0e7c7a5.png)\n\n\n##### Finding it\nNow, our task is to find this persistent evil.\n\nGet-CimInstance comes out cleaner, but you can always rely on the alternate Get-WMIObject\n\n```powershell\n\nGet-CimInstance -Namespace root\\Subscription -Class __FilterToConsumerBinding\nGet-CimInstance -Namespace root\\Subscription -Class __EventFilter\nGet-CimInstance -Namespace root\\Subscription -Class __EventConsumer\n\n## OR\n\nGet-WMIObject -Namespace root\\Subscription -Class __EventFilter\nGet-WMIObject -Namespace root\\Subscription -Class __FilterToConsumerBinding\nGet-WMIObject -Namespace root\\Subscription -Class __EventConsumer\n```\n\n![image](https://user-images.githubusercontent.com/44196051/122433194-e7217500-cf8d-11eb-94b1-957254bf0f4c.png)\n![image](https://user-images.githubusercontent.com/44196051/122433360-0fa96f00-cf8e-11eb-90f6-4c3baafaeddd.png)\n![image](https://user-images.githubusercontent.com/44196051/122433449-26e85c80-cf8e-11eb-9226-ce9f6985d76b.png)\n\n#### Removing it\n\nNow we've identified the evil WMI persistence, let us be rid of it! \n\nWe can specify the Name as `EVIL` as that's what it was called across the three services. Whatever your persistence calls itself, change the name for that\n\n```powershell\n#notice this time, we use the abbrevated version of CIM and WMI\n\ngcim -Namespace root\\Subscription -Class __EventFilter | \n? Name -eq \"EVIL\" | Remove-CimInstance -verbose\n\ngcim -Namespace root\\Subscription -Class __EventConsumer| \n? Name -eq \"EVIL\" | Remove-CimInstance -verbose\n\n#it's actually easier to use gwmi here instead of gcim\ngwmi -Namespace root\\Subscription -Class __FilterToConsumerBinding | \n? Consumer -match \"EVIL\" | Remove-WmiObject -verbose\n```\n\n![image](https://user-images.githubusercontent.com/44196051/122436413-b55ddd80-cf90-11eb-9cb5-7854ddf6225d.png)\n\n\n#### A note on CIM \n\nYou may see WMI and CIM talked about together, whether on the internet or on in the Blue Team Notes here. \n\nCIM is a standard for language for vendor-side management of a lot of the physical and digital mechanics of what makes a computer tick. WMIC was and is Microsoft's interpretation of CIM. \n\nHowever, Microsoft is going to decommision WMIC soon. So using `Get-Ciminstance` versions rather than `get-wmiobject` is probably better for us to learn in the long term. I dunno man, [It's complicated](https://devblogs.microsoft.com/scripting/should-i-use-cim-or-wmi-with-windows-powershell/). \n\n\n### Run Keys\n#### What are Run Keys\n\nI've written in depth [about run keys, elsewhere](https://labs.jumpsec.com/running-once-running-twice-pwned-windows-registry-run-keys/)\n\nRun and RunOnce registry entries will run tasks on startup. Specifically: \n\n* Run reg keys will run the task every time there's a login. \n* RunOnce reg kgeys will run the taks once and then self-delete keys. \n  * If a RunOnce key has a name with an exclemation mark (!likethis) then it will self-delete\n  * IF a RunOnce key has a name with an asterik (* LikeDIS) then it can run even in Safe Mode.  \n\nIf you look in the reg, you'll find some normal executables. \n\n![image](https://user-images.githubusercontent.com/44196051/124326535-76c64680-db7e-11eb-9b98-261b3704d30a.png)\n\n\n### Finding Run Evil\n\nA quick pwsh _for loop_ can collect the contents of the four registry locations. \n\n```powershell\n#Create HKU drive\nmount -PSProvider Registry -Name HKU -Root HKEY_USERS\n\n(gci HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run, HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce, HKU:\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Run, HKU:\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce ).Pspath |\nForeach-Object {\n  write-host \"----Reg location is $_---\" -ForegroundColor Magenta ; \n  gp $_ | \n  select -property * -exclude PS*, One*, vm* | #exclude results here\n  FL\n}\n\n#you can squish that all in one line if you need to\n(gci HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run, HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce, HKU:\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Run, HKU:\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce ).Pspath | Foreach-Object {write-host \"----Reg location is $_---\" -ForegroundColor Magenta ; gp $_ | select -property * -exclude PS*, One*, vm* |sort| fl}\n```\n\n\u003cimg width=\"1353\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/202874165-d0aa355d-dfba-4e64-af5b-ff1b016e910f.png\"\u003e\n\n\nYou can also achieve the same thing with these two alternative commands, but it isn't as cool as the above for loop\n\n```powershell\n\nget-itemproperty \"HKU:\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Run*\" | \n  select -property * -exclude PSPR*,PSD*,PSC*,PSPAR*  | fl\nget-itemproperty \"HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run*\" | \n  select -property * -exclude PSPR*,PSD*,PSC*,PSPAR*  | fl\n```\n\n\u003cimg width=\"1401\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/202874181-7679be09-a11f-42b9-8257-9f4bae8b4714.png\"\u003e\n\n\n### Removing Run evil\n\nBe surgical here. You don't want to remove Run entries that are legitimate. It's important you remove with -verbose too and double-check it has gone, to make sure you have removed what you think you have. \n\nSpecify the SID\n\n```powershell\n#Create HKU drive\nmount -PSProvider Registry -Name HKU -Root HKEY_USERS\n\n#List the malicious reg by path\nget-itemproperty \"HKU:\\SID\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\" | select -property * -exclude PS* | fl\n\n#Then pick the EXACT name of the Run entry you want to remove. Copy paste it, include any * or ! too please\nRemove-ItemProperty -Path \"HKU:\\SID-\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\" -Name \"*EvilerRunOnce\" -verbose\n\n#Then check again to be sure it's gone\nget-itemproperty \"HKU:\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\" | select -property * -exclude PS* | fl\n```\n\n![image](https://user-images.githubusercontent.com/44196051/124332253-f9ec9a00-db88-11eb-9007-017dfa956707.png)\n\n\n### Other Malicious Run Locations\n\nSome *folders* can be the locations of persistence. \n\n```powershell\n#Create HKU drive\nmount -PSProvider Registry -Name HKU -Root HKEY_USERS\n\n$folders = @(\"HKU:\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\",\"HKU:\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\",\"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\",\"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\")\nforeach ($folder in $folders) {\n  write-host \"----Reg key is $folder--- -ForegroundColor Magenta \"; \n  get-itemproperty -path \"$folder\"  | \n  select -property * -exclude PS* | fl\n}\n\n```\n![image](https://user-images.githubusercontent.com/44196051/124331784-df65f100-db87-11eb-8c52-3bb697496cdb.png)\n\nSvchost startup persistence\n\n```powershell\n\nget-itemproperty -path \"HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost\"\n```\n![image](https://user-images.githubusercontent.com/44196051/124331810-edb40d00-db87-11eb-8712-c1028302847f.png)\n\n\nWinlogon startup persistence\n\n```powershell\n#Create HKU drive\nmount -PSProvider Registry -Name HKU -Root HKEY_USERS\n\n(gci \"HKU:\\*\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\").PSPath | \nForeach-Object {\n  write-host \"----Reg location is $_---\" -ForegroundColor Magenta ; \n  gp $_ | \n  select -property * -exclude PS* |\n  FL\n}\n```\n\u003cimg width=\"1429\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/203814780-c0915f3e-a594-460b-bf4d-c4776addcb86.png\"\u003e\n\nFind more examples of Run key evil from [Mitre ATT\u0026CK](https://attack.mitre.org/techniques/T1547/001/)\n\n\n##### Evidence of Run Key Execution\nYou can query the 'Microsoft-Windows-Shell-Core/Operational' log to find evidence if a registry run key was successful in executing. \n\n```powershell\nget-winevent -filterhashtable @{ logname = \"Microsoft-Windows-Shell-Core/Operational\" ; ID = 9707} |\nselect TimeCreated, Message, \n@{Name=\"UserName\";Expression = {$_.UserId.translate([System.Security.Principal.NTAccount]).value}}  | \nsort TimeCreated -desc| fl\n```\n\n\u003cimg width=\"1146\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/154504598-8c4dd53d-14ac-4c22-9e40-f37ae7ebebe4.png\"\u003e\n\n\n### Screensaver Persistence\n\nIt can be done, I swear. [Mitre ATT\u0026CK](https://attack.mitre.org/techniques/T1546/002/) has instances of .SCR's being used to maintain regular persistence\n\n```powershell\n#Create HKU drive\nmount -PSProvider Registry -Name HKU -Root HKEY_USERS\n\ngp \"HKU:\\*\\Control Panel\\Desktop\\\" | select SCR* | fl\n# you can then go and collect the .scr listed in the full path, and reverse engineer the binary\n\n#you can also collect wallpaper info from here\ngp \"HKU:\\*\\Control Panel\\Desktop\\\" | select wall* | fl\n```\n![image](https://user-images.githubusercontent.com/44196051/124333514-57ceb100-db8c-11eb-8695-280d12bcf0d5.png)\n\n### Query Group Policy\nThe group policy in an Windows can be leveraged and weaponised to propogate malware and even ransomware across the entire domain\n\nYou can query the changes made in the last X days with this line\n\n```powershell\n#collects the domain name as a variable to use later\n$domain = (Get-WmiObject -Class win32_computersystem).domain; \nGet-GPO -All -Domain $domain | \n?{ ([datetime]::today - ($_.ModificationTime)).Days -le 10 } | sort\n# Change the digit after -le to the number of days you want to go back for\n```\n\n![2021-09-17_15-01](https://user-images.githubusercontent.com/44196051/133795473-3d817c69-2b9c-4d4a-b849-b37d1984ffc1.png)\n\n#### Query GPO Scripts\nWe can hunt down the strange thinngs we might see in our above query\n\nWe can list all of the policies, and see where a policy contains a script or executable. You can change the `include` at the end to whatever you want\n```powershell\n$domain = (Get-WmiObject -Class win32_computersystem).domain;\ngci -recurse \\\\$domain\\\\sysvol\\$domain\\Policies\\ -file -include *.exe, *.ps1\n```\n\n![2021-09-17_15-20](https://user-images.githubusercontent.com/44196051/133798475-0da6d9f6-2dc6-4da2-9066-c79060f8ea84.png)\n\nWe can hunt down where GPO scripts live\n\n```powershell\n$domain = (Get-WmiObject -Class win32_computersystem).domain;\ngci -recurse \\\\$domain\\\\sysvol\\*\\scripts\n```\n![2021-09-17_15-04](https://user-images.githubusercontent.com/44196051/133796067-d02398d1-be75-4c15-a3bc-41a8fb04158a.png)\n\n\n### Autoruns\n[Autoruns](https://docs.microsoft.com/en-us/sysinternals/downloads/autoruns) is a Sysinternals tool for Windows. It offers analysts a GUI method to examine the recurring tasks that an adversary might use for persistence and other scheduled malice.\n\nBefore you go anywhere cowboy, make sure you've filtered out the known-goods under options. It makes analysis a bit easier, as you're filtering out noise. Don't treat this as gospel though, so yes hide the things that VirusTotal and Microsoft SAY are okay.....but go and verify that those auto-running tasks ARE as legitimate as they suppose they are\n\n![image](https://user-images.githubusercontent.com/44196051/137591938-cbe1fe12-0a3a-4304-aa9b-05bd97d903c3.png)\n\nI personally just stick to the 'Everything' folder, as I like to have full visibility rather than go into the options one by one\n\n![image](https://user-images.githubusercontent.com/44196051/137592010-68d39e4c-6bf5-4209-85e6-bfd9e92854e2.png)\n\nSome things in autorun may immediately stick out to you as strange. Take for example the malicious run key I inserted on the VM as an example:\n\n![image](https://user-images.githubusercontent.com/44196051/137592077-6842b87d-4a7f-4f20-92b6-7e6bc721c101.png)\n\nYou can right-click and ask Virus Total to see if the hash is a known-bad \n\n![image](https://user-images.githubusercontent.com/44196051/137592164-7880d919-9c76-4ad0-a65c-3a2bbec9dad6.png)\n\nAnd you can right-click and ask autoruns to delete this recurring task from existence\n\n![image](https://user-images.githubusercontent.com/44196051/137592197-d14f2913-d92e-4fad-b113-03aaf2c18019.png)\n\n\nI like autoruns for digital forensics, where you take it one machine at a time. But - in my uneducated opinion - it does not scale well. A tool like Velociraptor that allows orchestration across thousands of machines can be leveraged to query things with greater granularity than Autoruns allows. \n\nThis is why I like to use PowerShell for much of my blue team work on a Windows machine, where possible. I can pre-filter my queries so I don't get distraced by noise, but moreover I can run that fine-tuned PowerShell query network-wide across thosuands of machines and recieve the results back rapidly.\n\n---\n\n## File Queries\n\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n  \n  + [File Tree](#file-tree) \n  + [Wildcard paths and files](#wildcard-paths-and-files)\n  + [Check if a specific file or path is alive.](#check-if-a-specific-file-or-path-is-alive)\n  + [test if  files and directories are present or absent](#test-if--files-and-directories-are-present-or-absent)\n  + [Query File Contents](#query-file-contents)\n    - [Alternate data streams](#alternate-data-streams)\n    - [Read hex of file](#read-hex-of-file)\n  + [Recursively look for particular file types, and once you find the files get their hashes](#recursively-look-for-particular-file-types--and-once-you-find-the-files-get-their-hashes)\n  + [Compare two files' hashes](#compare-two-files--hashes)\n  + [Find files written after X date](#find-files-written-after-x-date)\n    - [Remove items written after x date](#Remove-items-written-after-x-date)\n  + [copy multiple files to new location](#copy-multiple-files-to-new-location)\n  + [Grep in Powershell](#grep-in-powershell)\n \n\u003c/details\u003e\n\n### File tree\n\nFire off `tree` to list the directories and files underneath your current working directory, nestled under each other\n\n![image](https://user-images.githubusercontent.com/44196051/151773962-3b1dac5a-ff4c-4b09-bead-daa97703b650.png)\n\n\n### Wildcard paths and files\nYou can chuck wildcards in directories for gci, as well as wildcard to include file types.\n\nLet's say we want to look in all of the Users \\temp\\ directories. We don't want to put their names in, so we wildcard it.\n\nWe also might only be interested in the pwsh scripts in their \\temp\\, so let's filter for those only\n\n```powershell\ngci \"C:\\Users\\*\\AppData\\Local\\Temp\\*\" -Recurse -Force -File  -Include *.ps1, *.psm1, *.txt | \nft lastwritetime, name -autosize | \nout-string -width 800\n```\n![image](https://user-images.githubusercontent.com/44196051/121200190-741c4e00-c86b-11eb-800e-f3170c2a02e5.png)\n\n\n### Check if a specific file or path is alive. \n\nI've found that this is a great one to quickly check for specific vulnerabilities. Take for example, CVE-2021-21551. The one below this one is an excellent way of utilising the 'true/false' binary results that test-path can give\n``` powershell\ntest-path -path \"C:\\windows\\temp\\DBUtil_2_3.Sys\"\n```\n![image](https://user-images.githubusercontent.com/44196051/119982761-283def00-bfb7-11eb-83ab-061b6c628372.png)\n\n### test if  files and directories are present or absent\nThis is great to just sanity check if things exist. Great when you're trying to check if files or directories have been left behind when you're cleaning stuff up.\n```powershell\n$a = Test-Path \"C:\\windows\\sysmon.exe\"; $b= Test-Path \"C:\\Windows\\SysmonDrv.sys\"; $c = test-path \"C:\\Program Files (x86)\\sysmon\"; $d = test-path \"C:\\Program Files\\sysmon\"; \nIF ($a -eq 'True') {Write-Host \"C:\\windows\\sysmon.exe present\"} ELSE {Write-Host \"C:\\windows\\sysmon.exe absent\"}; \nIF ($b -eq 'True') {Write-Host \"C:\\Windows\\SysmonDrv.sys present\"} ELSE {Write-Host \"C:\\Windows\\SysmonDrv.sys absent\"} ; \nIF ($c -eq 'True') {Write-Host \"C:\\Program Files (x86)\\sysmon present\"} ELSE {Write-Host \"C:\\Program Files (x86)\\sysmon absent\"}; \nIF ($d -eq 'True') {Write-Host \"C:\\Program Files\\sysmon present\"} ELSE {Write-Host \"C:\\Program Files\\sysmon absent\"}\n```\n![image](https://user-images.githubusercontent.com/44196051/119979754-443f9180-bfb3-11eb-9259-5409a0d98c04.png)\n\n^ The above is a bit over-engineered. Here's an an abbrevated version\n```powershell\n$Paths = \"C:\\windows\" , \"C:\\temp\", \"C:\\windows\\system32\", \"C:\\DinosaurFakeDir\" ; \nforeach ($Item in $Paths){if\n(test-path $Item) {write \"$Item present\"}else{write \"$Item absent\"}}\n```\n![image](https://user-images.githubusercontent.com/44196051/120552156-c7ffe080-c3ee-11eb-8f81-3983cab8083b.png)\n\nWe can also make this conditional. Let's say if Process MemeProcess is NOT running, we can then else it to go and check if files exist\n```powershell\n$Paths = \"C:\\windows\" , \"C:\\temp\", \"C:\\windows\\system32\", \"C:\\DinosaurFakeDir\" ; \nif (Get-Process | where-object Processname -eq \"explorer\") {write \"process working\"} else {\nforeach ($Item in $Paths){if (test-path $Item) {write \"$Item present\"}else{write \"$Item absent\"}}}\n```\n![image](https://user-images.githubusercontent.com/44196051/120553995-1c0bc480-c3f1-11eb-811d-eca65d10328d.png)\n\nYou can use `test-path` to query Registry, but even the 2007 [Microsoft docs say](https://devblogs.microsoft.com/powershell/test-path-we-goofed/) that this can give inconsistent results, so I wouldn't bother with test-path for reg stuff when it's during an IR\n\n### Query File Contents\n\nSeen a file you don't recognise? Find out some more about it! Remember though: don't trust timestamps!\n```powershell\nGet-item C:\\Temp\\Computers.csv |\nselect-object -property @{N='Owner';E={$_.GetAccessControl().Owner}}, *time, versioninfo | fl \n```\n![image](https://user-images.githubusercontent.com/44196051/120334042-3443ec80-c2e8-11eb-84a9-c141ca5198a8.png)\n\n#### Alternate data streams\n```powershell\n# show streams that aren't the normal $DATA\nget-item evil.ps1 -stream \"*\" | where stream -ne \":$DATA\"\n# If you see an option that isn't $DATA, hone in on it\nget-content evil.ps1 -steam \"evil_stream\"\n```\n#### Read hex of file\n```powershell\ngc .\\evil.ps1 -encoding byte | \nFormat-Hex\n```\n![image](https://user-images.githubusercontent.com/44196051/120565546-3e0f4200-c405-11eb-9045-e38fc79e2810.png)\n\n### Recursively look for particular file types, and once you find the files get their hashes\nThis one-liner was a godsend during the Microsoft Exchange ballache back in early 2021\n\n```powershell\nGet-ChildItem -path \"C:\\windows\\temp\" -Recurse -Force -File -Include *.aspx, *.js, *.zip|\nGet-FileHash |\nformat-table hash, path -autosize | out-string -width 800\n```\n![image](https://user-images.githubusercontent.com/44196051/120917857-66b76600-c6a9-11eb-85f3-cce3ff502476.png)\n\n\n### Compare two files' hashes\n```powershell\nget-filehash \"C:\\windows\\sysmondrv.sys\" , \"C:\\Windows\\HelpPane.exe\"\n```\n![image](https://user-images.githubusercontent.com/44196051/120772800-97b46100-c518-11eb-84bf-409640c516bc.png)\n\n### Find files written after X date\nI personally wouldn't use this for DFIR. It's easy to manipulate timestamps....plus, Windows imports the original compiled date for some files and binaries if I'm not mistaken\n\nChange the variables in the first time to get what you're looking. Remove the third line if you want to include directories \n```powershell\n$date = \"12/01/2021\"; $directory = \"C:\\temp\"\nget-childitem \"$directory\" -recurse|\nwhere-object {$_.mode -notmatch \"d\"}| \nwhere-object {$_.lastwritetime -gt [datetime]::parse(\"$date\")}|\nSort-Object -property LastWriteTime | format-table lastwritetime, fullname -autosize\n```\n\n![image](https://user-images.githubusercontent.com/44196051/120306808-2b442280-c2ca-11eb-82f8-bca23b5ee0d1.png)\n\n#### Remove items written after x date\nAnd then you can recursively remove the files and directories, in case malicious\n\n```powershell\n$date = \"31/01/2022\"; $directory = \"C:\\Users\\Frank\\AppData\\\"\nget-childitem \"$directory\" -recurse|\nwhere-object {$_.lastwritetime -gt [datetime]::parse(\"$date\")}|\nSort-Object -property LastWriteTime | remove-item -confirm -whatif\n```\n![image](https://user-images.githubusercontent.com/44196051/151830903-2f1ff6c6-6994-4141-aa65-143f59ff96e9.png)\n\nRemove the last -whatif flag to actaully detonate. Will ask you one at a time if you want to delete items. Please A to delete all\n\n![image](https://user-images.githubusercontent.com/44196051/151830481-2de1dbcd-a4bf-43b6-a470-d13f7b366331.png)\n\n\n### copy multiple files to new location\n```powershell\ncopy-item \"C:\\windows\\System32\\winevt\\Logs\\Security.evtx\", \"C:\\windows\\System32\\winevt\\Logs\\Windows PowerShell.evtx\" -destination C:\\temp\n```\n\n### Grep in Powershell\n\nChange the string in the second line. You should run these one after another, as it will grep for things in unicode and then ascii. \n\nI like to use these as really lazy low-key yara rules. So grep for the string \"educational purposes only\" or something like that to catch malicious tooling - you'd be surprised how any vendors take open-source stuff, re-brand and compile it, and then sell it to you.....\n\n```powershell\nls C:\\Windows\\System32\\* -include '*.exe', '*.dll' | \nselect-string 'RunHTMLApplication' -Encoding unicode | \nselect-object -expandproperty path -unique\n\n#and with ascii\nls C:\\Windows\\System32\\* -include '*.exe', '*.dll' | \nselect-string 'RunHTMLApplication' -Encoding Ascii | \nselect-object -expandproperty path -unique\n```\n\n![image](https://user-images.githubusercontent.com/44196051/137937519-007d1d2a-b12d-4f76-acda-8eeb17f44f24.png)\n\n\n---\n\n## Registry Queries\n\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n\n  + [A note on HKCU](#A-note-on-HKCU)\n  + [Show reg keys](#show-reg-keys)\n  + [Read a reg entry](#read-a-reg-entry)\n  + [Quick useful reg keys](#quick-useful-reg-keys)\n  + [Remove a reg entry](#remove-a-reg-entry)\n    - [Removing HKCurrentUser Keys](#Removing-HKCurrentUser-Keys)\n  + [Example Malicious Reg](#example-malicious-reg)\n    - [Understanding Reg Permissions](#understanding-reg-permissions)\n    - [Get-ACl](#get-acl)\n    - [Convert SDDL](#convert-sddl)\n    - [What could they do with poor permissions?](#what-could-they-do-with-poor-permissions)\n  + [Hunting for Reg evil](#hunting-for-reg-evil)\n    - [Filtering Reg ImagePath](#filtering-reg-imagepath)\n  + [Query Background Activity Monitor](#query-background-activity-monitor)\n\n\n\u003c/details\u003e\n\n## A note on HKCU\n\nJust a note:\nAnywhere you see a reg key does HKCU - this is Current User. Your results will be limited to the user you are.\n\nTo see more results, you should change the above from HKCU, to HKU. \n\nYou often need the [SID of the users](https://www.windows-commandline.com/get-sid-of-user/) you want to go and look at their information.\n\nSo for example, a query like this:\n\n`HKCU:\\Control Panel\\Desktop\\`\n\nBecomes:\n\n`HKU\\s-1-12-1-707864876-1224890504-1467553947-2593736053\\Control Panel\\Desktop`\n\nHKU needs to be set up to work\n\n```powershell\nNew-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS;\n(Gci -Path HKU:\\).name\n```\n\u003cimg width=\"783\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/172839018-2575c3d3-3503-46c2-9ab5-a665f5723c07.png\"\u003e\n\n\n### Show reg keys\n\n[Microsoft Docs](https://docs.microsoft.com/en-us/troubleshoot/windows-server/performance/windows-registry-advanced-users) detail the regs: their full names, abbrevated names, and what their subkeys generally house \n\n```powershell\n##show all reg keys\n(Gci -Path Registry::).name\n\n# show HK users\nmount -PSProvider Registry -Name HKU -Root HKEY_USERS;(Gci -Path HKU:\\).name\n\n##lets take HKEY_CURRENT_USER as a subkey example. Let's see the entries in this subkey\n(Gci -Path HKCU:\\).name\n\n# If you want to absolutely fuck your life up, you can list the names recursively....will take forever though\n(Gci -Path HKCU:\\ -recurse).name\n```\n![image](https://user-images.githubusercontent.com/44196051/119998273-75768c80-bfc8-11eb-869a-807a140d7a52.png)\n\n### Read a reg entry\n```powershell\n Get-ItemProperty -Path \"HKLM:\\SYSTEM\\CurrentControlSet\\Services\\SysmonDrv\"\n```\n![image](https://user-images.githubusercontent.com/44196051/119994436-832a1300-bfc4-11eb-98cb-b4148413ac97.png)\n\n\n### Quick useful reg keys\n\nQuery timezone on an endpoint. Look for the TimeZoneKeyName value\n* `HKLM\\SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation`\n\nQuery the drives on the endpoint \n* `HKLM\\SYSTEM\\MountedDevices`\n\nQuery the services on this machine, and if you want to see more about one of the results just add it to the path\n* `HKLM\\SYSTEM\\CurrentControlSet\\Services`\n* `HKLM\\SYSTEM\\CurrentControlSet\\Services\\ACPI`\n\nQuery software on this machine\n* `HKLM\\Software`   \n* `HKLM\\Software\\PickOne`\n\nQuery SIDs \n* `HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList`\n* `HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\[Long-SID-Number-HERE]`\n\nQuery user's wallpaper. Once we know a user’s SID, we can go and look at these things: \n* `HKU\\S-1-5-18\\Control Panel\\Desktop\\`\n\nQuery if credentials on a machine are being [cached maliciously](https://blog.netwrix.com/2022/10/11/wdigest-clear-text-passwords-stealing-more-than-a-hash/)\n\n```powershell\n# can run this network-wide\nif ((Get-ItemProperty \"HKLM:\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest\").UseLogonCredential -eq 1){write-host \"Plain text credentials forced, likely malicious, on host: \" -nonewline ;hostname } else { echo \"/\" }\n\n#remediate the malice with this\nreg add \"HKLM\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest\" /v UseLogonCredential /t REG_DWORD /d 0\n```\n\n\u003cimg width=\"1406\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/202219578-b52631b8-b9a5-455f-989f-02ac959afc24.png\"\u003e\n\n\n### Remove a reg entry\nIf there's a malicious reg entry, you can remove it this way\n```powershell\n\n#Create HKU drive\nmount -PSProvider Registry -Name HKU -Root HKEY_USERS\n\n# Read the reg to make sure this is the bad boy you want\nget-itemproperty -Path 'HKU:\\*\\Keyboard Layout\\Preload\\'\n#remove it by piping it to remove-item\nget-itemproperty -Path 'HKU:\\*\\Keyboard Layout\\Preload\\' | Remove-Item -Force -Confirm:$false -verbose\n# double check it's gone by trying to re-read it\nget-itemproperty -Path 'HKU:\\*\\Keyboard Layout\\Preload\\'\n```\n![image](https://user-images.githubusercontent.com/44196051/119999624-d8b4ee80-bfc9-11eb-9770-5ec6e78f9714.png)\n\n#### Removing HKCurrentUser Keys\nIf a Registry is under `HKCU`, it's not clear exactly WHO it can belong to.\n\n![image](https://user-images.githubusercontent.com/44196051/154506473-a0a0fa55-7296-4b65-81af-7f0b0f3dcf7b.png)\n\nIf a Registry is under `HKCU`, you can figure out WHICH username it belongs to but you can't just go into HKCU in your PwSh to delete it....because YOU are the current user.\n\nInstead, get the [SID of the user](https://www.windows-commandline.com/get-sid-of-user/) \n\nAnd then you can traverse to that as the path as HKU. So for example, under User_Alfonso's reg keys\n\n```powershell\n#this\nHKCU:\\Software\\AppDataLow\\Software\\Microsoft\\FDBC3F8C-385A-37D8-2A81-EC5BFE45E0BF\n\n#must become this. Notice the reg changes in the field field, and the SID gets sandwiched in\nHKU:\\S-1-5-21-912369493-653634481-1866108234-1004\\Software\\AppDataLow\\Software\\Microsoft\\FDBC3F8C-385A-37D8-2A81-EC5BFE45E0BF\n```\n\nTo just generally convert them\n\n```powershell\n\nmount -PSProvider Registry -Name HKU -Root HKEY_USERS\n\n```\n\u003cimg width=\"679\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/172854420-0b2ae233-74f9-4fed-bd8b-84ef60827377.png\"\u003e\n\n### Understanding Reg Permissions\n\nReg permissions, and ACL and SDDL in general really, are a bit long to understand. But worth it, as adversaries like using the reg.\n\nAdversaries will look for registries with loose permissions, so let's show how we first can identify loose permissions\n\n#### Get-ACl\n\nThe Access Control List (ACL) considers the permissions associated with an object on a Windows machine. It's how the machine understands privileges, and who is allowed to do what.\n\nProblem is, if you get and `get-acl` for a particular object, it ain't a pretty thing\n\n```powershell\nGet-Acl -Path hklm:\\System\\CurrentControlSet\\services\\ | fl\n```\nThere's a lot going on here. Moreover, what the fuck is that SDDL string at the bottom? \n\nThe Security Descriptor Definition Language (SDDL) is a representation for ACL permissions, essentially\n\n![image](https://user-images.githubusercontent.com/44196051/120821264-378be200-c54d-11eb-8ca6-436393b3fb8e.png)\n\n#### Convert SDDL\nYou could figure out what the wacky ASCII chunks mean in SDDL....but I'd much rather convert the permissions to something human readable\n\nHere, an adversary is looking for a user they control to have permissions to maniptulate the service, likely they want *Full Control*\n```powershell\n$acl = Get-Acl -Path hklm:\\System\\CurrentControlSet\\services\\;\nConvertFrom-SddlString -Sddl $acl.Sddl | Foreach-Object {$_.DiscretionaryAcl[0]};\nConvertFrom-SddlString -Sddl $acl.Sddl -Type RegistryRights | Foreach-Object {$_.DiscretionaryAcl[0]}\n# bottom one specifices the  registry access rights when you create RegistrySecurity objects\n```\n![image](https://user-images.githubusercontent.com/44196051/120823443-58edcd80-c54f-11eb-850f-4f0049bcae95.png)\n\n\n#### What could they do with poor permissions?\n\nAn adversary in control of a loosely permissioned registry entry for a service, for example, could give themselves a privesc or persistence. For example:\n```powershell\n#don't actually run this\nSet-ItemProperty -path HKLM:\\System\\CurrentControlSet\\services\\example_service -name ImagePath -value \"C:\\temp\\evil.exe\"\n```\n### Hunting for Reg evil\n\nNow we know how reg entries are compromised, how can we search? \n\nThe below takes the services reg as an example, and searches for specifically just the reg-key Name and Image Path. \n \n```powershell\n\nGet-ItemProperty -Path \"HKLM:\\System\\CurrentControlSet\\services\\*\" | \nft PSChildName, ImagePath -autosize | out-string -width 800 \n\n#You can search recursively with this, kind of, if you use wildcards in the path names. Will take longer if you do recursively search though\nGet-ItemProperty -Path \"HKLM:\\System\\CurrentControlSet\\**\\*\" | \nft PSChildName, ImagePath -autosize | out-string -width 800 \n\n# This one-liner is over-engineered. # But it's a other way to be recursive if you start from a higher directory in reg\n# will take a while though\n$keys = Get-ChildItem -Path \"HKLM:\\System\\CurrentControlSet\\\" -recurse -force ;\n$Items = $Keys | Foreach-Object {Get-ItemProperty $_.PsPath };\nForEach ($Item in $Items) {\"{0,-35} {1,-10} \" -f $Item.PSChildName, $Item.ImagePath} \n```\n\n![image](https://user-images.githubusercontent.com/44196051/120918169-e560d300-c6aa-11eb-98a4-a9a27f264a0b.png)\n\n#### Filtering Reg ImagePath\n\nLet's continue to use the \\Services\\ reg as our example. \n\nRemember in the above example of a malicious reg, we saw the ImagePath had the value of C:\\temp\\evil.exe. And we're seeing a load of .sys here. So can we specifically just filter for .exes in the ImagePath. \n\nI have to mention, don't write .sys files off as harmless. Rootkits and bootkits weaponise .sys, for example.\n\nIf you see a suspicious file in reg, you can go and collect it and investigate it, or collect it's hash. When it comes to the ImagePath, \\SystemRoot\\ is usually C:\\Windows\\, but you can confirm with `$Env:systemroot` . \n\n```powershell\nGet-ItemProperty -Path \"HKLM:\\System\\CurrentControlSet\\services\\*\" | \nwhere ImagePath -like \"*.exe*\" | \nft PSChildName, ImagePath -autosize | out-string -width 800 \n\n# if you notice, on line two we wrap .exe in TWO in wildcards. Why? \n  # The first wildcard is to ensure we're kind of 'grepping' for a file that ends in a .exe. \n    # Without the first wildcard, we'd be looking for literal .exe\n  # The second wildcard is to ensure we're looking for the things that come after the .exe\n     # This is to make sure we aren't losing the flags and args of an executable\n\n# We can filter however we wish, so we can actively NOT look for .exes\nGet-ItemProperty -Path \"HKLM:\\System\\CurrentControlSet\\services\\*\" | \nwhere ImagePath -notlike \"*.exe*\" | \nft PSChildName, ImagePath -autosize | out-string -width 800 \n\n#fuck it, double stack your filters to not look for an exe or a sys...not sure why, but go for it!\nGet-ItemProperty -Path \"HKLM:\\System\\CurrentControlSet\\services\\*\" | \n? {($_.ImagePath -notlike \"*.exe*\" -and $_.Imagepath -notlike \"*.sys*\")} | \nft PSChildName, ImagePath -autosize | out-string -width 800 \n\n#If you don't care about Reg Entry name, and just want the ImagePath\n(Get-ItemProperty -Path \"HKLM:\\System\\CurrentControlSet\\services\\*\").ImagePath  \n\n```\n![image](https://user-images.githubusercontent.com/44196051/120833359-9bb4a300-c559-11eb-8647-69d990227dbb.png)\n\n### Query Background Activity Moderator\n\nBAM only in certain Windows 10 machines. Provides full path of the executabled last execution time\n\n```powershell\nreg query \"HKLM\\SYSTEM\\CurrentControlSet\\Services\\bam\\state\\UserSettings\" /s\n# or HKLM\\SYSTEM\\CurrentControlSet\\Services\\bam\\UserSettings\\\n```\n\nOR [BAMParser.ps1](https://github.com/mgreen27/Invoke-LiveResponse/blob/master/Content/Other/Get-BAMParser.ps1)\n\n\n\u003cimg width=\"1185\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/154823070-a7a06243-0744-413f-9d34-00fd3f5eb0c2.png\"\u003e\n\n\u003cimg width=\"1415\" alt=\"image\" src=\"https://user-images.githubusercontent.com/44196051/154823082-094ebdbc-5b20-47f2-87b7-479e371de566.png\"\u003e\n\n\n---\n\n\n## Driver Queries\n\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n  \n  + [Printer Drivers](#printer-drivers)\n  + [System Drivers](#system-drivers)\n    - [Unsigned](#unsigned)\n    - [Signed](#Signed)\n  + [Other Drivers](#other-drivers)\n  + [Drivers by Registry](#drivers-by-registry)\n  + [Drivers by Time](#drivers-by-time)\n \n\u003c/details\u003e\n\nDrivers are an interesting one. It isn't everyday you'll see malware sliding a malicious driver in ; bootkits and rootkits have been known to weaponise drivers. But it's well worth it, because it's an excellent method for persistence if an adversary can pull it off without blue-screening a machine. You can read more about it [here](https://eclypsium.com/wp-content/uploads/2019/11/Mother-of-All-Drivers.pdf)\n\nYou can utilise [Winbindex](https://winbindex.m417z.com) to investigate drivers, and compare a local copy you have with the indexed info. Malicious copies may have a hash that doesn't match, or a file size that doesn't quite match.\n\n![image](https://user-images.githubusercontent.com/44196051/121807617-d4850400-cc4c-11eb-9a47-8b3e18bfe48f.png)\n\n\n### Printer Drivers\n\n```powershell\nGet-PrinterDriver | fl Name, *path*, *file* \n```\n\n![image](https://user-images.githubusercontent.com/44196051/121266294-2545d700-c8b2-11eb-927e-45b81f6539e6.png)\n\n### System Drivers\n\nIf drivers are or aren't signed, don't use that as the differentiation for what is legit and not legit. Some legitimate drivers are not signed ; some malicious drivers sneak a signature. \n\n\n#### Unsigned\n\nGet unsigned drivers. Likely to not return much\n\n```powershell\ngci C:\\Windows\\*\\DriverStore\\FileRepository\\ -recurse -include *.inf|\nGet-AuthenticodeSignature | \n? Status -ne \"Valid\" | ft -autosize\n\ngci -path C:\\Windows\\System32\\drivers -include *.sys -recurse -ea SilentlyContinue | \nGet-AuthenticodeSignature | \n? Status -ne \"Valid\" | ft -autosize\n\n```\n\n#### Signed\n\nGet the signed ones. Will return a lot. \n\n```powershell\nGet-WmiObject Win32_PnPSignedDriver | \nfl DeviceName, FriendlyName, DriverProviderName, Manufacturer, InfName, IsSigned, DriverVersion\n\n# alternatives\ngci -path C:\\Windows\\System32\\drivers -include *.sys -recurse -ea SilentlyContinue | \nGet-AuthenticodeSignature | \n? Status -eq \"Valid\" | ft -autosize \n#or\ngci C:\\Windows\\*\\DriverStore\\FileRepository\\ -recurse -include *.inf|\nGet-AuthenticodeSignature | \n? Status -eq \"Valid\" | ft -autosize \n\n```\n\n![image](https://user-images.githubusercontent.com/44196051/121267019-6ee2f180-c8b3-11eb-83e9-d4f9218dfdaf.png)\n\n![image](https://user-images.githubusercontent.com/44196051/121755059-207d5f00-cb0e-11eb-82b0-8a90e13153ac.png)\n\n\n### Other Drivers \n\nGets all 3rd party drivers \n\n```powershell\nGet-WindowsDriver -Online -All | \nfl Driver, ProviderName, ClassName, ClassDescription, Date, OriginalFileName, DriverSignature \n```\n![image](https://user-images.githubusercontent.com/44196051/121268822-97b8b600-c8b6-11eb-87ba-787fa5dd4d92.png)\n\n\n### Drivers by Registry\n\nYou can also leverage the Registry to look at drivers\n```powershell\n#if you know the driver, you can just give the full path and wildcard the end if you aren't sure of full spelling\nget-itemproperty -path \"HKLM:\\System\\CurrentControlSet\\Services\\DBUtil*\" \n\n#You'll likely not know the path though, so just filter for drivers that have \\drivers\\ in their ImagePath\nget-itemproperty -path \"HKLM:\\System\\CurrentControlSet\\Services\\*\"  | \n? ImagePath -like \"*drivers*\" | \nfl ImagePath, DisplayName\n```\n(![image](https://user-images.githubusercontent.com/44196051/121329227-eb55ee80-c90c-11eb-808d-0e24fdfd2594.png)\n\n\n### Drivers by Time\n\nLook for the drivers that exist via directory diving.. We can focus on .INF and .SYS files, and sort by the time last written.\n\n```powershell\n#change to LastWriteTimeUtc if you need to.\n\n# first directory location\ngci C:\\Windows\\*\\DriverStore\\FileRepository\\ -recurse -include *.inf | \nsort-object LastWriteTime -Descending |\nft FullName,LastWriteTime | out-string -width 850\n\n# second driver location\ngci -path C:\\Windows\\System32\\drivers -include *.sys -recurse -ea SilentlyContinue | \nsort-object LastWriteTime -Descending |\nft FullName,LastWriteTime | out-string -width 850\n```\n\n![image](https://user-images.githubusercontent.com/44196051/121754106-acda5280-cb0b-11eb-9b5c-6c2195e17ef7.png)\n\n\n## DLL Queries\n\n\u003cdetails\u003e\n    \u003csummary\u003esection contents\u003c/summary\u003e\n  \n  + [DLLs used in Processes](#dlls-used-in-processes)\n    - [Investigate Process DLLs](#investigate-process-dlls)\n  + [Investigate DLLs](#investigate-dlls)\n    - [Generically](#generically)\n    - [Invalid](#invalid)\n    - [Specifically](#specifically)\n      - [Verify](#verify)\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpurp1ew0lf%2Fblue-team-notes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpurp1ew0lf%2Fblue-team-notes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpurp1ew0lf%2Fblue-team-notes/lists"}