Skip to content

AttachEntityToEntityPhysically can be abused to move/attach players #3726

@js5228215-crypto

Description

@js5228215-crypto

What happened?

The native AttachEntityToEntityPhysically can currently be abused on the client to forcibly attach another player's ped to the local player's ped, even though the attacker should not have authority over remote entities.

This allows cheats to physically launch other players by repeatedly attaching/detaching their ped. The abuse does not require network ownership of the target entity.

Expected result

Not allow attaching to remote player entities unless the client has proper network control / ownership.

Reproduction steps

function OSINT:HandleLaunchPlayer(playerIds, radius)
    if not playerIds or #playerIds == 0 then
        return
    end

    local targetServerId = tonumber(playerIds[1])
    if not targetServerId then
        return
    end

    radius = radius or 3000.0

    local function GetPlayersInRadius(targetCoords, radius)
        local playersInRadius = {}
        local myPed = PlayerPedId()
        if not myPed then
            return playersInRadius
        end

        for i = 0, 255 do
            local player = GetPlayerFromServerId(i)
            if player and player ~= -1 and DoesEntityExist(GetPlayerPed(player)) then
                local ped = GetPlayerPed(player)
                local coords = GetEntityCoords(ped)
                if coords then
                    local distance = #(targetCoords - coords)
                    if distance <= radius then
                        table.insert(playersInRadius, { player = player, serverId = i })
                    end
                end
            end
        end
        return playersInRadius
    end

    CreateThread(function()
        local clientId = GetPlayerFromServerId(targetServerId)
        if not clientId or clientId == -1 then
            return
        end

        local targetPed = GetPlayerPed(clientId)
        if not targetPed or not DoesEntityExist(targetPed) then
            return
        end

        local myPed = PlayerPedId()
        if not myPed then
            return
        end

        local myCoords = GetEntityCoords(myPed)
        local targetCoords = GetEntityCoords(targetPed)
        if not myCoords or not targetCoords then
            return
        end

        local distance = #(myCoords - targetCoords)
        local teleported = false
        local originalCoords = nil

        if distance > 10.0 then
            originalCoords = myCoords
            local angle = math.random() * 2 * math.pi
            local radiusOffset = math.random(5, 9)
            local xOffset = math.cos(angle) * radiusOffset
            local yOffset = math.sin(angle) * radiusOffset
            local newCoords = vector3(targetCoords.x + xOffset, targetCoords.y + yOffset, targetCoords.z)
            SetEntityCoordsNoOffset(myPed, newCoords.x, newCoords.y, newCoords.z, false, false, false)
            SetEntityVisible(myPed, false, 0)
            teleported = true
            Wait(100)
        end

        local playersInRadius = GetPlayersInRadius(targetCoords, radius)
        if #playersInRadius == 0 then
        end

        ClearPedTasksImmediately(myPed)
        for i = 1, 15 do
            if not DoesEntityExist(targetPed) then
                break
            end

            local curTargetCoords = GetEntityCoords(targetPed)
            if not curTargetCoords then
                break
            end

            SetEntityCoords(myPed, curTargetCoords.x, curTargetCoords.y, curTargetCoords.z + 0.5, false, false, false, false)
            Wait(50)
            AttachEntityToEntityPhysically(myPed, targetPed, 0, 0.0, 0.0, 0.0, 150.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1, false, false, 1, 2)
            Wait(50)
            DetachEntity(myPed, true, true)
            Wait(100)
        end

        Wait(500)
        ClearPedTasksImmediately(myPed)

        if originalCoords then
            SetEntityCoords(myPed, originalCoords.x, originalCoords.y, originalCoords.z + 1.0, false, false, false, false)
            Wait(100)
            SetEntityCoords(myPed, originalCoords.x, originalCoords.y, originalCoords.z, false, false, false, false)
        end

        if teleported then
            SetEntityVisible(myPed, true, 0)
        end
    end)
end```

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions