#!/usr/bin/perl # # (hhp-temprace.pl) v6.0 # Author: Cody Tubbs (loophole of hhp). # Site: http://www.hhp-programming.net/ # Email: pigspigs@yahoo.com # Date: 07/08/2001. 03:01:45PM CST. # iDate: 01/13/2001. 11:34:32PM CST. # # Description: # A _simple_ program that works on linux, BSD, Sun/Solaris, # and IRIX. This initializes Linux's strace, BSD's # ktrace/kdump, Sun/Solaris's truss, and IRIX's par to find # and parse /tmp and current directory temporary file. It # parses for *open(), *stat(), unlink(), and rmdir() calls # done within the target program. (BSD only tested for # open() so far, will add more later). This information # can then be used to determine if the target program is # vulnerable to any temp race conditions. I made this so I # don't have to do it manually for every binary I check. # Use if desired and give the code shouts if a temp race # condition is found/exploited. # # Note that I didn't really expand the verbosity of the # *stat() showings, just remember that the target program # probably checks to see if the temp file exists before # creation if this is used, check in depth afterwards. # # Email suggestions if you want to see anything added. # # ChangeLog: # 6.0: Added support for IRIX. Created some subroutines. # (Thanks for the account on your irix box bighawk). # 5.0: Added OS auto detection, not user supplied anymore. # 4.0: Added support for BSD and Sun/Solaris and verbosity # for ktrace[NAMI]. # 3.0: Added verbosity of stat(), unlink() and rmdir(). # # Todo: # Add support for DGUX. # ################################################ $ver="6_0"; if((@ARGV<1)||(@ARGV>3)){&usage} $y=0;$f=0;$z=0;$os=0;$foundOS=0;$t=".tmprace"; if((@ARGV<4)&&(@ARGV==3)&&(@ARGV[2] eq"-o")){($p,$k,$o)=@ARGV;$y=1} if(@ARGV==1){($p)=@ARGV} if((-e "/usr/sbin/par")&&($foundOS==0)){$os=4;$foundOS=1} if((-e "/usr/bin/strace")&&($foundOS==0)){$os=1;$foundOS=1} if((-e "/usr/bin/truss")&&($foundOS==0)){$os=2;$foundOS=1} if((-e "/usr/bin/ktrace")&&($foundOS==0)){$os=3;$foundOS=1} if($os==0){printf("strace, truss, or ktrace was not found!\n");exit(0)} unlink("$t");unlink("ktrace.out"); if($y==1){open(O,">>$o")or die "Can't open \"$o\".\n"} if($os==1){`strace -o $t $p>/dev/null 2>&1`; open(T,"$t")or &dye;} if($os==2){`truss -o $t $p>/dev/null 2>&1`; open(T,"$t")or &dye;} if($os==3){`ktrace $p>/dev/null 2>&1`; open(T,"$t")or &dye;} if($os==4){`par -o $t $p>/dev/null 2>&1`; open(T,"$t")or &dye;} if($y==1){print O "-"x10 . " temprace$ver results for \"$p\".\n"}else{ printf("%s temprace$ver results for \"%s\".\n", '-'x10, $p); } while(){ $line=$_; chomp($line); if($os==1){&stracetruss;} if($os==2){&stracetruss;} if($os==3){&kdump;} if($os==4){∥} } if($f==0){if($y==1){ print O "NO TMP FILE INFORMATION OR MODIFICATION WAS FOUND!\n"}else{ printf("NO TMP FILE INFORMATION OR MODIFICATION WAS FOUND!\n")} } if($y==1){print O "-"x10 . " End of results.\n"}else{ printf("%s End of results.\n", '-'x10); } if($y==1){close(O);} if($y==1){printf(">> Wrote results to: ($o).\n")} unlink("$t"); unlink("ktrace.out"); exit(0); sub stracetruss(){ if($line=~/(.*)open\("(\/tmp\/)*(.*)", (\S+), (\S+)\)/){ $g=uc($1);$x=$2;$i=$3;$fl=$4;$m=$5;$f=1; if(($x eq"")&&($i!~/\//)||($x ne"")){ if($y==1){print O ">> ".$g."OPEN: ($x$i), FLAGS: ($fl), MODE: ($m).\n"}else{ printf(">> %sOPEN: (%s%s), FLAGS: (%s), MODE: (%s).\n",$g,$x,$i,$fl,$m); } } } if($line=~/stat\("(\/tmp\/)*(.*)", /){ #Might add more here later. $ts=$1;$st=$2;$f=1; if($z==0){ if($y==1){print O ">> *STAT: ($ts$st) used at least once.\n"}else{ printf(">> *STAT: (%s%s) used at least once.\n",$ts,$st); } $z=1; } } if($line=~/rmdir\("(\/tmp\/)*(.*)"\)/){ $tr=$1;$rm=$2;$f=1; if(($tr eq"")&&($rm!~/\//)||($tr ne"")){ if($y==1){print O ">> RMDIR: ($tr$rm).\n"}else{ printf(">> RMDIR: (%s%s).\n",$tr,$rm); } } } if($line=~ /unlink\("(\/tmp\/)*(.*)"\)/){ $tu=$1;$ul=$2;$f=1; if(($tu eq"")&&($ul!~/\//)||($tu ne"")){ if($y==1){print O ">> UNLINK: ($tu$ul).\n"}else{ printf(">> UNLINK: (%s%s).\n",$tu,$ul); } } } } sub kdump(){ if($line=~/NAMI "(\/tmp\/)*(.*)"/){ #ktrace open() name. $x=$1;$i=$2;$f=1; if(($x eq"")&&($i!~/\//)||($x ne"")){ if($y==1){print O ">> OPEN: ($x$i).\n"}else{ printf(">> OPEN: (%s%s).\n",$x,$i); } } } } sub par(){ if($line=~/.*mS.*:(.*)open\("(\/tmp\/)*(.*)", (\S+), (\S+)\)/){ $g=uc($1);$x=$2;$i=$3;$fl=$4;$m=$5;$f=1; if(($x eq"")&&($i!~/\//)||($x ne"")){ if($y==1){print O ">> ".$g."OPEN: ($x$i), FLAGS: ($fl), MODE: ($m).\n"}else{ printf(">> %sOPEN: (%s%s), FLAGS: (%s), MODE: (%s).\n",$g,$x,$i,$fl,$m); } } } if($line=~/.*mS.*: stat\("(\/tmp\/)*(.*)", /){ #Might add more here later. $ts=$1;$st=$2;$f=1; if($z==0){ if($y==1){print O ">> *STAT: ($ts$st) used at least once.\n"}else{ printf(">> *STAT: (%s%s) used at least once.\n",$ts,$st); } $z=1; } } if($line=~/.*mS.*: rmdir\("(\/tmp\/)*(.*)"\)/){ $tr=$1;$rm=$2;$f=1; if(($tr eq"")&&($rm!~/\//)||($tr ne"")){ if($y==1){print O ">> RMDIR: ($tr$rm).\n"}else{ printf(">> RMDIR: (%s%s).\n",$tr,$rm); } } } if($line=~ /.*mS.*: unlink\("(\/tmp\/)*(.*)"\)/){ $tu=$1;$ul=$2;$f=1; if(($tu eq"")&&($ul!~/\//)||($tu ne"")){ if($y==1){print O ">> UNLINK: ($tu$ul).\n"}else{ printf(">> UNLINK: (%s%s).\n",$tu,$ul); } } } } sub dye(){print "Can't open internal tmp file \"$t\".\n";exit(0);} sub usage(){ if($ [args]\" [-o outfile]\n",$0); printf("Examp: %s \"wall a\"\n",$0); printf("Examp: %s \"wall a\" -o outfile\n",$0); exit(0); } #EOF