Key Takeaways

  • Before running any penetration test against AWS infrastructure, confirm it's covered under AWS's Customer Support Policy for Penetration Testing — most EC2, RDS, and VPC-level testing is pre-authorized, but a few services (RDS DoS testing, DNS zone walking) still need explicit permission.
  • A thorough vpc check covers security groups, NACLs, route tables, VPC endpoints, flow logs, and peering/transit gateway attachments — not just open ports.
  • The most common finding in VPC assessments isn't a missing firewall rule — it's an overly permissive one (0.0.0.0/0 on a security group that should be scoped to a bastion or VPN CIDR).
  • VPC Flow Logs plus Amazon GuardDuty give you detection coverage that a point-in-time pentest can't — pentesting finds gaps, monitoring catches exploitation.
  • Findings should map to concrete remediation: tighten a security group, add a NACL deny rule, or move a resource behind a private subnet — not just a severity score.

Penetration testing an AWS VPC is different from testing traditional on-prem networks because so much of the "network" is actually policy — security groups, NACLs, and route tables defined in code rather than physical cabling. A vpc check done well combines traditional network testing techniques (port scanning, service enumeration) with a configuration review of exactly these policy layers, because a perfectly scanned-and-patched EC2 instance behind a security group open to the internet is still a serious finding.

Know AWS's Rules Before You Start

AWS permits customers to run penetration tests against their own resources without prior approval for most services — EC2, RDS, CloudFront, Lambda, Lightsail, Elastic Beanstalk, and API Gateway are explicitly covered. A few activities still require submitting a request through AWS Support first:

  • Protocol-level DDoS simulation or load testing beyond normal traffic patterns.
  • DNS zone walking against Route 53.
  • Any test targeting another AWS customer's resources (obviously).

Always test against resources you own, in an account you control, and keep records of your authorization scope — especially if you're a consultant testing on behalf of a client.

The VPC Security Layers to Check

<svg viewBox="0 0 640 260" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Layered VPC security controls from internet gateway down to instance security group">
  <style>
    .layer { fill: none; stroke: currentColor; stroke-width: 1.5; }
    .lbl { fill: currentColor; font-family: sans-serif; font-size: 12px; }
  </style>
  <rect class="layer" x="20" y="10" width="600" height="40"/>
  <text class="lbl" x="35" y="35">Internet Gateway / Route 53</text>
  <rect class="layer" x="20" y="60" width="600" height="40"/>
  <text class="lbl" x="35" y="85">Network ACLs (subnet-level, stateless)</text>
  <rect class="layer" x="20" y="110" width="600" height="40"/>
  <text class="lbl" x="35" y="135">Route tables (public vs. private subnet routing)</text>
  <rect class="layer" x="20" y="160" width="600" height="40"/>
  <text class="lbl" x="35" y="185">Security groups (instance/ENI-level, stateful)</text>
  <rect class="layer" x="20" y="210" width="600" height="40"/>
  <text class="lbl" x="35" y="235">VPC Flow Logs + GuardDuty (detection layer)</text>
</svg>

Each layer fails differently. NACLs are stateless, so a rule allowing inbound traffic needs a matching outbound rule — a frequent misconfiguration. Security groups are stateful, so return traffic is automatically allowed, but an overly broad inbound rule still exposes the resource directly.

Enumerating Security Group Exposure

Start a VPC check by listing every security group with a rule that's wide open:

aws ec2 describe-security-groups \
  --filters Name=ip-permission.cidr,Values=0.0.0.0/0 \
  --query 'SecurityGroups[].[GroupId,GroupName,IpPermissions[].FromPort]' \
  --output table

Cross-reference the results against what's actually attached to resources:

aws ec2 describe-network-interfaces \
  --filters Name=group-id,Values=sg-0123456789abcdef0 \
  --query 'NetworkInterfaces[].[NetworkInterfaceId,PrivateIpAddress,Attachment.InstanceId]'

A security group with 0.0.0.0/0 on port 22 or 3389 attached to a production instance is a near-automatic critical finding — SSH and RDP should go through a bastion, Session Manager, or VPN, never directly from the internet.

Checking Route Tables and Subnet Isolation

A VPC check should confirm that subnets intended to be "private" don't actually have a route to an internet gateway:

aws ec2 describe-route-tables \
  --filters Name=association.subnet-id,Values=subnet-0abc123def456 \
  --query 'RouteTables[].Routes[?GatewayId!=`local`]'

If this returns a route to an igw-* gateway for a subnet you believe is private, resources there have direct internet egress — a common gap that undermines network segmentation assumptions baked into the rest of the architecture.

Using VPC Endpoints to Reduce Attack Surface

Resources in private subnets that need to reach S3 or DynamoDB often get a NAT Gateway route to the internet just for that — unnecessarily widening the attack surface. VPC endpoints remove that need entirely:

aws ec2 create-vpc-endpoint \
  --vpc-id vpc-0123456789abcdef0 \
  --service-name com.amazonaws.us-east-1.s3 \
  --route-table-ids rtb-0abc123def456 \
  --vpc-endpoint-type Gateway

Traffic to S3 now stays on the AWS network backbone instead of routing through a NAT gateway and the public internet path, closing off a class of exfiltration and interception risk.

Enabling Detection Alongside Testing

A pentest is a point-in-time snapshot. Pair it with always-on detection:

aws guardduty create-detector --enable
aws ec2 create-flow-logs \
  --resource-type VPC \
  --resource-ids vpc-0123456789abcdef0 \
  --traffic-type ALL \
  --log-destination-type cloud-watch-logs \
  --log-group-name /vpc/flow-logs

GuardDuty flags anomalous network behavior (port scanning, command-and-control traffic patterns, crypto-mining signatures) using VPC Flow Logs, DNS logs, and CloudTrail — findings a manual pentest scoped to a two-week engagement will never surface on its own.

Turning Findings Into Fixes

FindingRemediation
Security group allows 0.0.0.0/0 on admin portsRestrict to bastion/VPN CIDR or replace with Session Manager
"Private" subnet has IGW routeRemove IGW route; use NAT Gateway or VPC endpoint for egress
No VPC Flow Logs enabledEnable flow logs to CloudWatch Logs or S3 for all VPCs
Overly broad NACL rulesScope NACL rules to known CIDR ranges per subnet tier
Cross-account VPC peering with no route restrictionLimit peering routes to only the required CIDR ranges and ports

FAQ

Do I need AWS's permission before pentesting my own VPC? For most services (EC2, RDS, Lambda, API Gateway), no — AWS pre-authorizes testing against your own resources under its Customer Support Policy for Penetration Testing. A few activities, like DDoS simulation, still require a support request.

What's the difference between a security group and a NACL in a VPC check? Security groups are stateful and attach to instances/ENIs; NACLs are stateless and attach to subnets, meaning NACL rules need explicit inbound and outbound entries. A VPC check reviews both, since either can cause an exposure the other doesn't catch.

Can VPC Flow Logs replace a penetration test? No — they're complementary. Flow logs and GuardDuty give you ongoing detection; a pentest actively probes for exploitable misconfigurations that haven't yet been triggered or logged.

What's the most common finding in AWS VPC assessments? Overly permissive security group rules — most often 0.0.0.0/0 on administrative ports (22, 3389) or application ports that should be restricted to internal CIDR ranges or a load balancer's security group.

Get an Authorized VPC Security Assessment

f9infotech runs AWS-compliant VPC penetration tests and configuration reviews — security groups, NACLs, route tables, and flow log coverage — with clear, actionable remediation steps. Request a VPC security assessment to find the gaps before someone else does.