Loud music exploit keeps happening despite everything being heavily secured and in check

  1. What do you want to achieve? Keep it simple and clear!

I want to get to the bottom of combating an exploit that seems to be simply too persistent. No matter what we have tried the exploit somehow still manages to go through.

  1. What is the issue? Include screenshots / videos if possible!

There is an exploiter (or possible more) that keep targeting a car driving game I am working for, and I happen to be the one that scripts it all. The exploit is the insertion of a foreign sound object into the workspace of the game that plays bypassed music loudly for everyone.


image

A loop I ran in the workspace found this audio which silenced the music. From this image alone I deducted that the exploiter could choose a name, pitch, and SoundId for the object, which is plenty of freedom.

I want to add that one of our developers did have an infected plugin that inserted a backdoor script in the past, but that has been addressed long ago and the current build of the game is clean from suspicious scripts with obfuscated code or weird require() calls.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I looked through the entire game using CTRL+Shift+F to find items related to Instance.new, getfenv, require, etc but came up empty handed. Currently everything audio related is managed by server and the client can only choose things like a radio station, engine, and so on, not audios and properties directly.

There is also zero instances of Instance.new() being able to be used freely, and the only Instance.new(“Sound”) in the game is in a local script that gets an OnClientEvent from the gun system, the hypothetical scenario of the exploiter changing the guns sound ID then firing it to trigger the client event has been tested and only the offender was affected, rest hearing regular gunshots.

When spawning a car, the car comes with a set of sound objects placed already to avoid needing to use Instance.new(), and the IDs for it are taken from the cars module script, not a local script. The server side script that manages the volume and pitch also go through a math.clamp().

The custom car radio we have is also heavily secured, the server-side script limiting the volume between 0 and 3, only allowing a custom ID and only goes forth if the player has a gamepass, which gets prompted to buy if they don’t have it… the range of the sound is also small.

We also use an admin system called Adonis, which i confirmed twice with the owner that its the official one, having checked myself the modules it requires and comparing it with the official one from Epix Incorporated.

The obvious SoundService.RespectFilteringEnabled is checked and loadstring() is not enabled.

I tried to look on the devforum for answers but none have fixed the issue.

In summary:

  • RespectFilteringEnabled and loadstring() are as they should be
  • No remote event ingame that can freely create sound objects on client request
  • Only one case of remote event which can change SoundId of a cars radio, but that is heavily secured
  • Exploiter somehow inserts a sound object into workspace with a custom name, pitch and SoundId that can be heard by everyone loudly while no ingame feature or RemoteEvent offers such large freedom.

Our current plan is possibly replacing Adonis with a custom admin system but I really doubt Adonis would have vulnerabilities as heavy as this, plus their music command places sounds in SoundService not workspace. All of this is concerning and I don’t know where to look anymore.

Edit: I got the Adonis main module and forked its sound related commands, purposely breaking them so they don’t work and throw an error instead, and then made the Adonis loader use the forked module instead of the official live one. These loud music cases I get from the players seem to have stopped from a sudden…? I will give it some time and make a second edit if the loud music exploit cases happen again, it could be a coincidence.

Edit 2: It still happens, Adonis is not it. The exploiter can even choose where to put the sound, I don’t know anymore what could be causing this.

2 Likes

premade admin systems are never a good idea to have in game

i would just make a custom one

The only (reasonable) way that this exploit could occur is due to a backdoor script/plugin or a remote event that plays sound through the server. Are you sure you don’t have any remote events connected to playing sounds on the server?

I am looking at it for the seventh time now I believe.


all possible cases of a sound object being created.

local char = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()

game.ReplicatedStorage.RemoteStuff.DistantGunshot.OnClientEvent:Connect(function(Soundd, Vol, Pos, MaxRange)
	
	local SoundPart = Instance.new("Part")
	SoundPart.CanCollide = false
	SoundPart.CanQuery = false
	SoundPart.Anchored = true
	SoundPart.Transparency = 1
	SoundPart.Parent = workspace
	local Sound = Instance.new("Sound")
	Sound.Parent = SoundPart
	Sound.RollOffMaxDistance = MaxRange
	Sound.RollOffMode = Enum.RollOffMode.Linear
	Sound.SoundId = Soundd
	SoundPart.Position = Pos
	local Distance = (workspace.CurrentCamera.CFrame.Position - Pos).Magnitude
	if Distance > 250 then
		wait(Distance / 700)
	end
	Sound:Play()
	Sound.Ended:Wait()
	SoundPart:Destroy()
	
end)

