Bugtraq mailing list archives

stackguard 1.21 vulnerability


From: Hiroaki Etoh <ETOH () JP IBM COM>
Date: Fri, 18 Aug 2000 14:22:54 +0900

A security vulnerability has been discovered by Mariusz Woloszyn and Immunix has
released the protected version of StackGuard that is said to effectively protect
against the vulnerability.

Hiroaki Etoh has discovered a security vulnerability that permits attackers to
perpetrate attacks against StackGuarded programs under common circumstances.


The XOR Random Canary

This is the vulnerable code discovered by Mariusz Woloszyn and summarized by
Immunix member: (see. http://www.immunix.org/StackGuard/emsi_vuln.html)

foo (char *arg) {

    char *p = arg;            // a vulnerable pointer

    char a[25];               // the buffer that makes the pointer vulnerable

    gets (a);            // using gets() makes you vulnerable

    gets (p);            // this is the good part

}

The attacker first overflows the buffer a[] and changes the value of the char *p
pointer so as to address a return address record in an activation record.  When
the gets(p) is executed, the program takes input and stores it to the return
address record. The value is the address where the attacker put a malicious
code.



The attack is caused because the canary mechanism doesn't check the validity of
a return address record. The XOR random canary mechanism eliminates the flaw by
saving the return address in a canary location. The saved return address is the
XOR value with a random number that is saved in a global data area. Therefore,
the value can't be guessed by the attacker and also can be used for validating
the return address.



The Problem

Mariusz's attack can change the value of two portion of memories simultaneously,
one is an activation record of the function and the other is any portion of
memory addressed by the pointer p.  On the other hand, StackGuard has two
portion of memories  that must be protected from the attacker.  One is an
activation record: the return address and the canary value, the other is the
random number referred as a canary value.  By the fact that the number of attack
portions is equal to the number of  defense portions, it is possible to
perpetrate attacks against the XOR random canary mechanism.



Consider this program. This program is the quite possible example.

foo (char *arg) {

    char *p = arg;            // a vulnerable pointer

    char a[25];               // the buffer that makes the pointer vulnerable

    gets (a);            // using gets() makes you vulnerable

    *p = 0;              // this is the good part

}

The attacker overflows the buffer a[] and changes a series of values: the value
p, the XOR random canary, and the return address with the address of the random
value[i] that is used at that function, the address of some malicious code, and
the same address of that code respectively.   When the *p=0 is executed, the
program stores zero to the random value[i].  It means that the protection only
checks the equality of the return address and the canary value, because the
canary is gotten from this expression "the return address" XOR "random value[i]
(zero). The fact that an attacker can change the random value causes that he can
prepare the XOR random canary and the return address to a malicious code.  After
that, he can take a control of the program. Furthermore, he can store a
malicious code after the return address.



Hiroaki Etoh,  Tokyo Research Laboratory, IBM Japan
ProPolice: machine independent protection from stack-smashing attack
(http://www.trl.ibm.co.jp/projects/security/propolice/)


Current thread: