Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果python可执行文件是通过“env”指定的,那么ptrace将破坏堆栈_Python_Linux_Environment Variables_Ptrace_Stack Smash - Fatal编程技术网

如果python可执行文件是通过“env”指定的,那么ptrace将破坏堆栈

如果python可执行文件是通过“env”指定的,那么ptrace将破坏堆栈,python,linux,environment-variables,ptrace,stack-smash,Python,Linux,Environment Variables,Ptrace,Stack Smash,我试图截取getrandomsyscall并修改其结果。我试着制作一个最小的可复制示例,如下所示:[原始代码库是用Rust编写的,大约有400行,进行了正确的错误检查,并且遇到了相同的问题] #include <stdio.h> #include <stdlib.h> #include <sys/ptrace.h> #include <sys/reg.h> #include <sys/syscall.h> #include <s

我试图截取
getrandom
syscall并修改其结果。我试着制作一个最小的可复制示例,如下所示:[原始代码库是用Rust编写的,大约有400行,进行了正确的错误检查,并且遇到了相同的问题]

#include <stdio.h>
#include <stdlib.h>

#include <sys/ptrace.h>
#include <sys/reg.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <unistd.h>

void wait_sigtrap() {
    int status;
    wait(&status);
    if (WIFEXITED(status)) exit(0);
}

int main() {
    pid_t child = fork();
    if (child == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        const char* file = "./pi.py";
        if (execl(file, file, "1000", NULL) < 0) {
            perror("execl");
            return 1;
        };
    } else {
        pid_t pid = child;
        wait_sigtrap(); // there will be an initial stop after traceme, ignore
                        // it

        ptrace(PTRACE_SYSCALL, pid, 0, 0); // wait for another
        for (;;) {
            // detect enter, get syscall no
            wait_sigtrap();
            long no = ptrace(PTRACE_PEEKUSER, pid, 8 * ORIG_RAX, 0);

            if (no != SYS_getrandom) {
                ptrace(PTRACE_SYSCALL, pid, 0, 0); // wait for another
                wait_sigtrap();                    // wait for exit
            } else {
                // getrandom
                long bufptr = ptrace(PTRACE_PEEKUSER, pid, 8 * RDI, 0);
                long buflen = ptrace(PTRACE_PEEKUSER, pid, 8 * RSI, 0);

                printf("getrandom request: 0x%016lx 0x%016lx\n", bufptr,
                       buflen);
                fflush(stdout);

                ptrace(PTRACE_SYSCALL, pid, 0, 0); // wait for another
                wait_sigtrap();                    // wait for exit

                long ret = ptrace(PTRACE_PEEKUSER, pid, 8 * ORIG_RAX, 0);
                if (ret < 0) {
                    printf("Syscall %ld exited with an error, not touching it",
                           no);
                    fflush(stdout);
                } else {
                    long ind = 0;
                    while (ind < buflen) {
                        ptrace(PTRACE_POKEDATA, pid, bufptr + ind, 0);
                        ind += sizeof(long);
                    }
                }
            }

            ptrace(PTRACE_SYSCALL, pid, 0, 0); // wait for another
        }
    }
    return 0;
}
这将触发堆栈破坏保护:

