Shellcode в обработчике сигналов - PullRequest
0 голосов
/ 12 октября 2018

Почему мой шелл-код (int3) не будет обработан обработчиком сигнала?

Помимо нежелания иметь printf () в обработчике, я забочусь о том, как доставлять шелл-код (как не встроенный ассемблер) в обработчике сигналов, выполняемый во время выполнения.

Однако, Я представляю здесь более длинный сеанс GDB, который показывает состояние регистра и обратный след.

 <code> Pid 19750 waiting for SIGUSR1 Program received signal SIGUSR1,
 User defined signal 1. 0x0e5f9f89 in nanosleep () at <stdin>:2 2      
 <stdin>: No such file or directory.
         in <stdin> Current language:  auto; currently asm (gdb) bt
 #0  0x0e5f9f89 in nanosleep () at <stdin>:2
 #1  0x0e650348 in sleep (seconds=10) at /usr/src/lib/libc/gen/sleep.c:45
 #2  0x18cb3d5b in main () at sig5.c:37 (gdb) i r eax            0x5b     91 ecx            0x0      0 edx            0xa      10 ebx           
 0x2e5df594       777909652 esp            0xcfbf73fc       0xcfbf73fc
 ebp            0xcfbf7438       0xcfbf7438 esi            0x38cb62df  
 952853215 edi            0x38cb61e0       952852960 eip           
 0xe5f9f89        0xe5f9f89 eflags         0x206    518 cs            
 0x2b     43 ss             0x33     51 ds             0x33     51 es  
 0x33     51 fs             0x5b     91 gs             0x63     99
 (gdb) c Continuing.

 Program received signal SIGUSR1, User defined signal 1. 0x0e5f9f89 in
 nanosleep () at <stdin>:2 2       in <stdin> (gdb) c Continuing.
 Signal 30 from pid 0, should int3

 Program received signal SIGSEGV, Segmentation fault. 0x18cb3c7a in
 sigusr1 (signo=30, si=0xcfbf737c, data=0xcfbf7328) at sig5.c:23 23    
 ret(); Current language:  auto; currently c (gdb) bt
 #0  0x18cb3c7a in sigusr1 (signo=30, si=0xcfbf737c, data=0xcfbf7328) at sig5.c:23
 #1  <signal handler called>
 #2  0x0e5f9f89 in nanosleep () at <stdin>:2
 #3  0x0e650348 in sleep (seconds=10) at /usr/src/lib/libc/gen/sleep.c:45
 #4  0x18cb3d5b in main () at sig5.c:37 (gdb) i r eax            0xcfbf7305       -809536763 ecx            0x0      0 edx           
 0x0      0 ebx            0x38cb5124       952848676 esp           
 0xcfbf72e8       0xcfbf72e8 ebp            0xcfbf7310       0xcfbf7310
 esi            0x38cb62df       952853215 edi            0x38cb61e0   
 952852960 eip            0x18cb3c7a       0x18cb3c7a eflags        
 0x10282  66178 cs             0x2b     43 ss             0x33     51
 ds             0x33     51 es             0x33     51 fs            
 0x5b     91 gs             0x63     99   (gdb) bt full
 #0  0x18cb3c7a in sigusr1 (signo=30, si=0xcfbf737c, data=0xcfbf7328) at sig5.c:23
         code = "ëÌ"
         ret = (int (*)()) 0xcfbf7305
 #1  <signal handler called> No symbol table info available.
 #2  0x0e5f9f89 in nanosleep () at <stdin>:2 No locals.
 #3  0x0e650348 in sleep (seconds=10) at /usr/src/lib/libc/gen/sleep.c:45
         rqt = {tv_sec = 10, tv_nsec = 0}
         rmt = {tv_sec = 0, tv_nsec = 0}
 #4  0x18cb3d5b in main () at sig5.c:37
         sa = {__sigaction_u = {__sa_handler = 0x18cb3c04 <sigusr1>, 
     __sa_sigaction = 0x18cb3c04 <sigusr1>}, sa_mask = 0, sa_flags = 64}

 -bash-4.3$ cat sig5.c 
 #include <errno.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>

 void sigusr1(int signo, siginfo_t *si, void *data) {
         (void)signo;
         (void)data;

         unsigned char code[] = \
                                "\xeb\xcc";
         int (*ret)() = (int(*)())code;
         printf("Signal %d from pid %lu, should int3\n", (int)si->si_signo,
                         (unsigned long)si->si_pid);
         sleep (1);
         ret();
         exit(0); }

 int main(void) {
         struct sigaction sa;
         memset(&sa, 0, sizeof(sa));
         sa.sa_flags = SA_SIGINFO;
         sa.sa_sigaction = sigusr1;
         if (sigaction(SIGUSR1, &sa, 0) == -1) {
                 fprintf(stderr, "%s: %s\n", "sigaction", strerror(errno));
         }
         printf("Pid %lu waiting for SIGUSR1\n", (unsigned long)getpid());
         for (;;) {
                 sleep(10);
         }

         return 0; } </code>

 Any Ideas?

1 Ответ

0 голосов
/ 23 октября 2018
So this uses mprotect(), but still does not lead to the shell. We really need to update
radare2 shellcode sources :)    

<code>
    #include "errno.h"
    #include "signal.h"
    #include "stdio.h"
    #include "stdlib.h"
    #include "string.h"
    #include "unistd.h"
    #include "sys/mman.h"

    void sigusr1(int signo, siginfo_t *si, void *data) {
        (void)signo;
        (void)data;

        unsigned char sc[] = \
                       "\xcc";
        mprotect(sc,strlen(sc),PROT_EXEC|PROT_READ|PROT_WRITE);
        int (*r)() = (int(*)())sc; /* Thanks, maybe change to define? */
            r();
    }

    int main(void) {
        struct sigaction sa;
        memset(&sa, 0, sizeof(sa));
        sa.sa_flags = 5; /* SIGTRAP via Sil... */
        sa.sa_sigaction = sigusr1;
        if (sigaction(SIGUSR1, &sa, 0) == -1) {
            fprintf(stderr, "%s: %s\n", "sigaction", strerror(errno));
        }
        printf("Pid %lu waiting for SIGUSR1\n", (unsigned long)getpid());
        for (;;) {
            sleep(10);
        }

        return 0;
    }
</code>
...