Analysis of the bug =================== There are several bugs. 1. There is a one-byte overflow in the `f` operation, when the input string `id` is exactly 16 bytes long. The `strcpy()` will then put the terminator `\0` in the next field of the `cmd` structure, that is, `nselected`. This affects the number of arguments that are passed to the commands. 2. The `frobnicate` program assumes that `argc` is always at least 1. If that is not the case, the program will start processing as arguments the contents of memory immediately after the `argv` vector, where the the _environment_ vector is stored. 3. The `z` command puts a secret in the environment to pass it to a program. In the normal case the process successfully `exec()`s the program and execution does not return to the `child()` function. If the `exec()` fails, however, the `child()` function continues with the secret still in the environment. From there it may be passed to other commands. Attack plan =========== The three bugs can be exploited to read the secret: first, a `z` command can be used to load the secret in the environemnt, then the overflow in the `f` command can be exploited to zero-out the `nselected` field in the `cmd` structure and pass zero arguments to `frobnicate`. The latter program will try to interpret the environment strings as filenames, printing them. Attack implementation ===================== The only difficulty is that just one byte of `nselected` can be zeroed, so the attack fails if `nselected` is greater than 255. This is easily remedied by using the `s` command with any filter that selects fewer than 255 files (e.g., `1`). The attack can then be implemented as follows: 1. send a `z` command 2. send an `s` command, answer `1` to the `filter:` prompt 3. send an `f` command, answer `1234567812345678` to the `id:` prompt. Suggested Fix ============= For bug 1, an additional byte should be allocated for `id` in the `cmd`. For bug 2, a check on `argc > 0` should be added at the beginning of the program. For bug 3, an `unsetenv("COMPRESS_PASSWORD")` should be added after `execcmd(&c)`. Additional Notes ================ Bug 2 is based on the recently discovered vulnerability in `pkexec`: https://blog.qualys.com/vulnerabilities-threat-research/2022/01/25/pwnkit-local-privilege-escalation-vulnerability-discovered-in-polkits-pkexec-cve-2021-4034