Skip to content

Commit

Permalink
added attach/detach remove crowdstrike firmware logic for AZURE
Browse files Browse the repository at this point in the history
Signed-off-by: Rahul Jadhav <[email protected]>
  • Loading branch information
nyrahul committed Jul 22, 2024
1 parent 141e39b commit f447ae7
Show file tree
Hide file tree
Showing 6 changed files with 293 additions and 42 deletions.
6 changes: 5 additions & 1 deletion crowdstrike-bsod-fix/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ python3 main.py --csp aws --instances i-0314fe10fbb79efd1,i-0214ae20ecc98e5d2
### Prerequisites
1. Download and install [az cli](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli-linux)
1. Configure `az login` such that it points to the right account/subscription
1. Install jq

### Using Azure
```bash
python3 main.py --csp azure --instances instance1,inst2 --az_res_grp "myResourceGroup"
python3 main.py --csp azure \
--instances instance_name1,inst2 \
--resource-group myResourceGroup \
--subscription-id 9af872e2-xxxx-yyyy-zzzz-7edf106007b4
```
41 changes: 41 additions & 0 deletions crowdstrike-bsod-fix/commonutil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2024 AccuKnox
# Copyright 2024 XCitium

import subprocess
import os
import glob
import time

# Function to get the device name
def get_dev_name():
res = subprocess.run(["fdisk -l"], capture_output=True, shell=True).stdout.decode()
for line in res.splitlines():
if "NTFS" in line:
device_name = line.split(" ")[0]
return device_name
return ""

# Function to remove the file
def remove_cs_file(mount_point):
file_pattern = f"{mount_point}/Windows/System32/drivers/CrowdStrike/C-00000291*.sys"
for file in glob.glob(file_pattern):
os.remove(file)

def mount_rem_cs_file(args):
mntpt = os.getcwd() + "/windows"
os.makedirs(mntpt, exist_ok=True)
log.info(f"mount directory {mntpt}")

devname=""
for retry in range(20):
devname=commonutil.get_dev_name()
if devname:
break
time.sleep(1)
if not args.dry_run:
subprocess.run(
["mount", devname, mntpt], capture_output=True
)
remove_cs_file(mntpt)
subprocess.run(["umount", mntpt], capture_output=True)
36 changes: 2 additions & 34 deletions crowdstrike-bsod-fix/csp_aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@
# Copyright 2024 XCitium

import logging
import time
import boto3
import subprocess
import os
import glob
import commonutil

logging.basicConfig(level=logging.INFO)
log = logging.getLogger("aws")
Expand Down Expand Up @@ -57,21 +54,6 @@ def detach_vol(ec2, vid, dry_run=False):
if "DryRunOperation" not in str(e):
log.error(f"Failed to detach volume {vid}: {e}")

# Function to get the device name
def get_dev_name():
res = subprocess.run(["fdisk -l"], capture_output=True, shell=True).stdout.decode()
for line in res.splitlines():
if "NTFS" in line:
device_name = line.split(" ")[0]
return device_name
return ""

# Function to remove the file
def remove_cs_file(mount_point):
file_pattern = f"{mount_point}/Windows/System32/drivers/CrowdStrike/C-00000291*.sys"
for file in glob.glob(file_pattern):
os.remove(file)

# Function to start an instance
def start_instance(ec2, inst_id, dry_run=False):
try:
Expand All @@ -95,9 +77,6 @@ def stop_instance(ec2, inst_id, dry_run=False):
def handle_aws(args):
log.info(f"called {args.csp}")
instances=args.instances.split(",")
mntpt = os.getcwd() + "/windows"
os.makedirs(mntpt, exist_ok=True)
log.info(f"mount directory {mntpt}")
ec2 = boto3.client('ec2')
# response = ec2.describe_instances()
# print(response)
Expand All @@ -119,19 +98,8 @@ def handle_aws(args):
log.error(f"attach vol failed {vid}: {err}")
continue

devname=""
try:
for retry in range(20):
devname=get_dev_name()
if devname:
break
time.sleep(1)
if not args.dry_run:
subprocess.run(
["mount", devname, mntpt], capture_output=True
)
remove_cs_file(mntpt)
subprocess.run(["umount", mntpt], capture_output=True)
commonutil.mount_rem_cs_file(args)
finally:
detach_vol(ec2, vid, dry_run=args.dry_run)
attach_vol(ec2, inst_id, vid, dev, dry_run=args.dry_run)
Expand Down
69 changes: 64 additions & 5 deletions crowdstrike-bsod-fix/csp_azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,70 @@
import logging
from azure.identity import DefaultAzureCredential
from azure.mgmt.compute import ComputeManagementClient
import subprocess
import os
import commonutil

logging.basicConfig(level=logging.INFO)
log = logging.getLogger("azure")

def detach_vol(client, args, inst_id):
def detach_vol(client, args, inst_id, disk_id):
response = client.virtual_machines.begin_attach_detach_data_disks(
resource_group_name=resgrp,
resource_group_name=args.resource_group,
vm_name=inst_id,
parameters={
"dataDisksToDetach": [
{
"detachOption": "ForceDetach",
"diskId": f"/subscriptions/{args.subscription_id}/resourceGroups/{args.resource_group}/providers/Microsoft.Compute/disks/rahulwinmachine-deleteby24July_disk1_1b82042a4eed45adbb41b61d9d942656",
"diskId": disk_id,
},
],
},
).result()
print(response)
return

def attach_vol(client, args, inst_id, disk_id):
response = client.virtual_machines.begin_attach_detach_data_disks(
resource_group_name=args.resource_group,
vm_name=inst_id,
parameters={
"dataDisksToAttach": [
{
"caching": "ReadWrite",
"deleteOption": "Detach",
"diskEncryptionSet": {
"id": "/subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/diskEncryptionSets/{existing-diskEncryptionSet-name}"
},
"diskId": disk_id,
"lun": 1,
"writeAcceleratorEnabled": True,
},
],
},
).result()
print(response)
return

def get_dev_name():
res = subprocess.run(["fdisk -l"], capture_output=True, shell=True).stdout.decode()
for line in res.splitlines():
if "NTFS" in line:
device_name = line.split(" ")[0]
return device_name
return ""

def check_disk(client, args, inst_id, line):
try:
resp = detach_vol(client, args, inst_id, line)
print(resp)
commonutil.mount_rem_cs_file(args)
resp = attach_vol(client, args, inst_id, line)
print(resp)
except Exception as e:
log.error(f"failed to detach/attach disk {inst_id}: {e}")
return

def handle_azure(args):
if not args.resource_group:
log.error("needs --resource-group <group> to be specified")
Expand All @@ -50,8 +95,22 @@ def handle_azure(args):
print(response)
log.info(f"found the azure vm [{inst_id}]")

client.virtual_machines.begin_start(
resource_group_name=args.resource_group,
vm_name=inst_id,
).result()

res = subprocess.run(["az vm list | jq -r .[].storageProfile.dataDisks[].managedDisk.id"],
capture_output=True, shell=True).stdout.decode()
print(res)
for line in res.splitlines():
if "/subscriptions/" in line:
check_disk(client, args, inst_id, line)

client.virtual_machines.begin_start(
resource_group_name=args.resource_group,
vm_name=inst_id,
).result()
except Exception as err:
log.error(f"instance get failed {inst_id}: {err}")
continue

resp = detach_vol(client, args, inst_id)
3 changes: 1 addition & 2 deletions crowdstrike-bsod-fix/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
boto3==1.34.145
azure-mgmt-resource
azure-identity
azure-mgmt-compute
azure-mgmt-storage
azure-mgmt-compute
Loading

0 comments on commit f447ae7

Please sign in to comment.