2024-04-29
C
main declarationIn the last couple of days, we can see people talking about the security aspect of this behaviour.
In C
, we can in fact easily interact with shell variables with the char *getenv(const char *name)
standard function:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
printf("PATH: %s\r\n", getenv("PATH"));
return (0);
}
But the C
offers a way to access them directly as passing argument into the main function, just like **argv
.
The definition of main
can indeed have 0, 2 or 3 arguments:
int main(void)
int main(int argc, char **argv)
int main(int argc, char **argv, char **envp)
The third and option argument is then our way to access shell variables, e.g.:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv, char **envp)
{
unsigned short timeout = 0;
while ((*envp != NULL) && (timeout++ < (1 << 15))) {
if (strncmp(*(envp++), "PATH", 4) == 0) {
printf("%s\r\n", *(envp - 1));
return (0);
}
}
printf("Timeout error\r\n");
return (1);
}
Note that this third definition of main
is not part of the C99 Standard (par. 5.1.2.2.1), making it de facto POSIX-specific though widely supported.
You could however achieve the same result by overflowing the **argv
parameter:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
unsigned short timeout = 0;
argv += argc + 1;
while ((*argv != NULL) && (timeout++ < (1 << 15))) {
if (strncmp(*(argv++), "PATH", 4) == 0) {
printf("%s\r\n", *(argv - 1));
return (0);
}
}
printf("Timeout error\r\n");
return (1);
}
You can find many examples and applications of this new main
argument online, sometimes with another name (e.g. **environ
) as, again, it is not standard.