How to detect compromised accounts in MU Online
Learn how to identify hijacked accounts on your MU Online server through log analysis, SQL queries and signs of anomalous behavior, so you can act before the damage is done.
Compromised accounts are one of the most corrosive security problems on a MU Online server. Unlike a DDoS attack, which is loud and immediate, an account hijack is silent: the attacker logs in with the stolen credential, empties the warehouse, transfers valuable items and zen to a "mule" account and
Compromised accounts are one of the most corrosive security problems on a MU Online server. Unlike a DDoS attack, which is loud and immediate, an account hijack is silent: the attacker logs in with the stolen credential, empties the warehouse, transfers valuable items and zen to a "mule" account and disappears — often before the legitimate owner even notices. By the time the report comes in, the items have already circulated and reversal has become difficult. An effective defense combines prevention (strong passwords, second factor, session limits) with fast detection: spotting anomalous behavior while the reversal window is still open. This guide focuses on detection, showing which signals to monitor, how to query them in the database and how to respond without destroying evidence.
The examples use the classic MuServer schema (SQL Server, MuOnline database, MEMB_INFO table) and assume the existence of login and movement log tables. Table and column names vary by season/emulator — many distributions have no trade log by default, and enabling one is the first practical prerequisite. Adapt each query to your own database.
Why manual detection doesn't scale
Waiting for a player report is reactive and slow. By the time the ticket arrives, three things have already happened: the item left the account, passed through one or more intermediaries and was possibly negotiated. The window in which you can safely reverse — before the item blends into the economy — is usually a matter of hours. The right approach is to monitor signals proactively, with scheduled queries that flag suspicious patterns, and reserve manual inspection for the cases the automation surfaces.
Prerequisites
To detect for real, you need data. First of all:
- Active login logs: a record of account, IP, date/time and result (success/failure) for every attempt. Enable it on the ConnectServer/GameServer of your distribution.
- Item/zen movement log: warehouse, trade and drops on the ground. Not every season ships this — enable or install a logging module/trigger.
- SQL Server access with read permission over the logs and the game database.
- A recent backup to allow reversal of items/zen when you confirm a break-in.
- A stable server in production. If you're still building the environment, start with how to create a MU Online server and come back with logging configured.
- A defined response policy: who freezes, who investigates, who contacts the owner.
The signs of compromise
No single signal proves a break-in — the owner may have traveled, switched carriers or sold items legitimately. Confidence comes from correlation. These are the strongest indicators:
| Signal | What to watch for | Weight |
|---|---|---|
| Login from new IP/country | An IP never seen on the account, geolocation far from history | High |
| Unusual hour | A login in a time band very different from the player's pattern | Medium |
| Warehouse emptying | Many items leaving the warehouse right after login | High |
| Mass trading | Several outgoing trades in a short interval to the same account | High |
| Password/email change | A credential change followed by movement | High |
| Login failures before success | A sequence of wrong passwords (brute force) then a hit | Medium |
| Zen suddenly drained | The zen balance dropping to near zero in one session | Medium |
| "Mule" destination account | A freshly created account receiving items from several victims | High |
The golden rule: one signal is noise, three or more together are a case. A login from a new IP on its own doesn't justify freezing; a login from a new IP, followed by a warehouse emptying and mass trading to an account created yesterday, does.
Step 1 — Detect anomalous logins
Start with the login logs. The first useful query finds accounts that logged in from an IP never before associated with them in the last 24 hours:
-- Logins from a "new" IP (not seen for the account in prior history) in the last 24h
SELECT l.AccountID, l.IP, l.LoginDate
FROM LoginLog l
WHERE l.LoginDate >= DATEADD(HOUR, -24, GETDATE())
AND l.Result = 'success'
AND NOT EXISTS (
SELECT 1 FROM LoginLog h
WHERE h.AccountID = l.AccountID
AND h.IP = l.IP
AND h.LoginDate < DATEADD(HOUR, -24, GETDATE())
)
ORDER BY l.AccountID, l.LoginDate;
GO
A second classic pattern is brute force: many failures followed by a success, on the same account and within a short interval.
-- Accounts with many failures before a success (possible brute force)
SELECT AccountID,
SUM(CASE WHEN Result = 'fail' THEN 1 ELSE 0 END) AS Failures,
SUM(CASE WHEN Result = 'success' THEN 1 ELSE 0 END) AS Successes,
MIN(LoginDate) AS StartTime, MAX(LoginDate) AS EndTime
FROM LoginLog
WHERE LoginDate >= DATEADD(HOUR, -1, GETDATE())
GROUP BY AccountID
HAVING SUM(CASE WHEN Result = 'fail' THEN 1 ELSE 0 END) >= 10
AND SUM(CASE WHEN Result = 'success' THEN 1 ELSE 0 END) >= 1
ORDER BY Failures DESC;
GO
A third signal is the geographically impossible login: the same account logging in from very distant IPs within a few minutes. Without a geolocation database, you can approximate this by comparing distinct IP blocks (/16) within a short window.
Step 2 — Detect anomalous item and zen movement
A suspicious login only becomes a case when there's damage. Cross-reference it with movement. If you have a trade log, the most valuable query is the one for destination accounts that concentrate items from several sources — the typical behavior of a "mule" account:
-- Accounts that RECEIVED items from many different sources in the last 6h
SELECT t.ToAccount,
COUNT(DISTINCT t.FromAccount) AS DistinctSources,
COUNT(*) AS TotalTrades
FROM TradeLog t
WHERE t.TradeDate >= DATEADD(HOUR, -6, GETDATE())
GROUP BY t.ToAccount
HAVING COUNT(DISTINCT t.FromAccount) >= 4
ORDER BY DistinctSources DESC;
GO
And the one for accounts that emptied the warehouse right after login:
-- Many items leaving the warehouse shortly after login
SELECT w.AccountID, COUNT(*) AS ItemsWithdrawn, MIN(w.MoveDate) AS StartTime
FROM WarehouseLog w
JOIN LoginLog l
ON l.AccountID = w.AccountID
AND w.MoveDate BETWEEN l.LoginDate AND DATEADD(MINUTE, 15, l.LoginDate)
WHERE w.Direction = 'out'
AND l.LoginDate >= DATEADD(HOUR, -24, GETDATE())
GROUP BY w.AccountID
HAVING COUNT(*) >= 10
ORDER BY ItemsWithdrawn DESC;
GO
If your distribution has no trade/warehouse log, the alternative is to compare snapshots of the account's zen and item count between two moments (for example, daily snapshots), flagging sharp drops. It's less precise, but better than nothing.
Step 3 — Correlate the signals
The strength of the method lies in combining an anomalous login with anomalous movement. A query that joins "new IP in the last 24h" with "warehouse emptying in the same window" produces a short, high-confidence list for manual inspection:
-- Strong suspicions: new IP + warehouse emptying in the same session
WITH NewLogins AS (
SELECT l.AccountID, l.IP, l.LoginDate
FROM LoginLog l
WHERE l.LoginDate >= DATEADD(HOUR, -24, GETDATE())
AND l.Result = 'success'
AND NOT EXISTS (
SELECT 1 FROM LoginLog h
WHERE h.AccountID = l.AccountID AND h.IP = l.IP
AND h.LoginDate < DATEADD(HOUR, -24, GETDATE()))
)
SELECT n.AccountID, n.IP, n.LoginDate, COUNT(w.AccountID) AS ItemsWithdrawn
FROM NewLogins n
JOIN WarehouseLog w
ON w.AccountID = n.AccountID
AND w.Direction = 'out'
AND w.MoveDate BETWEEN n.LoginDate AND DATEADD(MINUTE, 15, n.LoginDate)
GROUP BY n.AccountID, n.IP, n.LoginDate
HAVING COUNT(w.AccountID) >= 5
ORDER BY ItemsWithdrawn DESC;
GO
Schedule this query (SQL Server Agent, every 15–30 minutes) to get near real-time alerts. It's the difference between reversing a theft and merely lamenting it.
Step 4 — Respond without destroying evidence
When you confirm a strong suspicion, the order of actions matters:
- Freeze the hijacked account (block login without banning). On MuServer this is usually done by changing the account's block status:
``sql -- Block login without deleting anything (column name varies by distribution) UPDATE MEMB_INFO SET bloc_code = 1 WHERE memb___id = 'victimAccount'; GO ``
- Freeze the destination account ("mule") too, to stop the items from moving on.
- Preserve the logs: export the relevant rows from
LoginLog,TradeLogandWarehouseLogto a case table or file. Don't trust that they'll stay in the database — logs rotate. - Reconstruct the timeline: first suspicious login, items that left, where they went.
- Reverse based on the backup and the logs, returning the items to the victim and removing them from the mule account. Do it in a transaction and document it.
- Contact the legitimate owner through a verified channel, advise them to change the password and (if available) enable a second factor/warehouse PIN.
- Only then decide on banning the destination account, if it's proven it was created for the theft.
> Never start with a ban. Banning erases traces, may punish the legitimate owner whose account was used, and closes the door to a clean reversal. Freezing preserves everything and is reversible.
Step 5 — Close the loop with prevention
Detection is the last line; reducing the volume of cases comes from prevention:
- Strong passwords and proper hashing: never store a password in plain text. Enforce a minimum length and complexity at registration.
- Second factor or warehouse/trade PIN: an extra lock over the warehouse prevents emptying even with a leaked password.
- Simultaneous session limits per account and, if possible, an alert on login from a new IP.
- Anti-brute-force: a temporary block after N login failures per account/IP.
- Community education: most leaks come from phishing and fake "top-up" sites. Warn your players.
Common errors and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| I can't investigate anything | Login/trade logs disabled | Enable logs on the ConnectServer/GS before anything else |
| I banned the account and lost the evidence | The response started with a ban | Adopt the freeze → preserve → reverse → decide flow |
| Too many false positives for "new IP" | ISPs with dynamic IPs | Correlate with movement; a new IP alone isn't enough |
| Reversal returned a duplicated item | Reversal without a transaction/without checking logs | Reverse in a transaction, matching each item to the outbound log |
| Legitimate owner complains about the block | Account frozen without a real break-in | Require correlation of 3+ signals before freezing |
| Items had already circulated by the time I acted | Detection only via reports, no automation | Schedule the correlated query every 15–30 min |
Launch checklist
- Login logs (account, IP, date, result) enabled and retained
- Item/zen movement log (warehouse, trade) enabled or installed
- A recent backup available for item/zen reversal
- New-IP login query tested against real data
- Brute-force query (failures before success) validated
- "Mule" account query (many sources) validated
- Correlated query (new login + emptying) scheduled every 15–30 min
- Response flow documented (freeze → preserve → reverse → decide)
- Freeze command (bloc_code or equivalent) tested and reversible
- Prevention reinforced (strong password, warehouse PIN, session limit, anti-brute-force)
- Verified channel to contact legitimate owners defined
Frequently asked questions
How do I know an account was really hijacked and it isn't just the owner playing?
Cross-reference signals: a sudden change of IP/country, a login at an unusual hour, mass item and zen transfers right after login. A single signal is noise; three or more together indicate compromise with high probability.
Should I ban the account as soon as I suspect a break-in?
Don't ban right away. The first step is to freeze it (block login) and preserve the logs. Banning erases traces and may punish the legitimate owner. Freeze, investigate, and only then decide on reversal and blocking.
Can I detect compromised accounts without a logging system?
Partially. Without logs you depend on database snapshots (current items/zen) and player reports. That's why the first security investment is enabling and retaining logs for logins, item movement and trades.
Is it worth automating detection?
Yes. A scheduled query that flags logins from a new IP followed by a warehouse being emptied, or many trades leaving one account, finds break-ins in minutes instead of days, while reversal is still possible.
How do I prevent break-ins beyond just detecting them?
Enforce strong passwords, offer a warehouse PIN/second factor, limit simultaneous sessions per account and never store passwords in plain text. Detection is the last line; prevention reduces the volume of cases.