Scam scanner
Key RequiredUniversal

Scam scanner

Universal ScriptDcruzRaceDcruzRace 2.5K views 65 executesUpdated Sep 30, 2025
3.8/ 5(8 votes)
6275% Positive
Lua Script•356 lines (13351 chars)
-- Scam Script Analyzer GUI with HTTP-spy (detects webhooks & URLs)
local Players = game:GetService("Players")
local player = Players.LocalPlayer

-- Main ScreenGui
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "ScamAnalyzerGUI"
screenGui.Parent = player:WaitForChild("PlayerGui")

-- === TOGGLE BUTTONS ===
local toggleBtn = Instance.new("TextButton")
toggleBtn.Size = UDim2.new(0, 120, 0, 40)
toggleBtn.Position = UDim2.new(1, -130, 0, 10)
toggleBtn.Text = "Toggle Analyzer"
toggleBtn.BackgroundColor3 = Color3.fromRGB(0, 170, 255)
toggleBtn.TextColor3 = Color3.fromRGB(255, 255, 255)
toggleBtn.Font = Enum.Font.SourceSansBold
toggleBtn.TextSize = 16
toggleBtn.Parent = screenGui

local historyToggleBtn = Instance.new("TextButton")
historyToggleBtn.Size = UDim2.new(0, 120, 0, 40)
historyToggleBtn.Position = UDim2.new(1, -130, 0, 60)
historyToggleBtn.Text = "Toggle History"
historyToggleBtn.BackgroundColor3 = Color3.fromRGB(170, 0, 255)
historyToggleBtn.TextColor3 = Color3.fromRGB(255, 255, 255)
historyToggleBtn.Font = Enum.Font.SourceSansBold
historyToggleBtn.TextSize = 16
historyToggleBtn.Parent = screenGui

-- === ANALYZER FRAME ===
local frame = Instance.new("Frame")
frame.Size = UDim2.new(0, 560, 0, 480)
frame.Position = UDim2.new(0.5, -280, 0.5, -240)
frame.BackgroundColor3 = Color3.fromRGB(30, 30, 30)
frame.Visible = false
frame.Parent = screenGui

local title = Instance.new("TextLabel")
title.Size = UDim2.new(1, 0, 0, 40)
title.BackgroundColor3 = Color3.fromRGB(50, 50, 50)
title.Text = "⚡ Scam Script Analyzer (with HTTP-spy) ⚡"
title.TextColor3 = Color3.fromRGB(255, 255, 255)
title.Font = Enum.Font.SourceSansBold
title.TextSize = 20
title.Parent = frame

local textBox = Instance.new("TextBox")
textBox.Size = UDim2.new(1, -20, 0, 220)
textBox.Position = UDim2.new(0, 10, 0, 50)
textBox.PlaceholderText = "Paste script here..."
textBox.TextWrapped = true
textBox.MultiLine = true
textBox.ClearTextOnFocus = false
textBox.TextXAlignment = Enum.TextXAlignment.Left
textBox.TextYAlignment = Enum.TextYAlignment.Top
textBox.TextSize = 16
textBox.TextColor3 = Color3.fromRGB(0, 0, 0)
textBox.BackgroundColor3 = Color3.fromRGB(245, 245, 245)
textBox.Font = Enum.Font.SourceSans
textBox.Parent = frame

local analyzeBtn = Instance.new("TextButton")
analyzeBtn.Size = UDim2.new(0, 220, 0, 40)
analyzeBtn.Position = UDim2.new(0.5, -110, 0, 280)
analyzeBtn.Text = "Analyze Script"
analyzeBtn.BackgroundColor3 = Color3.fromRGB(0, 170, 255)
analyzeBtn.TextColor3 = Color3.fromRGB(255, 255, 255)
analyzeBtn.Font = Enum.Font.SourceSansBold
analyzeBtn.TextSize = 20
analyzeBtn.Parent = frame

local resultLabel = Instance.new("TextLabel")
resultLabel.Size = UDim2.new(1, -20, 0, 100)
resultLabel.Position = UDim2.new(0, 10, 0, 330)
resultLabel.Text = "Result: Waiting..."
resultLabel.TextWrapped = true
resultLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
resultLabel.BackgroundColor3 = Color3.fromRGB(40, 40, 40)
resultLabel.Font = Enum.Font.SourceSansBold
resultLabel.TextSize = 16
resultLabel.TextXAlignment = Enum.TextXAlignment.Left
resultLabel.TextYAlignment = Enum.TextYAlignment.Top
resultLabel.Parent = frame

