Jump to content




Modify FS Root in an Unrevertable Way


  • You cannot reply to this topic
17 replies to this topic

#1 The Crazy Phoenix

  • Members
  • 136 posts
  • LocationProbably within 2 metres of my laptop.

Posted 16 June 2015 - 05:00 PM

Assume I were programming an OS, and I wanted to change the root directory. I could do this by overwriting all FS API functions. However, this can be bypassed by another program.

Thought of but invalid solutions:
  • Overwrite functions. Bypass Method: Mentioned earlier.
  • Make a local function performing all the changes and overwrite the global one to call the local one. Bypass Method: Append "../" to the start of the file name string.
  • Load it into executed programs as an environment variable. Bypass Method: Overwrite and then run shell.
Please no solutions involving rom modifications.

#2 Creator

    Mad Dash Victor

  • Members
  • 2,168 posts
  • LocationYou will never find me, muhahahahahaha

Posted 16 June 2015 - 08:32 PM

Well, do this:
path = string.find(newroot,fs.combine(newroot,path)) and fs.combine(newroot,path) or newroot

That way you'll be sure they aint bypassing anything.

#3 valithor

  • Members
  • 1,053 posts

Posted 16 June 2015 - 08:50 PM

View PostCreator, on 16 June 2015 - 08:32 PM, said:

Well, do this:
path = string.find(newroot,fs.combine(newroot,path)) and fs.combine(newroot,path) or newroot

That way you'll be sure they aint bypassing anything.

Unfortunately that line of code will always return newroot. Seeing as string.find(newroot,fs.combine(newroot,path)) will always return nil only time it wouldn't is if path was "", which would still make the line of code return newroot.

You will want to overwrite all of the fs functions following roughly the same format.
-- example of fs.open
local oldOpen = fs.open
local combine = fs.combine
newroot = "this/is/a/file/path/to/the/new/root"

fs.open = function(path,...)
  -- you would likely want checks here to make sure path is a string.
  path = combine(newroot,path)
  local s,e = path:find(newroot)
  path = e and e<=#newroot and path or combine(newroot,path)
  return oldOpen(path,...)
end



edit:
Now that I look back on this I noticed another thing I should fix.

local oldOpen = fs.open
local combine = fs.combine
local lType = type
local err = error
newroot = "this/is/a/file/path/to/the/new/root"

fs.open = function(path,...)
  if lType(path) == "string" then
	path = combine("/",path) --# gets rid of all the ".."'s
	path = combine(newroot,path)
	return oldOpen(path,...)
  else
	err("Expected String, String")
  end
end

Edited by valithor, 17 June 2015 - 02:51 AM.


#4 Creator

    Mad Dash Victor

  • Members
  • 2,168 posts
  • LocationYou will never find me, muhahahahahaha

Posted 16 June 2015 - 08:55 PM

path could be "../i/am/at/the/real/root" -- these ".." make it go up a dir.

#5 valithor

  • Members
  • 1,053 posts

Posted 16 June 2015 - 08:57 PM

View PostCreator, on 16 June 2015 - 08:55 PM, said:

path could be "../i/am/at/the/real/root" -- these ".." make it go up a dir.

fs.combine automatically handles ".."'s

edit:

and now I said that I noticed i messed up lol I will fix it a sec.

Edited by valithor, 16 June 2015 - 08:58 PM.


#6 The Crazy Phoenix

  • Members
  • 136 posts
  • LocationProbably within 2 metres of my laptop.

Posted 16 June 2015 - 10:28 PM

I mentioned that solution in the first post and said that it could be bypassed using ".."

Maybe I could remove all preceding ".." components or error if they're there...

#7 MKlegoman357

  • Members
  • 1,170 posts
  • LocationKaunas, Lithuania

Posted 16 June 2015 - 10:56 PM

Like valithor already mentioned, fs.combine deals with "..", a single fs.combine( rootPath, userGivenPath ) is enough.

#8 valithor

  • Members
  • 1,053 posts

Posted 17 June 2015 - 02:41 AM

View PostCrazyPyroEagle, on 16 June 2015 - 10:28 PM, said:

I mentioned that solution in the first post and said that it could be bypassed using ".."

Maybe I could remove all preceding ".." components or error if they're there...

The one I posted deals with the ".."'s. The first time it calls fs.combine it combines the root and the path, which gets rid of all of the ".."'s. The only problem is at this point it could be at a higher point in the root directory than you want them to, so that is what the second combine call is for. It checks to see if the new root path is even in the path anymore and if it isn't it adds it back.

Even if you did remove them or error if they are there, nothing says they have to be at the beginning.
"../hi" would go up a directory, but so would: "/hi/../../hi"

