Over the past week I have taken on the task of tracking down and stopping the source of a large number of SPAM emails which had been sent from a server that I was working on. I had gone through the usual notions of going through a few of the SPAM mail headers to no avail.
The server itself is really quite secure from a SPAM mail perspective in that we do not allow POP before SMTP or the sending of unauthenticated mail via PHP (preventing the use of sendmail via PHP). Ordinarily I will manage to track the mails down to a user account fairly easily via a number of methods too long to explain in this post, but not in this case. After quite a while of looking through the message headers, I had ascertained that the mails were being sent from a script on the server. The server supports 3 main scripting languages: PHP, CGI/Perl and Ruby. I knew that PHP wasn’t the problem, so I moved onto the CGI search.
My first stop was running a simple
ps ax | grep cgi |
just to determine if there were any cgi scripts running. To my surprise, there were two scripts running, and each was running four times. I took down the PID’s and worked out where the script was being executed from – this is simple once you have the PID, just run the following (where [PID] is the PID you would like to investigate)
ls -l /proc/[PID] | grep cwd |
After running that, you will get a single line ending with the location that the script was executed from. In this case, it was /home/someuser/public_html/erri. Interestingly, my line also ended with “(deleted)”. This means that the script I was looking for was deleted after it was executed. At this point I killed all of the rogue processes and dealt with the user who’s account it was.
It was at this stage that I decided to write a little bash script which would just respond with “yes, everything is fine” or it “looks like there could be an issue”. Now I cant say that I ever do much shell scripting, so it may not be best practice, but this is what I came up with.
#!/bin/bash # Get the total number of cgi processes running a=`ps ax | grep -c cgi` # Remove 3 of them (2 for the main script, 1 for the "ps grep" let a=$a-3 # If $a is not 0 it means there is a cgi script running if [ "$a" -gt 0 ] then # If there are some processes running, output them thisScript=`basename $0` b=`ps ax | grep cgi | grep -v $thisScript | grep -v "grep cgi"` # Split the output of the above command into an array # This is basically just to make the output more readable IFS=" " c=( $b ) echo "There is/are $a cgi script(s) running : detais below"; for (( i = 0 ; i < ${#c[*]} ; i++ )) do case ${c[i]} in *"cgi") echo -e ${c[i]} "\t";; *) echo -ne ${c[i]} "\t";; esac done else # There are no CGI Scripts running echo "All is good, there are no CGI scripts running" fi |
To run it, just save the above code to a file called cgicheck.cgi then run the following commands
chmod 0755 cgicheck.cgi ./cgicheck.cgi |
I suggest that you dont put it in a web accessible area just to be safe. I just have it sitting in ~/scripts/cgicheck.cgi
Now my original idea was to run something similar to this as a cron then just filter the cron emails if there was something returned of interest. I suppose since I’m giving away this code freely, you should know that this code comes with no warranties and is provided “as is”. By using it you agree to not hold me responsible for any damages or losses yada yada yada.
As I said, I don’t really do much in the way of shell scripts, so I’m probably not doing it the best way possible. If you have any suggestions, please feel free to contribute them as comments.




Leave a Reply