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.