top of page

The Scanner User Agent We See Most Is a Typo: 'Mozlila,' 'Bulid,' 'Moblie.' It Is Hard-Coded in Public Webshell Finders, and the IPs Behind It Never Come Back.

Writer: Patrick Duggan
Patrick Duggan
55 minutes ago
4 min read

If your logs show a client calling itself "Mozlila/5.0 (Linux; Android 7.0; SM-G892A Bulid/NRD90M; wv) … Moblie Safari," that is one of a family of public scanner scripts, and it is asking whether somebody already planted a webshell on your server. The string is misspelled three times, the scripts that send it are on GitHub, and the IP addresses behind it do not come back.





What we saw


We searched our own edge records from August 1 to October 31. One exact user agent string appeared in 219 records from 49 IP addresses: 212 blocks and 7 canary hits. Hits by month were 54 in August, 19 in September and 146 in October. We cannot say when it began, because that is where our search window starts.


The requests come in two modes.


  • One-shot bursts. Eight DigitalOcean addresses in Singapore sent 91 requests. Each address made 9 to 12 requests in 43 to 146 seconds and then never appeared again. The requests walk a chain of repeated directory names to a file, for example //images/images/images/images/cache.php, with one more repeat each time.

  • Slow probers. Small hosting providers in seven networks sent 3 to 8 requests per address, spread over days or weeks. Several addresses sit in the same /24 ranges, such as 185.242.3.0 and 43.228.157.0, and new addresses keep turning up inside them.

What they ask for is a list of webshell file names: cache.php (136 requests), db.php (27), perl.alfa (16, a file name tied to the ALFA webshell), filefuns.php and core.php. A smaller share sprays .env and credential files, including URL-encoded forms.



Where the string comes from


A code search on GitHub for the misspelled literals returned about 878 files for "Mozlila/5.0," about 872 for "Bulid/NRD90M" and about 506 for "Moblie Safari." GitHub's counts are approximate and count files, not repositories.


Part of that is defenders. Bad-bot blocklists for nginx and Apache, bot-detection test fixtures and user-agent databases all contain the string, because it is a marker for exactly this traffic. The rest is attacker tooling. We read three public scripts statically, without running them, and each hard-codes the exact string:


  • A small Python 2 "webshell finder," under 2 KB, that requests two file names from every site in a list on 150 threads and marks a site vulnerable if the response contains one of four strings, including "403WebShell" and "LinuXploit."

  • A Laravel .env grabber.

  • A mass site-grabbing script.

The webshell file-name wordlist is public too. A search for "perl.alfa" and "cache.php" and "db.php" together matched about 250 files across GitHub, including shell-finder lists, a honeypot configuration and site-statistics files that recorded the probes.


So the string identifies a toolkit that anyone can copy. It does not identify an operator, and we are not attributing anything to one. The scripts we read are not necessarily the ones that hit us. Our requests use different paths, but they share the string, the style and the wordlist.



What a defender can do


  1. Search your logs for the string. Look for "Mozlila," "Bulid/" or "Moblie Safari" in user agents. We have not seen a legitimate client send these spellings. Check your own security tooling first, since test suites and bot-detection fixtures contain the string.

  2. Block or alert on it at your WAF. It is cheap, and it stops the lazy end of this family. It does not stop a copy that fixes its typo, which is a one-line edit.

  3. Answer the question the paths are asking. Search your web roots for cache.php, db.php, filefuns.php and core.php in directories you did not put them in, especially image, asset, upload and cgi-bin directories, and for any file with the ALFA shell's name. Some CMSes ship a real cache.php, so judge by location and contents. A shell nobody told you about is the whole point of the hunt.

  4. Do not rely on an IP list. Each address in the bursts fired once, and the slow probers rotate inside their ranges. The signal that lasts is the request shape: a webshell file name behind a chain of repeated directory names.


What we hold, and what we did


We hold 22 of these addresses as first-party observations at confidence 60: the first 10, mostly one-day bursts, and 12 more with three or more requests each. Each record says the address was seen on one or a few days, that the string is shared, and that the address may be reassigned. We did not add the single-request addresses, which are too thin, and we did not ingest the user agent, because it is not an indicator of one actor. Two more addresses were already in our corpus from earlier first-party canary hits.


On October 31 we also shipped an edge change that answers an inert empty page to a cache.php request behind a repeated-directory chain, on our own zones, and records the visit. We have not verified that it works, and we think it may rarely fire. Of the 212 blocks, 207 were made by Cloudflare's managed ruleset, which runs before our edge code, so most of this traffic probably never reaches it. The next real hit will tell us. An empty page also gives these scripts nothing to match, so they log a miss and move on, which is no better for us than a block.


This is the other end of this week's picture. One operator spent more than $7,000 on AI services and still got in with stolen passwords. The traffic in this post comes from a 2010s script with a typo in its header. In both cases the controls that matter are plain ones.



Limits


The edge counts come from our own block and canary records for August 1 to October 31 and describe our zones only. The GitHub counts are approximate file counts from October 31, and we read three scripts, not all of them. We did not run or fetch anything from any script. We cannot tell whether any file the scanners ask for exists on anyone's server, and we make no claim that anyone is compromised.


Five percent of this is wrong somewhere. It always is.


Was this useful? Rate this post. The widget is at the bottom of the page, and we read every response.




Every indicator in this post is in the feed. Free.

1.58M+ IOCs, STIX 2.1 / TAXII, 88% novel vs ThreatFox, exploited-CVE leads ahead of CISA. No credit card — a free API key in 30 seconds, and you can audit every claim above against the live endpoints.


Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
bottom of page