AFAIK ESC can not be detected using standard i/o, such as getchar() and fgets(). Same with other special keys such as function and arrow keys.
Not so. From the standard IO perspective, escape is just a regular character. getchar is perfectly happy to read it, and putchar - to print. You can easily verify that with a help of a trivial cat-like program
while((ch = getchar()) != EOF)
feeding it a file with escape in it.
The problem lies outside the stdio. The offending party is either a console driver, or a framework, or whatever else, which intercepts the escape and interprets it (in case of Windows console, it is a console driver).
If the application is desperate to see the escape, it must configure the offensive driver, replace it or bypass it somehow. How to do it is not addressed by a programming language.