This is the local script, the gun has a sound object which uses its ID to fire this remote event to all clients in a 3D position to play a long range distant gunshot sound when the gun is fired. As stated above i tried setting on client this Sound to a different one then firing, but others still heard gunshots while only i heard music, so this is not the case.

script.Parent.RemoteContainer.SnapSound.Event:Connect(function(Ps)
	
	local prt = Instance.new("Part")
	prt.Position = Ps
	prt.Transparency = 1
	prt.CanCollide = false
	prt.Anchored = true
	prt.Parent = workspace
	prt.Size = Vector3.new(.1,.1,.1)
	local sond = Instance.new("Sound")
	sond.Parent = prt
	sond.SoundId = "rbxassetid://6113434368"
	sond.Volume = 2
	sond.RollOffMode = Enum.RollOffMode.InverseTapered
	sond.RollOffMaxDistance = 35
	sond:Play()
	sond.Ended:Wait()
	prt:Destroy()
	
end)

This is the server side playing a bullet snap sound at where a shot lands, no client input here.


Rest are server side scripts setting their own Sound Id’s from server side sources, like the radio stations on the car radio.


About backdoors there’s nothing, require() calls are all just Datastore2 getting mentioned, Cars getting their module script, etc., I did not skim through it, i actually scrolled through.

The game has had this issue for a long time, I decided to halt updates for 2 years to rewrite it from the ground up with this exact issue in mind to be prevented, but its still happening even after all of this securing and checking.

is there a way that they can fire game.ReplicatedStorage.RemoteStuff.DistantGunshot

What game is it you’re working for? Maybe you can try to reverse-engineer public exploits. I took a look at your profile and did some digging… if it’s Vehicle Legends, then I found this repo with obfuscated code:

https://gitlab.com/D3athFeather/Script/-/blob/main/Protected_00931243a3ed8799d723b950.lua?ref_type=heads

1 Like

Obfuscated script somewhere is my guess.

No, that event is fired by server towards client, not from client to server. There is no OnServerEvent connected to it.

Its Southern Ontario, which recently got a revamp.

Hayo, sorry to hear about your troubles!

I help maintain Adonis, I can say that the chance it is Adonis is very unlikely, we’ve never seen an actual report in recent years of random access gained without something else being present already. There is a lot of misinformation out there.

Based on the information you have provided though, I can say that your cause likely is the A-Chassis Tune system. If you have not already patched it, that is. The reason it did not show up in your search is because the Sound creation system also parents in the Instance.new() method.

image

In the A-Chassis system, the audio system is completely unsecured by default. Allowing anyone to play any sound, any volume, any pitch, anywhere with no cooldowns.

image

A potential fix is to both limit what sounds can be passed through, verify the person calling the remote is the actual driver, and limiting sound inputs. I have a version of mine already written up & secured if you are interested, it would require some modifications if you use more sounds in your cars.

For example,
image

Cheers!

1 Like

Thanks for the reply! Unfortunately this is not the issue since we knew about it a long long time ago, our A-Chassis cars use a different engine sound system that does not allow the client such dangerous freedom with sounds.

Client:

local Rev = script.Parent:WaitForChild("Values"):WaitForChild("RPM")
local Boost = script.Parent:WaitForChild("Values"):WaitForChild("Boost")
local Gear = script.Parent:WaitForChild("Values"):WaitForChild("Gear")
local Car = script.Parent:WaitForChild("Car").Value
local IsOn = script.Parent:WaitForChild("IsOn")
local throt = script.Parent:WaitForChild("Values"):WaitForChild("Throttle")
local throtdb = false
game:GetService("RunService").Heartbeat:Connect(function()
	
	if Car.Ignition.Value == "On" then
		IsOn.Value = true
	else
		IsOn.Value = false
	end
	Car.DriveSeat.UpdateES:FireServer(Rev.Value / 20000, Boost.Value, script.Parent:WaitForChild("Values"):WaitForChild("Throttle").Value / 70, Gear.Value, Rev.Value)
	
end)

throt.Changed:Connect(function()
	if throt.Value < .5 and not throtdb then
		throtdb = true
		Car.DriveSeat.UpdateES.BOVGo:FireServer(Boost.Value)
	elseif throt.Value >= .5 and throtdb then
		throtdb = false
	end
end)

Server:

