a deep dive into my HWID ban system
August 22, 2022 (3y ago)
this was a creation of a hwid (hardware id) ban system for a harry potter game on roblox. back when exploiting was the norm, i needed a solid plan to keep my game fair and fun.
the spark for this project came from a github repo, which was all about tracking users across accounts on roblox.
the core idea? use os.clock()
to get a unique time count since the cpu started, basically a fingerprint for each machine.
let's dive into the rongoData
script, the heartbeat of our system.
this script was like the central hub, managing our mongoDB database interactions.
when a player joined, the serverData
event would fire up, kicking our script into action.
Player Hook
this little snippet starts the whole process. when a player hops into the game, it fetches their unique fingerprint—a mix of the hardware id and other data points.
all the data points
- CPU Start:
tick() - os.clock()
- Timezone:
os.date("%Z")
- Is Daylight Savings Time:
os.date("*t").isdst
- Has Accelerometer:
UserInputService.AccelerometerEnabled
- Has Touchscreen:
UserInputService.TouchEnabled
next, we checked this fingerprint against our database. if the player had any linked accounts (ones with the same fingerprint), we updated the account lists for all those users. the kicker? changing your hardware id later wouldn't help; once an account was linked, it stays that way.
Document Fetch
Document Updation
Aggregation and Analysis
this bit aggregated all data relevant to a player's fingerprint. it was like putting together a puzzle, finding which accounts were connected.
Data Structure
the database was structured to store detailed information about each player, including their unique hardware fingerprint and any linked accounts. here's a simplified view:
userId
: unique identifier for each player.username
: the player's roblox username.fingerprint
: unique hardware id, a blend of various hardware and system characteristics.flagged
: boolean indicating if the account is flagged (for exploiting, alt account, etc.).accountList
: a collection of linked accounts (identified through the fingerprint).
this structure allowed me to keep track of individual players and any potential alternate accounts they might be using.
Aggregation Pipeline
the aggregation pipeline was where the heavy lifting happened. it was designed to process and analyze player data to find linked accounts. here's a glimpse into the steps involved:
-
Matching Stage: using the
$match
operator, we filtered documents based on the user'suserId
orfingerprint
. this was the initial step to narrow down relevant documents. -
Projection Stage: with
$project
, we transformed the data to include the number of accounts linked (numAccounts
), along with other relevant fields likeflagged
,username
, and theaccountList
. -
Sorting Stage: next,
$sort
helped us order the documents by the number of linked accounts in descending order - the idea was to prioritize documents with more links. -
Limiting Stage: finally,
$limit
was used to restrict the number of documents processed, ensuring efficiency and focus on the most relevant data.
this pipeline was key to identifying and linking accounts. by processing data this way, we could efficiently flag exploiters and alt accounts and update linked accounts.
the journey of building this system was a rollercoaster.
Current State
fast forward to now, and this system seems like overkill. roblox's security game is strong, and exploiting isn't what it used to be. plus, with big players like synapse exiting the stage, the landscape's really changed.
if you want to see the current state of exploiting, take a look at this.