Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements needed to run /bin/id from binutils #93

Open
thealberto opened this issue Apr 28, 2022 · 8 comments
Open

Improvements needed to run /bin/id from binutils #93

thealberto opened this issue Apr 28, 2022 · 8 comments
Labels
env/emulation Everything related to emulation of the environment (file system, syscalls, library emulation, ...) Good first issue Good issue to get started and contribute to Maat

Comments

@thealberto
Copy link

Hi,
I would like to use maat with simple projects but I have troubles running, for instance, id. My code is the following:

from maat import *
m = MaatEngine(ARCH.X64, OS.LINUX)  
m.load("/bin/id", BIN.ELF64, libdirs=["/usr/lib/x86_64-linux-gnu/"])
m.run()

and the output is the following

➜  maat python3 id.py
[Info] Adding object 'ld-linux-x86-64.so.2' to virtual fs at '/usr/lib/ld-linux-x86-64.so.2'
[Info] Adding object 'libc.so.6' to virtual fs at '/usr/lib/libc.so.6'
[Info] Adding object 'libdl.so.2' to virtual fs at '/usr/lib/libdl.so.2'
[Info] Adding object 'libpcre2-8.so.0' to virtual fs at '/usr/lib/libpcre2-8.so.0'
[Info] Adding object 'libpthread.so.0' to virtual fs at '/usr/lib/libpthread.so.0'
[Info] Adding object 'libselinux.so.1' to virtual fs at '/usr/lib/libselinux.so.1'
[Info] Adding object 'id' to virtual fs at '/id'
[Error] Exception in CALLOTHER handler: SYSCALL: EnvEmulator: syscall '218' not supported for emulation
[Error] Unexpected error when processing IR instruction, aborting...
➜  maat 

Would it be hard to add the support for the missing system call?

Thanks

@Boyan-MILANOV
Copy link
Collaborator

Hi Alberto,

Syscall 218 is set_tid_address which is related to thread management. Maat doesn't support multithreading yet so this type of syscall should be safe to ignore.

We can probably implement some trivial handlers that make it seem like this syscall (and some related ones like gettid, maybe some others) behaves as if it succeeded in the kernel. It's fairly easy to add new syscalls (https://github.com/trailofbits/maat/blob/master/src/env/emulated_syscalls/linux_syscalls.cpp)
so I put this in the TODO list but tag it as "good first issue" if someone wants to make an easy first contribution :)

@Boyan-MILANOV Boyan-MILANOV added env/emulation Everything related to emulation of the environment (file system, syscalls, library emulation, ...) Good first issue Good issue to get started and contribute to Maat labels May 1, 2022
@integeruser
Copy link
Contributor

integeruser commented Jun 12, 2022