-- Trust Score Bar
local trustFrame = Instance.new("Frame")
trustFrame.Size = UDim2.new(1, -20, 0, 28)
trustFrame.Position = UDim2.new(0, 10, 0, 440)
trustFrame.BackgroundColor3 = Color3.fromRGB(60, 60, 60)
trustFrame.Parent = frame

local trustBar = Instance.new("Frame")
trustBar.Size = UDim2.new(0, 0, 1, 0)
trustBar.BackgroundColor3 = Color3.fromRGB(0, 170, 0)
trustBar.Parent = trustFrame

local trustText = Instance.new("TextLabel")
trustText.Size = UDim2.new(1, 0, 1, 0)
trustText.BackgroundTransparency = 1
trustText.Text = "Trust Score: 100%"
trustText.TextColor3 = Color3.fromRGB(255, 255, 255)
trustText.Font = Enum.Font.SourceSansBold
trustText.TextSize = 16
trustText.Parent = trustFrame

-- === HISTORY PANEL ===
local historyFrame = Instance.new("Frame")
historyFrame.Size = UDim2.new(0, 420, 0, 340)
historyFrame.Position = UDim2.new(0.5, 60, 0.5, -170)
historyFrame.BackgroundColor3 = Color3.fromRGB(20, 20, 20)
historyFrame.Visible = false
historyFrame.Parent = screenGui

local historyTitle = Instance.new("TextLabel")
historyTitle.Size = UDim2.new(1, 0, 0, 36)
historyTitle.BackgroundColor3 = Color3.fromRGB(80, 0, 120)
historyTitle.Text = "📜 Scan History"
historyTitle.TextColor3 = Color3.fromRGB(255, 255, 255)
historyTitle.Font = Enum.Font.SourceSansBold
historyTitle.TextSize = 18
historyTitle.Parent = historyFrame

local historyScrolling = Instance.new("ScrollingFrame")
historyScrolling.Size = UDim2.new(1, -12, 1, -48)
historyScrolling.Position = UDim2.new(0, 6, 0, 40)
historyScrolling.BackgroundColor3 = Color3.fromRGB(40, 40, 40)
historyScrolling.BorderSizePixel = 0
historyScrolling.ScrollBarThickness = 6
historyScrolling.CanvasSize = UDim2.new(0,0,0,0)
historyScrolling.Parent = historyFrame

local uiListLayout = Instance.new("UIListLayout")
uiListLayout.Padding = UDim.new(0, 6)
uiListLayout.Parent = historyScrolling

-- Storage for past scans (table of data)
local pastScans = {}

-- === HTTP-spy & Scam Detection ===
local function extractURLs(scriptText)
    local urls = {}
    -- basic URL pattern (http/https)
    for url in scriptText:gmatch("https?://[%w%p%%/-]+") do
        table.insert(urls, url)
    end
    -- also catch common webhook-looking fragments without protocol
    for frag in scriptText:gmatch("[wWw%.%w%-%_]+discord[%w%p/%%=-]+") do
        table.insert(urls, frag)
    end
    return urls
end

