_var_short_name function reads and returns the content of the USER environment variable without sanitizing it, as can be seen in the code below:
inetutils/telnetd/utility.c
_var_short_name is always inlined into _expand_var. This is normal if a function is called just once and from a single place, which is the case.
Finding _expand_var
To start the rule in the right context, the functions scope can be used like this:
_expand_var function in the binary. As the function name is fixed in this case, there’s no need to use target = {matching = "<regex>"}.
Because scope:functions was used, the check function receives two parameters, of types ProjectHandle and FunctionContext, in that order. The first gives access to project-level methods, while the second holds the context of the matched function — _expand_var in this case — and provides access to function-level methods.
Finding getenv
A good rule should annotate relevant addresses precisely. To find the call to getenv, one possible check function is as follows:
Finding start_login and its call to execv
After reading the contents of USER, a start_login function passes it to login(1) (by default), which has a -f <username> option to skip login authentication for a given <username>. Consequently, if an attacker sets USER to -f root, the authentication is bypassed and the attacker will be logged as root. The relevant code is as follows:
inetutils/telnetd/pty.c
_expand_var, it’s necessary to look at the project level to find start_login in the code. The following code uses a method from project — check’s first parameter — to achieve it:
Returning the evidence
Below is the completecheck function to detect this vulnerability. It includes a check for possible calls to strcspn from _expand_var, which are added with the patch. Production-level rules may use a result:patch method to properly inform the binary is patched. Check the Scopes Result Overview in the VulHunt Reference for more information.
telnetd.vh
VulHunt rules are versatile. Instead of usingscope:functionswithmatchingto locate_expand_var, an analyst could targetstart_loginand adapt the remaining logic to identify other functions. There are multiple ways to achieve the same goal.