Archive for category Security
Ahh-My-API : Discover publically exposed APIs in AWS
Posted by Ashish Gupta in AWS, Security on February 21, 2023

TL;DR;
The REST API gateways created in AWS have a default endpoint [https://{api_id}.execute-api.{region}.amazonaws.com] and If not explicitly secured, they are publically accessible from internet by default. Wrote a script which would find such APIs across all regions under all the AWS accounts in the AWS organizations and takes screenshot their webpage for evidence. It will also generate a CSV file which may be ingested by a SIEM such as Splunk for alerting and remediation.
https://github.com/ashishmgupta/ah-my-api
The script when executed will produce a CSV file in the below format showing all the API URLs and which one could be publically accessible and which security setting are applied on the API if API is not accessible.

It is important to discover and actually test the endpoints from an external environment to reduce the false positives for detection becuase APIs can be secured by various means (described below)
Most common ways to secure AWS Rest APIs
- API Token e.g. Check for specific token value in the pre-defined x-api-header.
- Lambda Authorizers e.g. Custom lamda code to check for specific headers/secrets before allowing access.
- Resource policies e.g. Allow access from certain IP addresses and deny others.
- Authentication/Authorization from with in the backend code (e.g. Lambda).
How to use the script
We follow below two steps :
- Set up an IAM user with approperiate permissions in the management account to assume a given role in the other accounts.
- Set up the role to assume in all the workload accounts using CloudFormation and StackSets.
The script makes use of Access Key on the IAM user “boto3user” in the management account.
boto3user has the permission to assume role in the workload account and get temporary credentials to access the API gateways in the workload accounts. Diagram below :

In my AWS organizations, I have 3 AWS accounts out of which “Account 1” is the management account.

Setting up the IAM user and permissions in the management account
Create a IAM user named boto3user.
Create an access key and secret for the IAM user.
Create a policy with below and assosciate it with the IAM user.
ScanAWSAPIPolicy
This allows the user to assume the role named ScanAWSAPIRole in all the AWS accounts in the AWS organization.
Since the script will iterate through the AWS organizations as well, we provide the ListAccounts and DescribeAccount permission as well.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"organizations:ListAccounts",
"organizations:DescribeAccount"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::*:role/ReadOnlyAPIGatewayAssumeRole"
}
]
}

Create the role to assume in the other accounts
We will use a CloudFormation template for the role to be created and Stackset to deploy the template across all the AWS accounts in the AWS organization.
- Download the CloudFormation template from here and save it locally :
https://github.com/ashishmgupta/ah-my-api/blob/main/CloudFormation_Template_For_Role_and_Policy.yaml - On the management account, navigate to CloudFormation > StackSets > Create StackSet

3. In the “Specify template” section, choose “Upload a template file” and browse to select the previously saved CloudFormation template

4. Specify a name for the StackSet and optional description.

5. In the deployment options screen, set the deployment target as “Deploy to Organization”
and specify US East as the region.


6. In the review screen, acknowledge and submit.

StackSet has been deployed with success.

Verify the role has been created across all the accounts
We can see the role “ReadOnlyAPIgatewayAssumeRole” has been created in the AWS accounts.
The “Trusted entities” is the AWS Account number of the management account which is trusted to assume the “ReadOnlyAPIgatewayAssumeRole” role.

If we look at the role, we see the Policy named “ReadOnlyAPIGatewayPolicy” is attached to it with GET/HEAD operations on apigateway just like we specified in the CloudFormation template.

when we look at the “Trusted Entities”, we notice the IAM user named “boto3user” in the management account.
This means It is this user which has the permission to assume the “ReadOnlyAPIgatewayAssumeRole” role in all the AWS accounts and call the API gateway GET/HEAD operation.