local function detectScam(scriptText)
    local scamIndicators, mediumIndicators = {}, {}
    local foundURLs = {}

    -- Obfuscation (long base64-like blobs)
    if scriptText:find("[A-Za-z0-9%+/=]{30,}") then
        table.insert(scamIndicators, "❌ Obfuscation detected (long encoded string)")
    end

    -- Suspicious require()
    for id in scriptText:gmatch("require%((%d+)%)") do
        local num = tonumber(id)
        if num and num > 500000 then
            table.insert(scamIndicators, "❌ Suspicious require() with Module ID: " .. id)
        else
            table.insert(mediumIndicators, "⚠️ Mildly suspicious require(): " .. id)
        end
    end

    -- High-risk function usage
    local highRisk = {
        "getfenv", "setfenv", "loadstring", "load%(", "dofile%(", "compile%(",
        "HttpGet", "HttpPost", "RequestAsync", "PostAsync", "GetAsync", "Request",
        "syn%.", "krnl", "scriptware", "fluxus", "exploit"
    }
    for _, pat in ipairs(highRisk) do
        if scriptText:lower():find(pat:lower()) then
            table.insert(scamIndicators, "❌ High-risk call: " .. pat)
        end
    end

    -- Medium-risk patterns
    local mediumRisk = {
        "while true do", "repeat until false",
        "script%.Parent%s*=%s*nil",
        "print%(\"this is not a scam\"%)", "warn%(\"safe\"%)",
        "math%.randomseed%(", "string%.reverse", "string%.char",
        "token", "webhook", "key", "password", "discord", "nitro", "robux", "free"
    }
    for _, pat in ipairs(mediumRisk) do
        if scriptText:lower():find(pat:lower()) then
            table.insert(mediumIndicators, "⚠️ Medium suspicious pattern: " .. pat)
        end
    end

    -- Malicious behavior
    local malicious = {
        "game%.Shutdown", "Player:Kick", "Players%.LocalPlayer:Kick",
        "CoreGui:Destroy", "StarterGui:ClearAllChildren",
        "DestroyAllChildren", "workspace:ClearAllChildren"
    }
    for _, pat in ipairs(malicious) do
        if scriptText:find(pat) then
            table.insert(scamIndicators, "❌ Malicious action: " .. pat)
        end
    end

    -- HTTP-spy: extract URLs and detect webhook patterns
    local urls = extractURLs(scriptText)
    for _, u in ipairs(urls) do
        -- normalize spacing
        local url = u:gsub("%s+", "")
        table.insert(foundURLs, url)
        local lower = url:lower()
        -- Discord webhook patterns
        if lower:find("discordapp%.com/api/webhooks") or lower:find("discord%.com/api/webhooks")
            or lower:find("discord.com/api/webhooks") or lower:find("/api/webhooks/") then
            table.insert(scamIndicators, "❌ Discord webhook URL detected: " .. url)
        else
            -- any external URL used in combination with Http* calls is suspicious
            if scriptText:lower():find("http") or scriptText:lower():find("request") or scriptText:lower():find("postasync") then
                table.insert(mediumIndicators, "⚠️ External URL detected: " .. url)
            end
        end
    end

    return mediumIndicators, scamIndicators, foundURLs
end