After some tests, running /bin/id seems to require (at least):

  • Adding stubs for lseek(), socket() linux syscalls.
  • Adding Python bindings to map /etc/shadow, /etc/group to the virtual fs.
  • Supporting directories in fstatat() (e.g. newfstatat(AT_FDCWD, "/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) as seen in strace /bin/id).
  • Supporting CMOV, CX8, FPU, FXSR CPU features to reach the baseline ISA level (otherwise /usr/lib/libc.so.6: CPU ISA level is lower than required).

@Boyan-MILANOV
Copy link
Collaborator

Adding Python bindings to map /etc/shadow, /etc/group to the virtual fs

I can take care of this

Supporting directories in fstatat() (e.g. newfstatat(AT_FDCWD, "/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) as seen in strace /bin/id)

I thought we supported those when AT_FDCWD is passed but will look into it.

Supporting CMOV, CX8, FPU, FXSR CPU features to reach the baseline ISA level (otherwise /usr/lib/libc.so.6: CPU ISA level is lower than required)

They are described in table 2-27 of Intel Advanced Vector Extensions Programming Reference. I think Maat/sleigh already support them, but we should also set the corresponding flags to 1 in the CPUID handler.

@integeruser
Copy link
Contributor

(FYI I also tried enabling the CPU features in X86_CPUID_handler() by setting the missing bits, but then running /usr/bin/whoami symbolically triggers:

FATAL: Error in sleigh translate(): Can not lift instruction at 0x40b4aad: PMAXUB XMM3, XMM0 (unsupported callother occurence)
[Fatal] Lifter error: MaatEngine::run(): failed to lift instructions

and I didn't investigate further.)

@Boyan-MILANOV
Copy link
Collaborator

Ugh - some instructions must still be unsupported by sleigh then. We should check whether updating to latest sleigh would add support for those (see #105), and if not we can write the sleigh spec for missing instructions.

@Boyan-MILANOV Boyan-MILANOV changed the title syscall '218' not supported for emulation Improvements needed to run /bin/id from binutils Jun 12, 2022
@Boyan-MILANOV
Copy link
Collaborator

FYI: I renamed the issue since we are actually discussing several issues in here

@integeruser
Copy link
Contributor

With the latest additions from the related PR emulation of /bin/id on my Debian machine completes successfully, although with a slightly different output than the typical (e.g. uid=0 gid=0 groups=0 instead of uid=0(root) gid=0(root) groups=0(root)). I think a different code path is taken because the emulated fstatat(AT_FDCWD, "/", ...) returns ENOENT instead of success.

@integeruser
Copy link
Contributor

After some more tests, the last fixes required to properly emulate /bin/id are:

  • Handling the fstatat(AT_FDCWD, "/", ...) case.
  • Updating to latest sleigh (already done in bc65761).
  • Fixing X86_PMINUB_handler() so that CPUContext::_check_assignment_size() doesn't complain about assigning a 128-bit value into a 512-bit register.

Tested with the following snippet:

m = MaatEngine(ARCH.X64, OS.LINUX)
m.env.fs.add_real_file("/lib/x86_64-linux-gnu/libnss_files.so.2", "/usr/lib/libnss_files.so.2")
m.env.fs.add_real_file("/etc/nsswitch.conf", "/etc/nsswitch.conf")
m.env.fs.add_real_file("/etc/group", "/etc/group")
m.env.fs.add_real_file("/etc/passwd", "/etc/passwd")
m.load("/bin/id", BIN.ELF64, libdirs=["/lib/x86_64-linux-gnu/"])
m.run()

Boyan-MILANOV added a commit that referenced this issue Jul 19, 2022
* Fix a typo related bug crashing when using virtual_fs (#90)

* Map real files into the virtual filesystem (#116)

* Add add_real_file() method to FileSystem

* Add FileSystem::add_real_file() to python bindings

* Add getpid, getuid and geteuid linux syscalls (#93)

* Add getrandom linux syscall

* Add stubs for gettid, set_tid_address, set_robust_list, rseq and prlimit64 linux syscalls (#93)

* Add a note about the need for determinism

Co-authored-by: Boyan MILANOV <[email protected]>

* Initialise ruid and euid to zero by default

* Add getgid, getegid and getgroups linux syscalls (#93)

* Set CPU features bits to reach baseline ISA level (#93)

* Update set_robust_list, rseq and prlimit64 linux syscalls stubs to return success

* Add stubs for rt_sigaction and rt_sigprocmask linux syscalls (#93)

* Add stubs for statfs and socket linux syscalls (#93)

* Warn user about syscalls not fully emulated

* Initialise UID, EUID, GID and EGID to 1000

* Add lseek linux syscall (#93)

* Don't use the RLMI_INFINITY token directly

* Don't use `INFINITY` token either

`INFINITY` is also a C++ macro from `cmath`...

Co-authored-by: Boyan-MILANOV <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
env/emulation Everything related to emulation of the environment (file system, syscalls, library emulation, ...) Good first issue Good issue to get started and contribute to Maat
Projects
None yet
Development

No branches or pull requests

3 participants