We recently added a C/C++ security checklist to the Testing Handbook and challenged readers to spot the bugs in two code samples: a deceptively simple Linux ping program and a Windows driver registry handler. If you found the inet_ntoa global buffer gotcha or the missing RTL_QUERY_REGISTRY_TYPECHECK flag, nice work. If not, here’s a full walkthrough of both challenges, plus a deep dive into how the Windows registry type confusion escalates from a local denial of service to a kernel write primitive. Since we first released the new C/C++ security checklist, we also developed a new Claude skill, c-review. It turns the checklist into bug-finding prompts that an LLM can run against a codebase. It’s also platform and threat-model aware. Run these commands to install the skill: claude skills add-marketplace https://github.com/trailofbits/skills claude skills enable c-review --marketplace trailofbits/skills The Linux ping program challenge The Linux warmup challenge we showed you in the last blog post has an obvious command injection issue. #include #include #include #include #define ALLOWED_IP "127.3.3.1" int main() { char ip_addr[128]; struct in_addr to_ping_host, trusted_host; // get address if (!fgets(ip_addr, sizeof(ip_addr), stdin)) return 1; ip_addr[strcspn(ip_addr, "\n")] = 0; // verify address if (!inet_aton(ip_addr, &to_ping_host)) return 1; char *ip_addr_resolved = inet_ntoa(to_ping_host); // prevent SSRF if ((ntohl(to_ping_host.s_addr) >> 24) == 127) return 1; // only allowed if (!inet_aton(ALLOWED_IP, &trusted_host)) return 1; char *trusted_resolved = inet_ntoa(trusted_host); if (strcmp(ip_addr_resolved, trusted_resolved) != 0) return 1; // ping char cmd[256]; snprintf(cmd, sizeof(cmd), "ping '%s'", ip_addr); system(cmd); return 0; } There are three validations that have to be bypassed before the system call can be reached with malicious inputs: The inet_aton function “converts the Internet host address from the IPv4 numbers-

Read Full Article at Trail of Bits Blog →