-- Trust Score
local function calculateTrustScore(mediumIndicators, scamIndicators)
    local score = 100
    score = score - (#mediumIndicators * 12) - (#scamIndicators * 35)
    if score < 0 then score = 0 end
    if score > 100 then score = 100 end
    return score
end

-- Utility: create history entry UI
local function addHistoryEntry(snippet, trustScore, statusColor, details)
    local entry = Instance.new("Frame")
    entry.Size = UDim2.new(1, -12, 0, 56)
    entry.BackgroundColor3 = Color3.fromRGB(45, 45, 45)
    entry.Parent = historyScrolling

    local label = Instance.new("TextLabel")
    label.Size = UDim2.new(0.7, 0, 1, 0)
    label.Position = UDim2.new(0, 8, 0, 0)
    label.BackgroundTransparency = 1
    label.Text = snippet
    label.TextXAlignment = Enum.TextXAlignment.Left
    label.TextYAlignment = Enum.TextYAlignment.Center
    label.TextColor3 = Color3.fromRGB(240,240,240)
    label.Font = Enum.Font.SourceSans
    label.TextSize = 14
    label.Parent = entry

    local scoreLabel = Instance.new("TextLabel")
    scoreLabel.Size = UDim2.new(0.25, -16, 1, 0)
    scoreLabel.Position = UDim2.new(0.7, 12, 0, 0)
    scoreLabel.BackgroundTransparency = 1
    scoreLabel.Text = trustScore .. "%"
    scoreLabel.TextColor3 = statusColor
    scoreLabel.Font = Enum.Font.SourceSansBold
    scoreLabel.TextSize = 16
    scoreLabel.Parent = entry

    -- Click to load back into analyzer and show details
    entry.Active = true
    entry.Selectable = true
    entry.MouseButton1Click = nil -- ensure not error
    entry.InputBegan:Connect(function(input)
        if input.UserInputType == Enum.UserInputType.MouseButton1 then
            textBox.Text = details.fullText or snippet
            -- force re-analyze so the user sees full info
            analyzeBtn:CaptureFocus()
            analyzeBtn:ReleaseFocus()
            -- we call analyze function directly to refresh result
            -- (simulate button click)
            analyzeBtn.MouseButton1Click:Connect(function() end) -- noop to ensure exists
            -- we'll just call the analyze function below via shared closure; simpler: trigger the click programmatically by firing the event
            -- but to avoid complexity, we'll populate text and let user press Analyze
        end
    end)

    table.insert(pastScans, entry)
    -- adjust canvas size
    historyScrolling.CanvasSize = UDim2.new(0, 0, 0, #pastScans * 62)
end

-- === Events ===
toggleBtn.MouseButton1Click:Connect(function()
    frame.Visible = not frame.Visible
end)

historyToggleBtn.MouseButton1Click:Connect(function()
    historyFrame.Visible = not historyFrame.Visible
end)

analyzeBtn.MouseButton1Click:Connect(function()
    local scriptText = textBox.Text or ""
    local mediumInd, scamInd, urls = detectScam(scriptText)
    local trustScore = calculateTrustScore(mediumInd, scamInd)

    -- Update Trust Bar
    trustBar:TweenSize(UDim2.new(trustScore/100, 0, 1, 0), "Out", "Quad", 0.35, true)
    trustText.Text = "Trust Score: " .. trustScore .. "%"

    -- Color the bar
    if trustScore >= 70 then
        trustBar.BackgroundColor3 = Color3.fromRGB(0, 170, 0)
    elseif trustScore >= 40 then
        trustBar.BackgroundColor3 = Color3.fromRGB(255, 200, 0)
    else
        trustBar.BackgroundColor3 = Color3.fromRGB(200, 0, 0)
    end

    -- Build result text with URL list
    local lines = {}
    if #scamInd > 0 then
        table.insert(lines, "❌ SCAM / MALICIOUS INDICATORS:")
        for _, s in ipairs(scamInd) do table.insert(lines, s) end
    end
    if #mediumInd > 0 then
        table.insert(lines, "\n⚠️ Medium suspicious indicators:")
        for _, m in ipairs(mediumInd) do table.insert(lines, m) end
    end
    if #urls > 0 then
        table.insert(lines, "\n🔗 Detected URLs:")
        for _, u in ipairs(urls) do table.insert(lines, u) end
    end
    if #scamInd == 0 and #mediumInd == 0 and #urls == 0 then
        table.insert(lines, "✅ No obvious scam or external HTTP usage detected.")
    end

    resultLabel.Text = table.concat(lines, "\n")
    -- Color result background
    if trustScore >= 70 then
        resultLabel.BackgroundColor3 = Color3.fromRGB(0, 170, 0)
    elseif trustScore >= 40 then
        resultLabel.BackgroundColor3 = Color3.fromRGB(255, 200, 0)
    else
        resultLabel.BackgroundColor3 = Color3.fromRGB(200, 0, 0)
    end

    -- Add to history (snippet + full details)
    local snippet = string.gsub(scriptText:gsub("\n"," "), "%s+", " ")
    if #snippet > 60 then snippet = snippet:sub(1, 60) .. "..." end
    addHistoryEntry(snippet, trustScore,
        (trustScore >= 70 and Color3.fromRGB(0,170,0)) or (trustScore >=40 and Color3.fromRGB(255,200,0)) or Color3.fromRGB(200,0,0),
        { fullText = scriptText }
    )
end)

Features & Information

Can Analyze and Search for scams in a Script and can we also added a HHTP spy requested by Nds_Ter

Community Comments (9)

DcruzRaceDcruzRaceSep 30, 2025

Tell me.if they're is any mistakes or if I should add any more features

DcruzRaceDcruzRaceSep 30, 2025

AI helped me make this because it is a tool it didn't make the full script

DcruzRaceDcruzRaceSep 30, 2025

Dislike it if you want

Replying to @DcruzRace
DcruzRaceDcruzRaceSep 30, 2025

I'm not giving y'all cheats rn

Replying to @DcruzRace
printiden*yprintiden*ySep 30, 2025

@DcruzRace hey, its cool, keep working.

printiden*yprintiden*ySep 30, 2025

it could've be better without AI, but still okay.

Replying to @printiden*y
DcruzRaceDcruzRaceSep 30, 2025

@printideny I could have lied to you and said it wasn't AI thanks for commenting tho

DcruzRaceDcruzRaceSep 30, 2025

Don't forget I added original scripts so don't comment AI slop Slop is if its entirely made by AI

FraihnLolFraihnLolNov 15, 2025

peak script, one of the best out there in my opinion ngl

More Scripts for Universal Scripts