I had a user on our shared host who let their Wordpress install fall victim of an exploit that allowed for arbitrary file creation as the apache user. The files generated are obviously generated with a random generator, but fall under some sort of pattern. I was also thinking about just matching the group, but a find of that nature hits too many files that are legitimate. How can I match all of these example malicious files?

oihfoe09fposf.php (occured more often)
Jwlsjd_baaqifg.php (occured more often)

I'll obviously be working with the user to update their Wordpress install and plugins, but I would appreciate a regex I can toss into find and quickly verify whether the issue persists afterward, etc.

Patterns I can see:

  1. Always 8, 10, or 13 characters.
  2. Always *.php
  • 1
    Don't bother. Your box has been compromised. Reinstall from scratch, because you can't trust anything on it. Jun 7, 2019 at 18:02
  • Unless you rebuild that system from scratch, you are not going to know what files and utilities are installed by the intruder and what utilities are safe to use. The strange filenames are just a symptom of the intrusion. How do you know that sudo, for example, has not been changed to store or send your password somewhere?
    – Kusalananda
    Jun 7, 2019 at 18:11
  • @PhilipKendall Look at the age of the question. I already rebuilt the VM for the client, installed from scratch, updated, everything is fine and has been for months. I just happened to get a notification on another question of mine and decided to better word the title. The end. Jun 7, 2019 at 18:13

3 Answers 3


You'll have to determine that the "pattern" is precisely first (to create the regex). I can't see anything very clear. It always ends in .php, preceded by 8, 10, or 13 characters, which are upper- or lower-case letters, numbers, or _. Apart from that, it's unclear, e.g. there's not always a number. If you were to match this general "pattern", e.g. with ^[a-zA-Z0-9_]{8}\.php$ and for 10 or 13 characters too, then you'd likely get many false positives.

Instead, are the new files created with a current modification date? If so, you could search for newer suspicious files modified after, say, your new config.

find /path/to/directory -newer /path/to/new_config -regextype egrep -regex '.*/([a-zA-Z0-9_]{8}|[a-zA-Z0-9_]{10}|([a-zA-Z0-9_]{13})\.php'

One caveat is that it's possible to change the modification date using touch. If your malware does that, it might be possible to filter on access time -anewer, status-change time -cnewer, or -newerXY.

If all the files are owned by a particular user, you could also use that information to filter. i.e. add the option -user apache.

  • Also, testing apache file ownership might help Feb 12, 2019 at 1:06
  • @HagenvonEitzen Good idea. I've added that information in
    – Sparhawk
    Feb 12, 2019 at 2:01
  • note this regex doesn't have an underscore, and some of his examples do. This also doesn't match the 8,10,12 limit the autor specifies. Feb 12, 2019 at 2:05
  • 2
    @EvanCarroll Fixed. The question was edited after I posted my original answer.
    – Sparhawk
    Feb 12, 2019 at 2:08

This is PHP malware and I've seen this before. You should watch the video by Ben Dechrai called "Writing Viruses for Fun, not Profit" if you're interested in this specific attack.

The crux of my contribution is this. Rather than looking for the md5 of the filename, which is a totally valid approach, it's generated with something like this (though not exact because this one is always $length = 10)

function generateRandomString($length = 10) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyz';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0;$i < $length;$i++) {
        $randomString.= $characters[rand(0, $charactersLength - 1) ];
    return $randomString . ".php";

You should instead look for all files that are older than a specific date with


or eval(base64_decode(

That won't tell you for sure which characters match and which don't, but in my experience it is likely to be more close to correct.

I would.

  1. Take the server down.
  2. Back-up.
  3. Install a parallel version of Wordpress (fresh) in a new directory
  4. Check for false-positives of eval(base64_decode(
  5. Quarantine all files that match that string.
  6. See if any more files match your regex above.
  7. Back up quarantined files.
  8. Clean quarantined files that match the above string.
  9. Go looking for a Wordpress patch that prevents this exploit, or upgrade to a new version of Wordpress.
i have used below command to achieve

find . -type f -user "user" username | sed -n '/[a-zA-Z0-9_]\{8,\}.php$/p'

It will display all the files whose len is greater than 8
  • There are a few problems with this. (1) It will also match names starting with other characters, e.g. !@(# qwertyui.php. (2) There is no need to parse find, with creates potential special-character problems, because find has -regex (e.g. if a file has a newline in the name it might match here). (3) It would be more precise to match 8, 10, or 13 characters. (4) user "user" username is incorrect syntax.
    – Sparhawk
    Feb 12, 2019 at 21:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .