‘Second-Order Symlink Vulnerabilities’


Recently, Eric Romang of ZATAZ Audits reported several symlink issues that are different than the usual symlink vulnerabilities [1] [2]. There are probably a large number of applications that are safe with respect to traditional symlink problems, but vulnerable to this particular variant.

Specifically, the problem arises when one program, ‘PARENT,’ invokes another program, ‘CHILD,’ in which:
 – The CHILD has a ‘standalone’ design, i.e. its normal mode of operation is to be run by an interactive user, or a script on behalf of the user

 – The CHILD does not run with more privileges than the user that invokes it, e.g. it is not setuid

 – The CHILD program assumes that the user calling the program has control over all files that are specified as arguments, i.e. the specified filenames are trusted

 – The CHILD program follows symlinks

 – The PARENT uses filenames that are passed as arguments to the CHILD

 – The filenames as used by the PARENT are:
  – Controllable, or predictable, by the attacker, and
  – In a directory that’s writable by the attacker;

The attacker could then use a symlink attack on the filename arguments that the PARENT passes to the CHILD.
This variant might be referred to as a ‘Second Order Symlink Vulnerability’.’


[1] ‘everybuddy <= 0.4.3 insecure temporary file creation’ June 6, 2005 http://www.zataz.net/adviso/everybuddy-06062005.txt
[2] ‘LutelWall <= 0.97 insecure temporary file creation’, June 6, 2005 http://www.zataz.net/adviso/lutelwall-05222005.txt
[3] ‘Second Order Code Injection Attacks’ NGS Software http://www.nextgenss.com/papers/SecondOrderCodeInjection.pdf
The information has been provided by coley.’


‘Note that the four conditions for the CHILD, if treated alone, are not normally regarded as a security vulnerability: there aren’t any privilege boundaries being crossed, and the filenames are under the control of the user.

It’s the interaction between the PARENT and the CHILD that becomes the problem. There is a strong argument that it is the PARENT’s responsibility to protect against the second-order symlink vulnerability, since ‘fixing’ the child could significantly reduce
functionality in common standalone uses. However, there may be some cases in which the PARENT does not have intrinsic knowledge of which CHILD will be invoked at runtime.

Note that from the CHILD’s perspective, the attack vectors do NOT involve temporary files.

Current code scanning tools may not locate second-order symlink vulnerabilities when scanning the PARENT, because the affected fopen/create/etc. function call may not be in the PARENT at all, but in the CHILD.

Romang’s reports for everybuddy and LutelWall both deal with the case in which wget is the CHILD, and the PARENT specifies an output file to wget using the ‘-O’ argument.

It must be emphasized that the vulnerability is NOT in wget; as previously discussed, it is in the interaction between wget and the process that invokes it.

For LutelWall, we have:
  echo `wget -C off -O $tmp-newfeat -q -t 1 -T 3 -w 3

For everybuddy, we have:
  258 g_snprintf(buf, 2048, ‘rm /tmp/.eb.%s.translator -f ; wget -O
  ‘http://world.altavista.com/sites/gben/pos/babelfish/tr? tt=urltext&lp=%s_%s&urltext=%s”,
  259 getenv(‘USER’), getenv(‘USER’), from, to, string);
  263 if(system(buf)!=0)

Categories: Reviews