Running the script
Setup the AWS credentials
aws configure
Clone the git repo
https://github.com/ashishmgupta/ah-my-api.git
Install all the requirements
pip install -r requirements
Run the script
python .\ah-my-api.py
Microsoft 365 Security Implementation
Posted by Ashish Gupta in O365 security, Security on May 19, 2022
Below are the concrete steps we can take to secure Microsoft O365 tenants.
Microsoft O365 Security Implementation (ashishmgupta.github.io)
(This will be a living document and will be updated as new features are published)
This includes below :
Azure Policy – Deny creation of virtual machines without IP restriction across all Azure subscriptions
Posted by Ashish Gupta in Azure, Security on December 2, 2020
TLDR;
Public Azure virtual machines without any IP restriction is always an attack vector which may result in compromise of the VM and further lateral movement in Azure infrastructure.
Azure policy may be used to deny any attempt to even create the virtual machines without IP restriction.
This blog post has step-by-step process on how to implement an Azure policy on ALL your subscriptions covering IP restriction for ALL your future virtual machines.
What is Azure policy:
Azure policy is a service inside Azure that allows configuration management.It executes every time a new resource is added or an existing resource is changed. It has a set of rules, and set of actions. The Azure policy could report the event as non-compliant or even deny the action altogether if the rules are not matched.
Azure policy is an excellent way to enforce and bake-in security and compliance in the Azure infrastructure.
As you see in the below picture, Azure policy is an integral part of Azure Governance – mainly consisting of Policy Definitions and Policy Engine which works directly with Azure Resource Manager (ARM).
Image source : https://www.microsoft.com/en-us/us-partner-blog/2019/07/24/azure-governance/
Summary:
If the Azure virtual machines need to be accessible over internet, Its important to restrict access its access ONLY from your corporate public IP addresses.
This will help in couple of situations :
a) Limit external access from an attacker.
b) Limit Insider threat or misuse from an employee.
The IP address restriction could be created while creating the virtual machine using network security groups.
However, enforcing this on the policy level by the administrator would ensure we are not dependent on individual team’s best judgment.
Process:
As a best practice, always test the policy in audit mode before switching to deny mode. In this walkthrough, we will follow below steps :
1) Create the policy definition.
2) Apply the policy (Policy Assignment) in audit mode
3) Test with Audit mode
3) Apply the policy (Policy Assignment) in deny mode
4) Test with Deny mode
Create the policy definition
On the search bar, search for “policy” and click on it.
Click Definitions and then click Policy Definition
Click the … button under “Definition Location” to select the management group. If you want to apply this policy to all subscriptions, don’t select any subscription.
To apply this policy to a specific subscription, select the desired subscription under the subscription dropdown.
Policy Details:
Name:
Deny creation of virtual machine without access restricted only from company’s public IP addresses
(on-prem/VPN)
Description (Change the IP address list below):
Deny creation of virtual machine which does not have external company IP addresses restriction in the network security group.
One or more of the below corporate IP addresses must be specified in the network security group when creating the virtual machine. Otherwise, the validation will fail and the virtual machine will not be created.
Below is the valid public corporate IP addresses list :
208.114.51.253
104.104.51.253
108.104.51.253
Category : Network
Policy Rule:
{ "mode": "All", "policyRule": { "if": { "allOf": [ { "field": "type", "equals": "Microsoft.Network/networkSecurityGroups" }, { "count": { "field": "Microsoft.Network/networkSecurityGroups/securityRules[*]", "where": { "allOf": [ { "anyof": [ { "field": "Microsoft.Network/networkSecurityGroups/securityRules[*].sourceAddressPrefix", "notIn": [ "208.114.51.253", "104.104.51.253", "108.104.51.253" ] } ] } ] } }, "greater": 0 } ] }, "then": { "effect": "[parameters('effect')]" } }, "parameters": { "effect": { "type": "String", "metadata": { "displayName": "Effect", "description": "The effect determines what happens when the policy rule is evaluated to match" }, "allowedValues": [ "audit", "deny" ], "defaultValue": "audit" } } }
Policy Assignment
Under policy > definition, go to the newly created policy definition.
Click Assign.
Provide an assignment name and description
Name:
Deny creation of virtual machine without access restricted only from company’s public IP addresses
(on-prem/VPN)
Description (Change the IP address list below):
Deny creation of virtual machine which does not have external company IP addresses restriction in the network
security group.
One or more of the below corporate IP addresses must be specified in the network security group when creating the virtual machine. Otherwise, the validation will fail and the virtual machine will not be created.
Below is the valid public corporate IP addresses list :
208.114.51.253
104.104.51.253
108.104.51.253
Under “Parameters” tab, select “audit” in the Effect dropdown and click “Review+Create”
On the review page, click “Create” .
The policy assignment is created. Please note It takes about 30 minutes to take effect.
Test 1 – Audit mode :
Create virtual machine with RDP allowed from any external IP Address
With the policy in Audit mode, let us create a new virtual machine with RDP open to any external IP address.
When the policy is in the audit mode, the virtual machine creation is successful but Azure policy adds a Microsoft.Authorization/policies/audit/action
operation to the activity log and marks the resource as non-compliant.
Compliance State:
Policy > Compliance
Test 2 – Deny mode
Create virtual machine with RDP allowed from any external IP Address
We need to change the effect mode to “deny” in our policy assignment.
Head over to Policy > Assignments > Click on the policy we created
Click “Parameters” tab. Select “deny” from the dropdown and continue to save the policy assignment.
Attempt to create a virtual machine with the same settings as we did before.
When you proceed to create the virtual machine, the final validation will fail with an error message (left side) which when clicked will show which policy disallowed this action.
Clicking on the policy would show the policy assignment with details showing why the policy disallowed this action.
When the policy is in the deny mode, the virtual machine creation is successful but Azure policy adds a Microsoft.Authorization/policies/deny/action
operation to the activity log and marks the resource as non-compliant.
Under activity logs, you can see the deny action.:
Summary :
Azure policy is an excellent way of enforcing compliance in Azure infrastructure. In this blog post we saw how we can apply Azure policy to deny creation of virtual machines without any IP restriction.
For further readings :
Azure policy docs : https://docs.microsoft.com/en-us/azure/governance/policy/overview
Azure policy Github : https://github.com/Azure/azure-policy
Azure Sentinel – Detecting brute force RDP attempts
Posted by Ashish Gupta in Azure, Security on June 5, 2019
Azure Sentinel is a cloud based SIEM* and SOAR** solution.
As it’s still in preview, I wanted to test out few of Its capabilities.
In this post we will see how we can detect RDP brute-force attempts and respond using automated playbooks in Azure Sentinel.
[*SIEM : Security Incident Event Management]
[**SOAR : Security Orchestration Automated Response]
https://docs.microsoft.com/en-us/azure/sentinel/overview
The infrastructure:
I have couple of virtual machines in Azure which have RDP opened (sure, I am the first one to keep that opened) 🙂 Below is one of the Win 2012 machine.
The Attack:
Attackers always the scan the whole CIDR to find the services running on the machines in the range. In this example, simulating the scan, I will use only one machine ( the above one) from the Kali VM looking if the RDP (port 3389) is opened.
nmap -p 3389 IPAddress –Pn
For brute-force, we will use crowbar.
Clone the repository:
git clone https://github.com/galkan/crowbar.git
I have separate files for usernames(userlist) and passwords(passwordlist) which will be used by Crowbar in combination to attempt to login to the above machine via RDP.
python crowbar.py -b rdp -s ipaddress -U userlist -C passwordlist –v
-b indicates target service. In this case Its rdp but crowbar also supports openvpn, sskkey and vnckey.
-v indicates verbose output
You see the combination which has “RDP-SUCCESS” is the right combination of user name and password which was brute-forced for successful login via RDP. Other attempts failed. Of course, I have the right user name and password in the file. 🙂
Azure Sentinel
Now lets get to Azure Sentinel. As noted above, Its a cloud based SIEM.
You can quickly locate “Azure Sentinel” from the search bar.
Sentinel manages all Its data in a log analytics workspace. If you already have one, you can reuse or create a new one.
One of the first thing you notice in Azure Sentinel is a number of in-built Data Connectors available to collect data from different sources. Not only that includes Azure native data sources such as Azure AD, Office 365, Security center to name a few but also third parties like Palo Alto, Cisco ASA, Checkpoint, Fortinet and F5.
Pretty sure the list will only get longer.
For the purpose of this blog post, we will focus on the “Security Events” by clicking on “Configure”.
Select “All events”.
Click on “Download install Agent for Windows Virtual machines”.
Select the Virtual machine where the agent will be installed.
Click “Connect”.
The “Connect” process takes few minutes to complete.
When the machine is shows “Connected” in Azure portal, you will see the Microsoft Monitoring Agent (MMA) service running on the machine which will upload the logs to the Azure sentinel workspace for the subscription.
Start writing some queries
Azure Sentinel uses Kusto Query Language for read-only requests to process data and return results.
In the sentinel workspace, click on “Logs” and use the below query which is basically looking for security events with successful login event (EventId 4624) and unsuccessful login event (EventId 4625) originating from a workstation named “kali”.
Note the highlighted event was the only successful attempt(EventId 4624) and rest were failures (4525).
SecurityEvent
| where (EventID == 4625 or EventID== 4624) and WorkstationName == “kali”
| project TimeGenerated, EventID , WorkstationName,Computer, Account , LogonTypeName , IpAddress
| order by TimeGenerated desc
Creating Alerts
Create an alert for the above use case by clicking “Analytics” > Add
Give a name to the alert, provide a description. and set the severity.
Set the alert query to detect any RDP login failure:
SecurityEvent
| where EventID == 4625
| project TimeGenerated, WorkstationName,Computer, Account , LogonTypeName , IpAddress
| order by TimeGenerated desc
Set the entity mapping. These properties will be populated from the projected fields in the query above.
Will be very useful information when we build playbooks. As you can see, there are only three properties which could be mapped at this point but more to come.
In this example, Account Name used for the attempted login, the host where It is being tried on and the workstation where It is tried from will be populated.
Playbook
Playbooks in Azure Sentinel are basically Logic apps which is really powerful not only because of the inbuilt templates but also because they can be heavily customized.
Sorry, I just wanted to remind myself again and you, dear reader that logic apps are really powerful. 🙂
Create the logic app:
In the designer, click on “Blank Logic App”
We first need to define the trigger. In this case It would be when the response to an alert is triggered in Azure Sentinel.
Search “Sentinel” in the textbox and you will find the trigger. Click on the trigger and the trigger will be added as a first step.
We will send an email to respective team (e.g. Security Operations) when this event happens. In this case I am sending the email to my Office 365 email address.
You will need an Office 365 tenant(sign up for free trial here) to send email.
In the below example, I already one and connected. If I didn’t, all I had to do is to sign-in with my admin office-365 account and connection would be available to send emails.
As you click through the subject and body, you will be prompted to select the Dynamic contents which will have relevant data in this case.
Cases
When an alert fires, I creates a case and you can execute the relevant playbook for the case.
In this example, we have a alert configured named “rdp-bruce-force attempt-alert”.
Every time that alert fires, I will create a new case with the same name as the alert with a case Id.
We can then execute the relevant playbook on the case. In this example, we will execute the playbook we created before “rdp-bruce-force attempt-alert-playbook”.
In the Sentinel workspace, click on “Cases” to review all the cases and click on the case which got created for the brute-force attempt.
At the bottom the details pane of the case, click on the “View full details”.
Click “View Playbooks”
Click on “Run” for the playbook we want to execute.
Below is the email as a part of the playbook I got with the account names in the security event logs.
Hope this helps! 🙂