Commit 0d6bf607 by devttys0

Initial low-priv execution implementation

parent 04990193
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import os import os
import re import re
import pwd
import stat import stat
import shlex import shlex
import tempfile import tempfile
...@@ -47,6 +48,9 @@ class Extractor(Module): ...@@ -47,6 +48,9 @@ class Extractor(Module):
# squashfs-root-0). # squashfs-root-0).
UNIQUE_PATH_DELIMITER = '%%' UNIQUE_PATH_DELIMITER = '%%'
# Unprivileged user account to execute external extraction utilities
UNPRIVILEGED_USER_NAME = 'binwalksafe'
TITLE = 'Extraction' TITLE = 'Extraction'
ORDER = 9 ORDER = 9
PRIMARY = False PRIMARY = False
...@@ -121,6 +125,10 @@ class Extractor(Module): ...@@ -121,6 +125,10 @@ class Extractor(Module):
] ]
def load(self): def load(self):
user_info = pwd.getpwnam(self.UNPRIVILEGED_USER_NAME)
self.unpriv_uid = user_info.pw_uid
self.unpriv_gid = user_info.pw_gid
# Holds a list of extraction rules loaded either from a file or when # Holds a list of extraction rules loaded either from a file or when
# manually specified. # manually specified.
self.extract_rules = [] self.extract_rules = []
...@@ -534,6 +542,9 @@ class Extractor(Module): ...@@ -534,6 +542,9 @@ class Extractor(Module):
else: else:
output_directory = self.extraction_directories[path] output_directory = self.extraction_directories[path]
# Make sure unpriv user can access this directory
os.chown(output_directory, self.unpriv_uid, self.unpriv_gid)
return output_directory return output_directory
def cleanup_extracted_files(self, tf=None): def cleanup_extracted_files(self, tf=None):
...@@ -826,6 +837,9 @@ class Extractor(Module): ...@@ -826,6 +837,9 @@ class Extractor(Module):
# Cleanup # Cleanup
fdout.close() fdout.close()
fdin.close() fdin.close()
# Make sure unprivileged user can access this file
os.chown(fname, self.unpriv_uid, self.unpriv_gid)
except KeyboardInterrupt as e: except KeyboardInterrupt as e:
raise e raise e
except Exception as e: except Exception as e:
...@@ -873,8 +887,7 @@ class Extractor(Module): ...@@ -873,8 +887,7 @@ class Extractor(Module):
# Generate unique file paths for all paths in the current # Generate unique file paths for all paths in the current
# command that are surrounded by UNIQUE_PATH_DELIMITER # command that are surrounded by UNIQUE_PATH_DELIMITER
while self.UNIQUE_PATH_DELIMITER in cmd: while self.UNIQUE_PATH_DELIMITER in cmd:
need_unique_path = cmd.split(self.UNIQUE_PATH_DELIMITER)[ need_unique_path = cmd.split(self.UNIQUE_PATH_DELIMITER)[1].split(self.UNIQUE_PATH_DELIMITER)[0]
1].split(self.UNIQUE_PATH_DELIMITER)[0]
unique_path = binwalk.core.common.unique_file_name(need_unique_path) unique_path = binwalk.core.common.unique_file_name(need_unique_path)
cmd = cmd.replace(self.UNIQUE_PATH_DELIMITER + need_unique_path + self.UNIQUE_PATH_DELIMITER, unique_path) cmd = cmd.replace(self.UNIQUE_PATH_DELIMITER + need_unique_path + self.UNIQUE_PATH_DELIMITER, unique_path)
...@@ -885,9 +898,22 @@ class Extractor(Module): ...@@ -885,9 +898,22 @@ class Extractor(Module):
# command with fname # command with fname
command = command.strip().replace(self.FILE_NAME_PLACEHOLDER, fname) command = command.strip().replace(self.FILE_NAME_PLACEHOLDER, fname)
# Fork a child to drop privs
child_pid = os.fork()
if child_pid is 0:
# Switch to unprivileged user
binwalk.core.common.debug("Dropping privileges to user '%s'" % self.UNPRIVILEGED_USER_NAME)
os.setgid(self.unpriv_uid)
os.setuid(self.unpriv_gid)
# Execute external extractor
binwalk.core.common.debug("subprocess.call(%s, stdout=%s, stderr=%s)" % (command, str(tmp), str(tmp))) binwalk.core.common.debug("subprocess.call(%s, stdout=%s, stderr=%s)" % (command, str(tmp), str(tmp)))
rval = subprocess.call(shlex.split(command), stdout=tmp, stderr=tmp) rval = subprocess.call(shlex.split(command), stdout=tmp, stderr=tmp)
sys.exit(rval)
else:
rval = os.wait()
# Check the return value to see if extraction was successful or not
if rval in codes: if rval in codes:
retval = True retval = True
else: else:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment