#!/bin/bash
#Copyright 2001, William Stearns <wstearns@pobox.com>
#Released under the GPL.

DetectLibVer="020"

False=1		#As far as bash is concerned.
True=0

#Please leave Need_Utils before the rest, please.  This gets called at
#the beginning of each function that needs a system tool.
Need_Utils () {
	for OneUtil in $* ; do
		if ! type -path $OneUtil >/dev/null 2>/dev/null ; then
			echo Missing support tool \"$OneUtil\" in path \"$PATH\"
			echo Exiting.
			exit $False
		fi
	done
}

debug () {
	:
	#echo '++++ (debugging information)' $* >/dev/stderr
}

#-------------------------------------------------------------------------
# askYN function, returns true or false depending on user input.
#-------------------------------------------------------------------------
askYN () {	#SUDO checked
	TESTYN=""
	while [ "$TESTYN" != 'Y' ] && [ "$TESTYN" != 'N' ] ; do
		echo -n '?' >/dev/stderr
		read TESTYN || :
		case $TESTYN in
		T*|t*|Y*|y*)		TESTYN='Y'	;;
		F*|f*|N*|n*)		TESTYN='N'	;;
		esac
	done

	if [ "$TESTYN" = 'Y' ]; then
		return 0 #True
	else
		return 1 #False
	fi
} #End of askYN




#No required utils outside of bash builtins
AttackName () {
#Params: A descriptive name for this worm.
	if [ -n "$*" ]; then
		NameOfAttack="$*"
	else
		debug Null attack name in AttackName.
	fi
}

#No required utils outside of bash builtins
AttackMarker () {
#Params: One or more files or directories whose presence (of any of them, not all of them) 
#essentially guarantees the attack is on the system.
#DO NOT ASSUME ANY EXTERNAL UTILITY CAN BE TRUSTED AT THIS POINT.
	AttackPresent=$False
	if [ -z "$NameOfAttack" ]; then
		debug Null attack name in AttackMarker.
	fi
	for OneFile in $* ; do
		if [ -e $OneFile ]; then
			debug Found $OneFile
			AttackPresent=$True
		fi
	done
	if [ "$AttackPresent" = "$True" ]; then
		echo $NameOfAttack detected.
	else
		echo $NameOfAttack DOES NOT appear to be present on this system, good.
	fi
	return $AttackPresent
}



#No required utils outside of bash builtins
Need_Utils rm
AttackFiles () {

	OrigList=$*
	FoundFiles=""
	FoundDirs=""
	FoundSpecials=""
	while [ -n "$1" ]; do
		if [ -d "$1" ]; then
			FoundDirs="$FoundDirs $1"
			ObjectsFound=$True
		elif [ -f "$1" ]; then			
			FoundFiles="$FoundFiles $1"
			ObjectsFound=$True
		elif [ -b "$1" ] || [ -c "$1" ] || [ -p "$1" ] || [ -S "$1" ]; then
			FoundSpecials="$FoundSpecials $1"
			ObjectsFound=$True
		else
			MissingFiles="$MissingFiles $1"
		fi
		shift
	done

	if [ "$ObjectsFound" = "$True" ]; then
		echo Do you wish to delete the following files:
		echo $FoundFiles $FoundSpecials
		echo and directories:?
		echo $FoundDirs
		echo If so, enter \"Y\" without the quotes.
		if askYN ; then
			if [ -n "$FoundFiles$FoundSpecials" ]; then
				rm -f $FoundFiles $FoundSpecials
			fi
			if [ -n "$FoundDirs" ]; then
				rm -ri $FoundDirs
			fi
		else
			echo NOT removing the above listed files and directories.
		fi
		return $True
	else
		echo None of the following files and directories were detected:
		echo $OrigList
		return $False
	fi
}

Need_Utils mv
ReplacedFile () {
#Params: Suspect utility name, Where the good copy was moved if replaced.
	if [ -f "$2" ]; then
		echo \"$2\" found, so we assume \"$1\" is a trojan version and
		echo will restore the original version.
		if [ ! -f "$1" ]; then
			debug \"$1\" does not exist in WrappedUtil.
		fi
		echo Would you like to restore $1 from ${2}
		if askYN ; then
			mv -f "$2" "$1"
		else
			echo NOT restoring $1 from $2 .
		fi
	fi
}

NukedFiles () {
#Params: Files which may have been removed from the system or truncated to 0 bytes.
	if [ -n "$*" ]; then
		echo The following files may have been removed from the system or
		echo truncated.  You should inspect them to see if they need to be
		echo restored from backup.
		echo $*
	else
		debug Null filelist in NukedFiles
	fi
}

Need_Utils killall
PathToRunningApps () {
#Params: full path to apps that may be running as part of the attack
	echo Would you like to kill all running processes run from the
	echo following executables?  If so, enter \"Y\" without quotes.
	echo $*
	if askYN ; then
		for OneApp in $* ; do
			killall -9 $OneApp
			killall -9 ${OneApp##*/}
		done
	else
		echo NOT removing the above listed applications.
	fi
}

AddedLine () {
#Params: file which may have had a line added, line that was added (or at least enough of a regexp to match).
#FIXME - writeme
	echo The code to remove a line from a file is not a part of this
	echo worm library yet.
	echo Please remove the \"$2\" line from \"$1\" by hand.
}

ServicesStopped () {
#Params: names of SysVinit scripts that may need to be restarted.
	for OneService in $* ; do
		echo Would you like to stop and start service \"$OneService\"?
		echo If so, enter \"Y\" without quotes.
		if askYN ; then
			if [ -f /etc/rc.d/init.d/$OneService ]; then
				/etc/rc.d/init.d/$OneService stop
				/etc/rc.d/init.d/$OneService start
			elif [ -f /etc/init.d/$OneService ]; then
				/etc/init.d/$OneService stop
				/etc/init.d/$OneService start
			else
				echo Can\'t find the script that stops and starts the service.
				echo Please restart it by hand.
			fi
		else
			echo NOT restarting the above listed service.
		fi
	done
}

#Need_Utils mkdir
#Last function, please
InitDetectLib () {
	if [ ! "$DetectLibInitialized" = "$True" ]; then

		#set PATH=/knowngood

		DetectLibInitialized=$True
	fi
}