local TuneScript = require(script.Parent.Parent.Parent["A-Chassis Tune"])
local tn = TuneScript[1]()
local TopRPM = tn["Redline"]
script.Parent.OnServerEvent:Connect(function(plr, Bonus, PSI, Throttle, Gear, RPM)
	local NormalizedRev = (RPM / (TopRPM - script.RangeModifier.Value))
	script.Parent.Parent.Parent.LiveRPM.Value = RPM
	script.Parent.Parent.Parent.LiveGear.Value = Gear
	script.Parent.Parent.Parent.Body.EngineBlock.Rev.PlaybackSpeed = script.EngBasePS.Value + ((NormalizedRev / script.PitchDecimator.Value) + (Throttle / 4))
	script.Parent.Parent.Parent.Body.EngineBlock.Rev.Volume = math.clamp(script.EngBaseVol.Value + (NormalizedRev * script.MaxEngVol.Value), 0, script.MaxEngVol.Value)
	script.Parent.Parent.Parent.Body.EngineBlock.Idling.Volume = math.clamp(script.MaxIdVol.Value - ((NormalizedRev * script.IdleDecimator.Value) * script.MaxIdVol.Value), 0, script.MaxIdVol.Value)
	script.Parent.Parent.Parent.Body.EngineBlock.Turbo.Volume = PSI / 30
	script.Parent.Parent.Parent.Body.EngineBlock.Turbo.PlaybackSpeed = PSI / 5
	if Gear == -1 then
		script.Parent.Parent.Parent.Body.EngineBlock.ReverseGear.PlaybackSpeed = .3 + (script.Parent.Parent.AssemblyLinearVelocity.Magnitude / 50)
		script.Parent.Parent.Parent.Body.EngineBlock.ReverseGear.Volume = math.clamp(-.01 + (script.Parent.Parent.AssemblyLinearVelocity.Magnitude / 50), 0, 2)
	else
		script.Parent.Parent.Parent.Body.EngineBlock.ReverseGear.PlaybackSpeed = 0
		script.Parent.Parent.Parent.Body.EngineBlock.ReverseGear.Volume = 0
	end
end)
script.Parent.BOVGo.OnServerEvent:Connect(function(plr, Boost)
	script.Parent.Parent.Parent.Body.EngineBlock.Bov.Volume = Boost / 65
	script.Parent.Parent.Parent.Body.EngineBlock.Bov:Play()
end)

The entire sound system is designed with pre-inserted sound objects so the remote only accepts car related values like RPM, Boost, Throttle, etc. and the most it can control is Volume, Playbackspeed and Pitch. In my edit i did not mean to claim Adonis has a vulnerability, its probably not even that, the exploiter just oddly stopped doing its antics after I forked the module to break all sound related commands on purpose, very likely a coincidence.

Edit: Nevermind, it still happens.

Darn!

Was hoping it’d be an easy solution.
Do you see people doing anything else besides playing arbitrary sounds?

Things that would point to there being a backdoor, for example like random assets being inserted, world maps messed up, random players bragging about it?
If it’s just audios, it could very likely be messed up logic in a remote or multiple things in combination to modify existing sounds.

You could try logging remote activity to see if you can narrow down what remote they may be using, assuming it’s not a RemoteFunction.

I would be happy to provide an Adonis plugin you can plop into your game that would allow for this kind of logging temporarily while you work to solve it.

Cheers!

Sound like they are changing the sound settings itself… Maybe create that or call it by ID and not just place a sound part in a place it can be accessed.

I actually tried to search for a way to simulate a remote logger (sort of like RemoteSpy) for developer use but so far only found a studio plugin that does not offer any use in real game. A way to track activity of ingame remotes outside of studio would help a ton narrowing down what exactly this exploiter is doing and would greatly appreciate it.

Could you show code snippets of where this remote is being fired?

Another point of interest could be the radio. Having a volume cap of 3 is pretty generous considering some bypassed audios are insanely loud at just 0.5. Also how are you determining the range? You could temporarily reduce the cap to 0.5. If you notice the volume of the exploiters audio feeling quieter then it could be something with the radio.

The cap to 3 is just the beginning of it, for the remote to even consider doing its function, the following conditions need to be true:

  • The player instance firing it needs to be the driver seats “Occupant”
  • The player needs to own a gamepass, else :UserOwnsGamepassAsync() returns false

The car radios dont have a huge range, they are typically muffled when outside and youll stop hearing them after a few steps away.

As for the distant gunshot, i am not at my laptop right now but the remote is being fired from a server script inside a tool towards the client, its purpose is for the client to create a sound of a distant gushot echo instead of server to mitigate tbe limits of streaming enabled. I tested one possible scenario where the exploiter could change the SoundIDs of the sounds inside the tool and trick it like that, but for others shooting still sounded like regular gunshots with only me hearing music.