getrandom request: 0x00007fee772e29a0 0x0000000000000018
getrandom request: 0x00007ffc1788eb90 0x00000000000009c0
getrandom request: 0x00007ffc1788e420 0x00000000000009c0
*** stack smashing detected ***: python terminated
======= Backtrace: =========
/usr/lib/libc.so.6(+0x7254c)[0x7fee7735554c]
/usr/lib/libc.so.6(__fortify_fail+0x37)[0x7fee773e1307]
/usr/lib/libc.so.6(__fortify_fail+0x0)[0x7fee773e12d0]
/usr/lib/python3.6/lib-dynload/_random.cpython-36m-x86_64-linux-gnu.so(+0x1285)[0x7fee75169285]
======= Memory map: ========
00400000-00401000 r-xp 00000000 fe:00 22965216                           /usr/bin/python3.6
00601000-00602000 r--p 00001000 fe:00 22965216                           /usr/bin/python3.6
00602000-00603000 rw-p 00002000 fe:00 22965216                           /usr/bin/python3.6
0082e000-00924000 rw-p 00000000 00:00 0                                  [heap]
7fee74f2e000-7fee74f44000 r-xp 00000000 fe:00 22941269                   /usr/lib/libgcc_s.so.1
7fee74f44000-7fee75143000 ---p 00016000 fe:00 22941269                   /usr/lib/libgcc_s.so.1
7fee75143000-7fee75144000 r--p 00015000 fe:00 22941269                   /usr/lib/libgcc_s.so.1
7fee75144000-7fee75145000 rw-p 00016000 fe:00 22941269                   /usr/lib/libgcc_s.so.1
7fee75168000-7fee7516c000 r-xp 00000000 fe:00 23600949                   /usr/lib/python3.6/lib-dynload/_random.cpython-36m-x86_64-linux-gnu.so
7fee7516c000-7fee7536b000 ---p 00004000 fe:00 23600949                   /usr/lib/python3.6/lib-dynload/_random.cpython-36m-x86_64-linux-gnu.so
7fee7536b000-7fee7536c000 r--p 00003000 fe:00 23600949                   /usr/lib/python3.6/lib-dynload/_random.cpython-36m-x86_64-linux-gnu.so
7fee7536c000-7fee7536d000 rw-p 00004000 fe:00 23600949                   /usr/lib/python3.6/lib-dynload/_random.cpython-36m-x86_64-linux-gnu.so
7fee7536d000-7fee7536f000 r-xp 00000000 fe:00 23600965                   /usr/lib/python3.6/lib-dynload/_bisect.cpython-36m-x86_64-linux-gnu.so
7fee7536f000-7fee7556e000 ---p 00002000 fe:00 23600965                   /usr/lib/python3.6/lib-dynload/_bisect.cpython-36m-x86_64-linux-gnu.so
7fee7556e000-7fee7556f000 r--p 00001000 fe:00 23600965                   /usr/lib/python3.6/lib-dynload/_bisect.cpython-36m-x86_64-linux-gnu.so
7fee7556f000-7fee75570000 rw-p 00002000 fe:00 23600965                   /usr/lib/python3.6/lib-dynload/_bisect.cpython-36m-x86_64-linux-gnu.so
7fee75570000-7fee75586000 r-xp 00000000 fe:00 23600924                   /usr/lib/python3.6/lib-dynload/_sha3.cpython-36m-x86_64-linux-gnu.so
7fee75586000-7fee75785000 ---p 00016000 fe:00 23600924                   /usr/lib/python3.6/lib-dynload/_sha3.cpython-36m-x86_64-linux-gnu.so
7fee75785000-7fee75786000 r--p 00015000 fe:00 23600924                   /usr/lib/python3.6/lib-dynload/_sha3.cpython-36m-x86_64-linux-gnu.so
7fee75786000-7fee75788000 rw-p 00016000 fe:00 23600924                   /usr/lib/python3.6/lib-dynload/_sha3.cpython-36m-x86_64-linux-gnu.so
7fee75788000-7fee75796000 r-xp 00000000 fe:00 23600925                   /usr/lib/python3.6/lib-dynload/_blake2.cpython-36m-x86_64-linux-gnu.so
7fee75796000-7fee75995000 ---p 0000e000 fe:00 23600925                   /usr/lib/python3.6/lib-dynload/_blake2.cpython-36m-x86_64-linux-gnu.so
7fee75995000-7fee75996000 r--p 0000d000 fe:00 23600925                   /usr/lib/python3.6/lib-dynload/_blake2.cpython-36m-x86_64-linux-gnu.so
7fee75996000-7fee75997000 rw-p 0000e000 fe:00 23600925                   /usr/lib/python3.6/lib-dynload/_blake2.cpython-36m-x86_64-linux-gnu.so
7fee75997000-7fee75be8000 r-xp 00000000 fe:00 22946259                   /usr/lib/libcrypto.so.1.1
7fee75be8000-7fee75de7000 ---p 00251000 fe:00 22946259                   /usr/lib/libcrypto.so.1.1
7fee75de7000-7fee75e05000 r--p 00250000 fe:00 22946259                   /usr/lib/libcrypto.so.1.1
7fee75e05000-7fee75e0f000 rw-p 0026e000 fe:00 22946259                   /usr/lib/libcrypto.so.1.1
7fee75e0f000-7fee75e12000 rw-p 00000000 00:00 0 
7fee75e12000-7fee75e18000 r-xp 00000000 fe:00 23600946                   /usr/lib/python3.6/lib-dynload/_hashlib.cpython-36m-x86_64-linux-gnu.so
7fee75e18000-7fee76017000 ---p 00006000 fe:00 23600946                   /usr/lib/python3.6/lib-dynload/_hashlib.cpython-36m-x86_64-linux-gnu.so
7fee76017000-7fee76018000 r--p 00005000 fe:00 23600946                   /usr/lib/python3.6/lib-dynload/_hashlib.cpython-36m-x86_64-linux-gnu.so
7fee76018000-7fee76019000 rw-p 00006000 fe:00 23600946                   /usr/lib/python3.6/lib-dynload/_hashlib.cpython-36m-x86_64-linux-gnu.so
7fee76019000-7fee76023000 r-xp 00000000 fe:00 23600935                   /usr/lib/python3.6/lib-dynload/math.cpython-36m-x86_64-linux-gnu.so
7fee76023000-7fee76222000 ---p 0000a000 fe:00 23600935                   /usr/lib/python3.6/lib-dynload/math.cpython-36m-x86_64-linux-gnu.so
7fee76222000-7fee76223000 r--p 00009000 fe:00 23600935                   /usr/lib/python3.6/lib-dynload/math.cpython-36m-x86_64-linux-gnu.so
7fee76223000-7fee76225000 rw-p 0000a000 fe:00 23600935                   /usr/lib/python3.6/lib-dynload/math.cpython-36m-x86_64-linux-gnu.so
7fee76225000-7fee76265000 rw-p 00000000 00:00 0 
7fee76265000-7fee76268000 r-xp 00000000 fe:00 23600948                   /usr/lib/python3.6/lib-dynload/_heapq.cpython-36m-x86_64-linux-gnu.so
7fee76268000-7fee76467000 ---p 00003000 fe:00 23600948                   /usr/lib/python3.6/lib-dynload/_heapq.cpython-36m-x86_64-linux-gnu.so
7fee76467000-7fee76468000 r--p 00002000 fe:00 23600948                   /usr/lib/python3.6/lib-dynload/_heapq.cpython-36m-x86_64-linux-gnu.so
7fee76468000-7fee7646a000 rw-p 00003000 fe:00 23600948                   /usr/lib/python3.6/lib-dynload/_heapq.cpython-36m-x86_64-linux-gnu.so
7fee7646a000-7fee7666a000 rw-p 00000000 00:00 0 
7fee7666a000-7fee7677a000 r-xp 00000000 fe:00 22939716                   /usr/lib/libm-2.25.so
7fee7677a000-7fee7697a000 ---p 00110000 fe:00 22939716                   /usr/lib/libm-2.25.so
7fee7697a000-7fee7697b000 r--p 00110000 fe:00 22939716                   /usr/lib/libm-2.25.so
7fee7697b000-7fee7697c000 rw-p 00111000 fe:00 22939716                   /usr/lib/libm-2.25.so
7fee7697c000-7fee7697e000 r-xp 00000000 fe:00 22939712                   /usr/lib/libutil-2.25.so
7fee7697e000-7fee76b7d000 ---p 00002000 fe:00 22939712                   /usr/lib/libutil-2.25.so
7fee76b7d000-7fee76b7e000 r--p 00001000 fe:00 22939712                   /usr/lib/libutil-2.25.so
7fee76b7e000-7fee76b7f000 rw-p 00002000 fe:00 22939712                   /usr/lib/libutil-2.25.so
7fee76b7f000-7fee76b82000 r-xp 00000000 fe:00 22939717                   /usr/lib/libdl-2.25.so
7fee76b82000-7fee76d81000 ---p 00003000 fe:00 22939717                   /usr/lib/libdl-2.25.so
7fee76d81000-7fee76d82000 r--p 00002000 fe:00 22939717                   /usr/lib/libdl-2.25.so
7fee76d82000-7fee76d83000 rw-p 00003000 fe:00 22939717                   /usr/lib/libdl-2.25.so
7fee76d83000-7fee7704a000 r-xp 00000000 fe:00 22965217                   /usr/lib/libpython3.6m.so.1.0
7fee7704a000-7fee77249000 ---p 002c7000 fe:00 22965217                   /usr/lib/libpython3.6m.so.1.0
7fee77249000-7fee7724c000 r--p 002c6000 fe:00 22965217                   /usr/lib/libpython3.6m.so.1.0
7fee7724c000-7fee772b2000 rw-p 002c9000 fe:00 22965217                   /usr/lib/libpython3.6m.so.1.0
7fee772b2000-7fee772e3000 rw-p 00000000 00:00 0 
7fee772e3000-7fee7747f000 r-xp 00000000 fe:00 22939771                   /usr/lib/libc-2.25.so
7fee7747f000-7fee7767e000 ---p 0019c000 fe:00 22939771                   /usr/lib/libc-2.25.so
7fee7767e000-7fee77682000 r--p 0019b000 fe:00 22939771                   /usr/lib/libc-2.25.so
7fee77682000-7fee77684000 rw-p 0019f000 fe:00 22939771                   /usr/lib/libc-2.25.so
7fee77684000-7fee77688000 rw-p 00000000 00:00 0 
7fee77688000-7fee776a1000 r-xp 00000000 fe:00 22939790                   /usr/lib/libpthread-2.25.so
7fee776a1000-7fee778a0000 ---p 00019000 fe:00 22939790                   /usr/lib/libpthread-2.25.so
7fee778a0000-7fee778a1000 r--p 00018000 fe:00 22939790                   /usr/lib/libpthread-2.25.so
7fee778a1000-7fee778a2000 rw-p 00019000 fe:00 22939790                   /usr/lib/libpthread-2.25.so
7fee778a2000-7fee778a6000 rw-p 00000000 00:00 0 
7fee778a6000-7fee778c9000 r-xp 00000000 fe:00 22939772                   /usr/lib/ld-2.25.so
7fee778ca000-7fee778ef000 rw-p 00000000 00:00 0 
7fee778ef000-7fee77aa2000 r--p 00000000 fe:00 22961001                   /usr/lib/locale/locale-archive
7fee77aa2000-7fee77aa6000 rw-p 00000000 00:00 0 
7fee77ac8000-7fee77ac9000 rw-p 00000000 00:00 0 
7fee77ac9000-7fee77aca000 r--p 00023000 fe:00 22939772                   /usr/lib/ld-2.25.so
7fee77aca000-7fee77acb000 rw-p 00024000 fe:00 22939772                   /usr/lib/ld-2.25.so
7fee77acb000-7fee77acc000 rw-p 00000000 00:00 0 
7ffc17872000-7ffc17893000 rw-p 00000000 00:00 0                          [stack]
7ffc17917000-7ffc17919000 r--p 00000000 00:00 0                          [vvar]
7ffc17919000-7ffc1791b000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
这个地址区域确实超出了堆栈。此外,当我试图简单地用自定义覆盖器替换
getrandom
glibc系统调用时,错误不会出现在任何地方

更有趣的是,只有当我将可执行文件指定为
/usr/bin/env python
时,才会出现这种情况。如果我直接指定
/usr/bin/python
,一切都会按预期工作

此外,如果python可执行文件是通过env指定的,则存储在RDI和RSI寄存器中的参数将失效(被某些内容覆盖)。如果直接指定了
python
,则情况并非如此

如果我使用
strace
跟踪直接调用的
/pi.py
的执行,即使使用patched
getrandom
(使用
LD\u PRELOAD
),也不会发生任何错误,输出缓冲区也会被成功覆盖。缓冲区完全包含在堆栈中

我正在运行ArchLinux、Linux4.9.36-1-lts、Glibc2.25和Python3.6.1

/编辑:它变得更有趣了。如果我使用
LD_PRELOAD
技巧将libc getrandom例程修补为以下一个:

int getrandom(void *buf, size_t buflen, unsigned int flags)
{
    (void) flags;

    syscall(318, buf, buflen, flags);

    printf("Using our getrandom\n");
    uint8_t* b = buf;
    for (int i = 0; i < buflen; ++i) {
        b[i] = 0;
    }
    return buflen;
}
int getrandom(void*buf、size\t buflen、无符号int标志)
{
(b)旗帜;
系统调用(318,buf,buflen,flags);
printf(“使用我们的getrandom\n”);
uint8_t*b=buf;
对于(int i=0;i
然后,未修改的
ptrace
程序成功并按预期工作

/编辑2:它变得更有趣了。在系统调用之后添加任何日志记录都可以神奇地修复该问题。例如,此修补程序:
[这是在commit 0d0a32fb91cdfea1626e6c6b77a9bc44e15a2b8a上测试的]

我还没有机会运行您的代码,但我猜您的tracee会自己生成一个ptrace事件,并将您的enter syscall/exit syscall监视延迟一次,因此,你在系统调用结束时观察RSI,它不是我们预期的8这样的小数值,而是大得多。添加env行将添加另一个exec调用,该调用同步执行enter syscall/exit syscall监控。缓冲区长度正确,Python确实请求2496字节的随机数据,请参阅:好的,对不起,一定是其他内容。
ptrace(ptrace_POKEDATA,pid,bufptr+ind,0)
-if
bufptr+ind+sizeof(long)
except
bufptr+buflen
您遇到了麻烦在这种情况下,它总是与
sizeof(long)
对齐。经过一段时间的开发,这个问题神秘地消失了,可能是因为缺少
PTRACE\u O\u SYSGOOD
。看见
int getrandom(void *buf, size_t buflen, unsigned int flags)
{
    (void) flags;

    syscall(318, buf, buflen, flags);

    printf("Using our getrandom\n");
    uint8_t* b = buf;
    for (int i = 0; i < buflen; ++i) {
        b[i] = 0;
    }
    return buflen;
}