Nan ZoE <zoen...@gmail.com> wrote:

> Additionally, it's reasonable to assess the correctness of the ROP payloads
> we generate for a program by injecting vulnerabilities. Firstly, the
> original gadget set in the program remains intact and usable. Secondly,
> this method of injecting vulnerabilities is equivalent to assuming the
> existence of easily exploitable ROP attack vulnerabilities in the program.

You are using the word "exploitable" again, which is incorrect terminology.

It is not the same at all.  You have not just disabled all address space
layout control, but also pledge and unveil, and I'm sure there are other
things you have disabled but not mentioned.  The syntheticness of your
test is removing mitigations you aren't even aware of.

> In both cases, the ROP payloads can be executed, and the gadgets in these
> ROP payloads are all from the original program. In other words, if a
> program has vulnerabilities that require ROP attack techniques, then the
> ROP payloads generated by our tool are entirely applicable.
> 
> In our experiments, we extracted over a thousand programs from OpenBSD, and
> while most of them do not have syscall instruction gadgets, there are still
> more than 240 programs that contain syscall instruction gadgets. This is
> confirmed by various tools such as ropper <https://github.com/sashs/Ropper>and
> ROPgadget <https://github.com/JonathanSalwan/ROPgadget> that we used to
> extract gadget sets. Even in cases where programs are dynamically linked,
> the syscall instructions are not solely located within their ld.so.

The following diff will be commited soon.  I forgot to run pinsyscall()
in static binaries which don't actually call execve(), as a result in
those static binaries any syscall instruction would work, rather than
just the precise one assigned by pinsyscall(SYS_execve, ...).  With this
diff such programs no longer have a viable syscall instructions which
will reach execve(2).

The programs improved tend to be boring programs which run without any
privilege which could be "exploited".

This change makes it impossible to call execve() syscall in most of /bin
and /sbin (your list of 240 will shrink), and a couple static binaries
in /usr/*bin/.  A majority of those programs call pledge() without
"exec" early during startup, so your synthetic results of exploiting
programs before they actually run main() was already highly misleading.

Index: dlfcn/init.c
===================================================================
RCS file: /cvs/src/lib/libc/dlfcn/init.c,v
retrieving revision 1.18
diff -u -p -u -r1.18 init.c
--- dlfcn/init.c        27 Feb 2023 15:00:17 -0000      1.18
+++ dlfcn/init.c        12 Oct 2023 14:22:09 -0000
@@ -154,6 +154,11 @@ _libc_preinit(int argc, char **argv, cha
                        extern const int _execve_size;
 
                        pinsyscall(SYS_execve, &HIDDEN(execve), _execve_size);
+               } else {
+                       static const int not_syscall;
+
+                       /* Static binary which does not use execve() */
+                       pinsyscall(SYS_execve, (void *)&not_syscall, 1);
                }
 #endif
        }

Reply via email to