I urge you to at least try out the code I posted. I am fairly certain you won't be able to break out of the new root with it.

View PostMKlegoman357, on 16 June 2015 - 10:56 PM, said:

Like valithor already mentioned, fs.combine deals with "..", a single fs.combine( rootPath, userGivenPath ) is enough.

Unfortunately a single fs.combine call leaves open the possibility of them getting out of the new root.

Example:
fs.combine("this/is/the/new/root","../../../../hi")
This would return "/hi" instead of "this/is/the/new/root/hi", which wouldn't be what he is wanting.

That is why I had two combine calls in my example. One to get rid/handle all of the ..'s and then the second one to actually add the new root.

Edited by valithor, 17 June 2015 - 02:52 AM.


#9 The Crazy Phoenix

  • Members
  • 136 posts
  • LocationProbably within 2 metres of my laptop.

Posted 17 June 2015 - 12:02 PM

Wow thank you for the great solution, I'll try it in a minute...

Edit: Shouldn't I also overwrite _G.fs[func] to prevent bypassing?

Edited by CrazyPyroEagle, 17 June 2015 - 12:04 PM.


#10 flaghacker

  • Members
  • 655 posts

Posted 17 June 2015 - 01:38 PM

View PostCrazyPyroEagle, on 17 June 2015 - 12:02 PM, said:

Wow thank you for the great solution, I'll try it in a minute...

Edit: Shouldn't I also overwrite _G.fs[func] to prevent bypassing?

No, you don't need to overwrite stuff in _G explicitly. When you modify fs, you're actually modifying _G.fs .

#11 The Crazy Phoenix

  • Members
  • 136 posts
  • LocationProbably within 2 metres of my laptop.

Posted 17 June 2015 - 05:08 PM

It turns out that valithor's solution doesn't quite work. I will post on Pastebin a functional function (lol) and comment a few details soon.

#12 ardera

  • Members
  • 503 posts
  • LocationGermany

Posted 17 June 2015 - 05:54 PM

local newpath = fs.combine(root, fs.combine("/", path))
First it takes away the preceeding up-directory indexes (fs.combine("/", "../hey") -> "hey), and then it combines the safe path with the root. Should work.

Edited by ardera, 17 June 2015 - 05:56 PM.


#13 The Crazy Phoenix

  • Members
  • 136 posts
  • LocationProbably within 2 metres of my laptop.

Posted 17 June 2015 - 06:05 PM

It doesn't take away the preceeding up-directory indexes, that's the problem.

#14 MKlegoman357

  • Members
  • 1,170 posts
  • LocationKaunas, Lithuania

Posted 17 June 2015 - 06:57 PM

Please post an example of code which does not work.

#15 The Crazy Phoenix

  • Members
  • 136 posts
  • LocationProbably within 2 metres of my laptop.

Posted 17 June 2015 - 07:02 PM

Just look at the code valithor posted (the two fs.combine lines). I can't currently poste code snippets because of a forum bug I'm experiencing.

#16 MKlegoman357

  • Members
  • 1,170 posts
  • LocationKaunas, Lithuania

Posted 17 June 2015 - 07:04 PM

You can simply press the top-left button in the editor to go to the "editing mode", in which nothing gets messed up.

EDIT: I think I know what you mean. For some reason doing:

fs.combine("", ",,/path") --> ",,/path" # for some reason the forums doesn't let me use dots, so pretend that commas are dots..

simply returns the path. That's strange, I don't really remember fs.combine acting like this..

Edited by MKlegoman357, 17 June 2015 - 07:11 PM.


#17 valithor

  • Members
  • 1,053 posts

Posted 18 June 2015 - 12:38 AM

Interesting I did not remember fs.combine working that way either, but either way it is a relatively simple fix.

local oldOpen = fs.open
local combine = fs.combine
local lType = type
local err = error
newroot = "this/is/a/file/path/to/the/new/root"

fs.open = function(path,...)
  if lType(path) == "string" then
		path = combine("/",path):gsub("%.%./?","") --# gets rid of all the ".."'s
		path = combine(newroot,path)
		return oldOpen(path,...)
  else
		err("Expected String, String")
  end
end

The gsub just removes any extra "../"'s that might be present, since at that point there shouldn't be any anyway.

Edited by valithor, 18 June 2015 - 12:39 AM.


#18 The Crazy Phoenix

  • Members
  • 136 posts
  • LocationProbably within 2 metres of my laptop.

Posted 18 June 2015 - 01:16 PM

Thank you to all who helped!





3 user(s) are reading this topic

0 members, 3 guests, 0 anonymous users