c - 信号处理程序中的 Shellcode

标签 c signals shellcode

为什么我的 shellcode (int3) 不会被信号处理程序命中?

除了不喜欢在处理程序中使用 printf() 之外,我还关心 如何传递 shellcode(不是内联汇编器) 在信号处理程序中,在运行时执行。

然而,我在这里展示了一个更长的 gdb session ,它显示了 register 状态和回溯。

 <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?

最佳答案

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>

关于c - 信号处理程序中的 Shellcode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52777716/

相关文章:

c - 查找缓冲区地址以创建 shell 代码

iphone - Objective-C:unichar 与 char

linux - bash 如何终止父进程,或从 bash 模块脚本中的函数退出父进程

java - 缓冲区溢出 (vs) 缓冲区溢出 (vs) 堆栈溢出

c++ - 在信号处理函数中使用本地互斥量来同步共享数据

c - 如何修复信号处理程序分配

c++ - 如何注入(inject)从文件加载的shellcode?

c - Shellcode 和格式字符串漏洞?

c - 如何在C中读取/解析输入?常见问题

c++ - 如何测试是否定义了只能通过#define 宏访问的标识符?