100's of files infected by the same hacker code - any way to mass replace bad code?
Linux - NewbieThis 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
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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?
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,541
Rep:
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.
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.
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.
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.
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.
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 :
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,541
Rep:
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
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?
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:
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:
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,541
Rep:
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
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.