Hi again,

On 1/8/21 19:20, aitor wrote:

Hi Arnt,

On 1/8/21 17:59, Arnt Karlsen wrote:
I'm looking for a safer way to run the binary with suid permissions
using the shared memory of the system to send a signal.
Time ago somebody said me: "you can do nothing from your binary that
i can't do externally from another binary".

So, am i wasting time?
..nope.

Good :)


Today i've been testing the idea and it's working for me. I'd like to
prepare an example and share with all of you to resolve
vulnerabilities. The example consists of a window with a button (to
run the suid binary) and another binary -the intruder- located in the
same directory and trying to do the same by using the other party's
PID pretending to be the window.
..you're being too damned naive: Why would the intruder not try to
e.g. use your PID?

?

Yes, the intruder would.., of course. And that's what i'm trying to avoid. The logic is as follows:

Let's assume the intruder sending our PID. The suid binary receives the PID and extracts the corresponding binary name afterwards. There are other ways, but i'll use Jude Nelson's
libpstat for that.

If this name -say PSTAT_BINARY- doesn't match the name of our application, then the suid binary
will do nothing. For instance:

if (PSTAT_BINARY == $current_working_dir/app_name) {

    continue;

} else {

    do nothing;

}

Now, you're thinking: "The gui application is already running with the above PID. So,
the suid binary will go ahead!"

And here is the key point: the suid binary sends a SIGUSR1 signal to the gui application. But the signal handler associated to this SIGUSR1 is activated within the callback function of the button responsible for running the suid binary, being triggered its default signal handling behavior as soon as the suid binary has been executed. Hence, not reacting to the SIGUSR1 signal
events unlessthe user clicks again on the button.


gboolean button_callback ()
{

  /*

    ... run the suid binary asynchronously, going ahead...

 */

  /*  trigger the signal handler in order to receive the SIGUSR1 signal emited by the suid binary */

  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = sig_handler;
  sa.sa_flags = SA_RESTART | SA_SIGINFO;
  sigemptyset(&sa.sa_mask);
  sigaction(SIGUSR1, &sa, 0);

}

Now, the signal handler will react:

void signal_handler (int signum)
{

if( gtk_main_level() == 0) exit(-1);

/*

    ... here goes the socket ...

 */

  /*   Set to default !!  */

  signal(SIGUSR1, SIG_DFL);

}

After that, the suid binary can check _whether or not_ the emited signal has been received. If yes, both the gui and the suid will communicate each other through a unix socket or a fifo to know what to do.

Finally, the suid binary parses the received arguments.

Does it make sense? If not, i may stop here.

Thanks in advance,

Aitor.


The PID of the process is emmited via shmget():

https://www.csl.mtu.edu/cs4411.ck/www/NOTES/signal/kill.html <https://www.csl.mtu.edu/cs4411.ck/www/NOTES/signal/kill.html>

The idea might have weak points, but it's better than nothing.

Aitor.


_______________________________________________
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng

Reply via email to