CTF: Secure Coding
6 challenges — Week 5-8
Secure Coding Challenges
| 6 challenges | Week 5-8 | Weeks 5-8 (Cross-cutting: Strings, Memory, Structs) |
Security-focused challenges covering buffer overflow identification, gets-to-fgets migration, input validation with strtol, format string vulnerability awareness, secure memory handling (zeroing before free), and compiler security flags. These exercises weave secure coding practices into existing C programming topics from Weeks 5-8, supporting ABET security coverage requirements and NCAE-CD Software Security and NCAE-CO Low Level Programming knowledge units.
Difficulty Breakdown
| Level | Count |
|---|---|
| Beginner | 2 |
| Intermediate | 4 |
Challenges
1. Buffer Overflow Identification
| Difficulty: Intermediate | Time: ~12 min | Type: bare code |
Each of the following three code snippets contains a buffer overflow vulnerability. For each snippet: (1) identify the exact line that causes the overflow, (2) classify the vulnerability using its CWE identifier, (3) explain the danger in a real-world context, and (4) provide a corrected version …
Concepts: buffer overflow via strcpy, inherently dangerous functions (gets), buffer overflow via sprintf, CWE classification of vulnerabilities, bounds-checked alternatives: strncpy, fgets, snprintf
2. Gets To Fgets Migration
| Difficulty: Beginner | Time: ~8 min | Type: bare code |
The following program uses gets() in three places to read user input. Refactor the entire program to use fgets() safely. Your refactored code must: (1) pass the correct buffer size to fgets, (2) strip the trailing newline that fgets includes, (3) check the return value of fgets for NULL (indicati…
Concepts: gets() removal from C11 standard, fgets() with correct buffer size parameter, newline stripping after fgets, NULL return check on fgets, historical context: Morris Worm (1988)
3. Input Validation
| Difficulty: Intermediate | Time: ~15 min | Type: function |
Write a function safe_read_int that safely reads an integer from stdin. The function must:
- Print a prompt message passed as a parameter.
- Read input using fgets (NOT scanf).
- Validate that the input is a valid integer using strtol.
- Handle invalid input gracefully by printing an error a…
Concepts: input validation with fgets + strtol, strtol endptr check for partial/invalid input, errno check for overflow detection, retry loop for invalid input, defensive programming against malformed input
4. Format String Awareness
| Difficulty: Intermediate | Time: ~10 min | Type: bare code |
Trace the behavior of the following two code fragments and explain why they produce different results when the user enters “%x %x %x %x” as input.
Fragment A (VULNERABLE): char input[100]; fgets(input, 100, stdin); printf(input); /* user input used as format string */
Fragment B (SAFE): char i…
Concepts: format string vulnerability (CWE-134), printf format string as a control mechanism, %x for reading stack data (information leak), %n for writing to memory (arbitrary write primitive), the fix: always use printf(“%s”, str) instead of printf(str)
5. Secure Memory Handling
| Difficulty: Intermediate | Time: ~12 min | Type: function |
Write a function secure_free that securely deallocates sensitive memory. The function must:
- Zero out the memory before freeing it (prevents data remanence).
- Free the memory.
- Set the caller’s pointer to NULL (prevents use-after-free).
Scenario: You are writing a program that stores a us…
Concepts: data remanence: freed memory retains its contents, memset to zero sensitive data before free, double pointer to modify the caller’s pointer, defensive NULL check before operations, secure coding patterns for sensitive data
6. Compiler Security Flags
| Difficulty: Beginner | Time: ~8 min | Type: bare code |
For each of the following gcc security flags, explain: (1) what attack it prevents, (2) how to enable it, and (3) what happens when it catches a bug.
Flags to analyze: a) -Wall -Werror b) -fstack-protector-strong c) -D_FORTIFY_SOURCE=2 d) -pie -fPIE e) -Wformat -Wformat-security
Then …
Concepts: compiler-assisted security (defense in depth), stack canaries and -fstack-protector-strong, FORTIFY_SOURCE for compile-time bounds checking, ASLR and position-independent executables, format string warnings with -Wformat-security