CERN 3.0A Heap overflow advisory - There is a heap overflow that wastes memory space in the CERN/3.0A webserver. Close to 50000 bytes of the heap will be ruined! DoS example included.
489fc3d42f1e7f2c642902f70308d9caefba877586655086add9c34454afe5b3
#$%$#$%$#$%$#$%$#$%$#$%$#$%$#$%$#$%$#$%$#
$% CERN 3.0A Heap overflow advisory %$
#$%$#$%$#$%$#$%$#$%$#$%$#$%$#$%$#$%$#$%$#
$% By Scrippie %$
#$ Phreak.nl $#
$%$#$%$#$%$#$%$#$%$#$%$#$%$#$%$#$%$#$%$#$
#$ Love To: Maja, Dopey, Hester $#
$%$#$%$#$%$#$%$#$%$#$%$#$%$#$%$#$%$#$%$#$
there is a heap overflow that wastes memory space in the CERN/3.0A webserver.
Offending source code file is: Daemon/Implememtation/HTScript.c
Offending function is: PUBLIC int HTCallScript ARGS1(HTRequest *, req)
Offending Code snippet:
else { /* Try replacing unknown suffix with .pp */
char *test = (char*)malloc(strlen(HTReqScript) + 4);
char *s;
CTRACE(stderr, "Trying...... to find executable by appending .pp\n");
strcpy(test, HTReqScript);
s = strrchr(test, '.');
strcat(test, ".pp"); /* Try appending .pp */
CTRACE(stderr, "Trying...... \"%s\"\n", test);
if (-1==access(test, X_OK)) { /* Then try replacing suffix with .pp */
if (s) {
*s = 0;
strcat(s, ".pp");
CTRACE(stderr, "Bad luck.... now trying \"%s\"\n", test);
if (-1==access(test, X_OK)) { /* INVALID */
if (!(msg = (char*)malloc(3*strlen(test) + 100)))
outofmem(__FILE__, "HTCallScript");
sprintf(msg,
"Bad script request -- none of '%s' and '%s.pp' is executable",
HTReqScript, test );
free(test);
So we see that test is malloced to hold HTReqScript + ".pp\0" after which
HTReqScript is copied to test, the dot is located and .pp is appended.
We note that strcat() does not just append ".pp" to the string, but rather
".pp\0".
Now, if the HTReqScript did contain a suffix CERN will go and use the char
pointer s to overwrite the suffix of HtReqScript.
If the HtRequest with the new ".pp" suffix cannot be found we print an error
message.
It seems CERN allocates 3*strlen(test) + 100 bytes for our error string...
Probabely some 100 for our static string and the rest for HtReqScript and test.
Sadly, the strcat on test will have limited the lenght of the test string, but
NOT of HtReqScript, so making sure we have a lot of characters after our
seperating dot overflows the heap.
Consider a HtReqScript of 1 A a dot and 50000 A's - now we get something like:
HtReqScript - somewhere around 50000 bytes (50003)
Test - the same as HtReqScript + 4 (50007)
After putting ".pp\0" into place however in our test array we get:
strlen(test) - 1 A, 1 dot, pp - hmmm, 3 bytes
Now our msg will be:
3*3+100=109 - by far enough to hold test, but by far NOT enough to hold
HtReqScript. Close to 50000 bytes of the heap will be ruined!
It's unlikely that this flaw is exploitable, since there is nothing on the
heap after the malloced msg, but I'd sure like to hear any ideas.
/* Scrip kids DoS attack section */
iLikeDossing# lynx https://www.lart.org/cgi-bin/A.`perl -e 'print"A" x 50000'`
Repeat several times and see memory usage jump to remarkable heights :)
/* End of script kiddies section */
A lot of thanks go to dvorak for pointing out to me that most webservers
seem to suffer some sort of flaw in their script parsing routines and for
telling me to take a look at HTScript.c
A quick patch:
--- HTScript.back Wed Jan 26 22:18:44 2000
+++ HTScript.c Wed Jan 26 22:19:52 2000
@@ -894,7 +894,7 @@
strcat(s, ".pp");
CTRACE(stderr, "Bad luck.... now trying \"%s\"\n", test);
if (-1==access(test, X_OK)) { /* INVALID */
- if (!(msg = (char*)malloc(3*strlen(test) + 100)))
+ if (!(msg = (char*)malloc(strlen(HTReqScript)+strlen(test) + 100)))
outofmem(__FILE__, "HTCallScript");
sprintf(msg,
(Isn't a unified diff a beautifull thing :-)
A big hooray to: #phreak.nl
A lots of love to: Dopey, Maja, Hester
Thanks to: dvorak
Cheers,
Scrippie - ronald@grafix.nl