cybersecurity · intermediate · ~15 min · safe pentest lab

Flag High-Risk Exposed Ports

Practice deny-by-default allow/deny classification against a fixed lookup table, and bounds-checking attacker-controlled numeric input before use so out-of-range or malicious values are rejected rather than trusted.

Challenge

Risky exposed ports

During an external attack-surface review, you scan a host and get back a list of open TCP ports. Some services should almost never face the public internet: exposing them invites credential brute-force, unauthenticated data theft, and remote takeover. Your triage tool must flag these so an analyst can investigate first.

The insecure assumption to avoid: trusting the port value blindly and using it as an array index, or treating "not benign" as "safe". A hostile scanner (or a corrupted result row) can hand you a negative number, a value above 65535, or a near-miss like 20 vs 21. You must deny by default and match only against a fixed, known list.

Task

Implement int is_risky_exposed_port(int port). Return 1 if port is one of the commonly high-risk services to flag when exposed (21 FTP, 23 Telnet, 445 SMB, 3389 RDP, 3306 MySQL, 5432 Postgres, 6379 Redis, 9200 Elasticsearch, 27017 Mongo), otherwise return 0. The list is fixed and baked into your function. Never touch a live target, socket, or file.

Edge cases

  • Negative ports and ports above 65535 must return 0, never crash.
  • Near-misses (20, 446, 3388) are not on the list and must return 0.
  • Benign common ports (22, 80, 443) return 0.

Example

is_risky_exposed_port(3389) -> 1 (RDP) is_risky_exposed_port(443) -> 0 (HTTPS, not on the risky list)

Input format

A single int port, the TCP port number under review. May be any int value, including negative or out-of-range.

Output format

Return int 1 if port is on the fixed high-risk list, otherwise 0.

Constraints

C11, freestanding function logic only. No network, socket, filesystem, or dynamic allocation. The risky list is fixed inside the function. Reject any port outside 0..65535 by returning 0. Do not use port as an array index.

Starter code

int is_risky_exposed_port(int port){
    /* TODO: implement the fixed-list check. Stub returns -1 and is insecure. */
    (void)port;
    return -1;
}

Common mistakes

Using port directly as an array or bit-set index without a range check (out-of-bounds read on hostile input); treating any non-benign port as risky instead of matching the explicit list; returning a non-normalized value (e.g. the loop counter) instead of exactly 1 or 0; forgetting the negative / above-65535 rejection; off-by-one near-miss ports slipping through.

Edge cases to handle

port < 0 (return 0); port > 65535 (return 0); INT_MIN (return 0, no overflow); 0 and 65535 boundaries (not on list, return 0); near-misses like 20, 446, 3388 (return 0); benign ports 22/80/443 (return 0); every exact list member (return 1).

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.