linux中用execve创建文件夹,linux无文件执行— fexecve 揭秘

前言

良好的习惯是人生产生复利的有力助手。

继续2020年的flag,至少每周更一篇文章。

无文件执行

之前的文章中,我们讲到了无文件执行的方法以及混淆进程参数的方法,今天我们继续讲解一种linux上无文件执行的技巧,是后台朋友给我的提醒,万分感谢,又学到了新的东西。

linux无文件执行,首先要提到两个函数:memfd_create 和 fexecve。

memfd_create 和 fexecve

memfd_create:第一个允许我们在内存中创建一个文件,但是它在内存中的存储并不会被映射到文件系统中,至少,如果映射了,我是没找到,因此不能简单的通过ls命令进行查看,现在看来这的确是相当隐蔽的。事实上,如果一个文件存在,那么我们还是可以去发现它的,谁会去调用这个文件呢?使用如下的命令:

lsof | grep memfd

第二个函数,fexecve同样的功能很强大,它能使我们执行一个程序(同execve),但是传递给这个函数的是文件描述符,而不是文件的绝对路径,和memfd_create搭配使用非常完美!

但是这里有一个需要注意的地方就是,因为这两个函数相对的比较新,memfd_create 是在kernel3.17才被引进来,fexecve是glibc的一个函数,是在版本2.3.2之后才有的, 没有fexecve的时候, 可以使用其它方式去取代它,而memfd_create只能用在相对较新的linux内核系统上。

fexecve的实现

今天不谈memfd_create,这是linux的新特性,没有什么好玩的,本人对fexecve 的实现很有兴趣,因为fexecve是glibc中的函数,而不是linux的系统调用。先看一下fexecve的用法,下面的fexecve_test.c 代码是实现ls -l /dev/shm 功能。

#include

#include

#include

#include

#include

#include

static char *args[] = {

"hic et nunc",

"-l",

"/dev/shm",

NULL

};

extern char **environ;

int main(void)

{

struct stat st;

void *p;

int fd, shm_fd, rc;

shm_fd = shm_open("wurstverschwendung", O_RDWR | O_CREAT, 0777);

if (shm_fd == -1) {

perror("shm_open");

exit(1);

}

rc = stat("/bin/ls", &st);

if (rc == -1) {

perror("stat");

exit(1);

}

rc = ftruncate(shm_fd, st.st_size);

if (rc == -1) {

perror("ftruncate");

exit(1);

}

p = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,

shm_fd, 0);

if (p == MAP_FAILED) {

perror("mmap");

exit(1);

}

fd = open("/bin/ls", O_RDONLY, 0);

if (fd == -1) {

perror("openls");

exit(1);

}

rc = read(fd, p, st.st_size);

if (rc == -1) {

perror("read");

exit(1);

}

if (rc != st.st_size) {

fputs("Strange situation!\n", stderr);

exit(1);

}

munmap(p, st.st_size);

close(shm_fd);

shm_fd = shm_open("wurstverschwendung", O_RDONLY, 0);

fexecve(shm_fd, args, environ);

perror("fexecve");

return 0;

}

代码中主要是分为了三步:

首先通过shm_open函数在 /dev/shm中创建了wurstverschwendung文件

将ls 命令文件写入到wurstverschwendung文件

通过fexecve执行wurstverschwendung文件,因为/dev/shm在内存中,因此fexecve实际上是在内存中执行文件。

对fexecve_test.c 进行编译并执行,可以看到/dev/shm下面确实生成了wurstverschwendung文件。

00dc0f09f596174707ec9f3715bc6a98.png

调试角度

fexecve是如何执行内存中的文件的呢?一般可以从调试和源码的角度来探究其中的原理。首先使用strace调试一下:

strace -f -tt -T ./fexecve_test

从打印的日志中,找到open系统调用,从创建文件开始关联:

e6d970b206b36843e23f7ce6c432cfcd.png

大家可以看到shm_open 其实是在/dev/shm创建文件,而execve的执行文件为/proc/self/fd/3,为进程中打开的文件符号链接,这个指向的就是shm_open创建的文件,但是从监控execve的角度来说, execve无法获取执行文件的路径,从而实现了混淆。

源码角度

#include

#include

#include

#include

#include

/* Execute the file FD refers to, overlaying the running program image.

ARGV and ENVP are passed to the new program, as for `execve'. */

int

fexecve (fd, argv, envp)

int fd;

char *const argv[];

char *const envp[];

{

if (fd < 0 || argv == NULL || envp == NULL)

{

__set_errno (EINVAL);

return -1;

}

/* We use the /proc filesystem to get the information. If it is not

mounted we fail. */

char buf[sizeof "/proc/self/fd/" + sizeof (int) * 3];

__snprintf (buf, sizeof (buf), "/proc/self/fd/%d", fd);

/* We do not need the return value. */

__execve (buf, argv, envp);

int save = errno;

/* We come here only if the 'execve' call fails. Determine whether

/proc is mounted. If not we return ENOSYS. */

struct stat st;

if (stat ("/proc/self/fd", &st) != 0 && errno == ENOENT)

save = ENOSYS;

__set_errno (save);

return -1;

}

关键部位代码:

char buf[sizeof "/proc/self/fd/" + sizeof (int) * 3];

__snprintf (buf, sizeof (buf), "/proc/self/fd/%d", fd);

/* We do not need the return value. */

__execve (buf, argv, envp);

fexecve本质上还是调用execve,只不过文件路径是在/proc中。fexecve_test中实现的功能,可以用bash来简单描述,作用是等同的:

9f1494dba2b97f68363a8c3d460c6a78.png

最后

关注公众号:七夜安全博客

回复【1】:领取 Python数据分析 教程大礼包

回复【2】:领取 Python Flask 全套教程

回复【3】:领取 某学院 机器学习 教程

回复【4】:领取 爬虫 教程

回复【5】:领取 编译原理 教程

回复【6】:领取 渗透测试 教程

回复【7】:领取 人工智能数学基础 教程

本文章属于原创作品,欢迎大家转载分享,禁止修改文章的内容。尊重原创,转载请注明来自:七夜的故事 http://www.cnblogs.com/qiyeboy/

linux脚本文件执行的方法之间的区别

sh/bash sh a.sh bash a.sh 都是打开一个subshell去读取.执行a.sh,而a.sh不需要有"执行权限",在subshell里运行的脚本里设置变量,不会 ...

【转】Linux中文件的可读,可写,可执行权限的解读以及chmod&comma;chown&comma;chgrp命令的用法

chmod是更改文件的权限 chown是改改文件的属主与属组 chgrp只是更改文件的属组. 一.文件权限解读 如上图所示,开头的-rwxrw-r--这一字符串标识文件权限. 这个字符串有10位,可以 ...

linux中用一个&period;sh文件执行多个&period;sh文件

建一个文件夹存放你自己的.sh文件(用命令行操作) 先进入到: cd usr/local/sbin 目录里面 然后再新建一个文件夹: sudo mkdir myshell 建一个文件夹专门存放自己 ...

Windows、Linux下文件操作&lpar;写、删除&rpar;错误的产生原因、及解决方法

catalog . 引言 . Linux平台上涉及的File IO操作 . Windows平台上涉及的File IO操作 0. 引言 本文试图讨论在windows.linux操作系统上基于C库进行文件 ...

Linux Makefile文件编写详细步骤与实践

Linux Makefile文件编写详细步骤与实践 1.makefile概述 Windows环境下IDE会帮你完成makefile文件的编写,但在UNIX环境下你就必须自己写makefile了,会不会 ...

Linux指令--文件和目录属性

对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于我们用好linux系统只管重要,下面 ...

Linux 的文件类型

Linux 的文件通常分为 7 大类 文件类型                                  缩写      英文名称                                ...

linux下文件内容查找 转

find | xargs grep test find命令和xargs命令 网友:wuye_chinaunix 发布于: : (共有条评论) 查看评论 | 我要评论 青云 分配文件 - -| 回首页 ...

LInux 解压缩文件

常用命令有2个,一个是tar,一个是zip,二选一就行 有的服务器没有安装zip命令,就只有tar可以用,我个人建议还是安装一个zip好一些,tar实在太繁琐 1.解压 tar -zxvf ./xxx ...

随机推荐

React项目(二):生命游戏

引子 这是16年最后的一个练手项目,一贯的感觉就是,做项目容易,写说明文档难.更何况是一个唤起抑郁感觉的项目,码下的每个字,心就如加了一个千斤的砝码. 2016年,有些事我都已忘记,但我现在还记得.2 ...

&lbrack;转&rsqb;Java 常用排序算法&sol;程序员必须掌握的 8大排序算法

本文转自:http://www.cnblogs.com/qqzy168/archive/2013/08/03/3219201.html 本文由网络资料整理转载而来,如有问题,欢迎指正! 分类: 1)插 ...

Regex 例

密码复杂度:数字英文符号Regex r = new Regex("^(?:(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])|(?=.*[A-Z])(?=.*[a-z])(? ...

WCF 笔记 &lpar;2&rpar; - 传输泛型 List 对象

WCF 笔记 (2) - 传输泛型 List 对象 本帖介绍怎么在 WCF 中,在 Server-side 和 Client-side 之间,传递默认无法传输的 List.List& ...

python学习笔记13(模块、包)

在Python中有一个概念叫做模块(module),比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块. 模块文件以.py后缀结 ...

DOM4J 解析 XML

1.在项目根目录下新建lib文件夹 2.把dom4j文件拷贝到lib文件夹 3.dom4j,右键Build Path---->Add To Build Path 这样就添加dom4j到项目成功 ...

Python之FTP多线程下载文件之分块多线程文件合并

Python之FTP多线程下载文件之分块多线程文件合并 欢迎大家阅读Python之FTP多线程下载系列之二:Python之FTP多线程下载文件之分块多线程文件合并,本系列的第一篇:Python之FTP ...

Java中的String类能否被继承?为什么?

不能被继承,因为String类有final修饰符,而final修饰的类是不能被继承的. Java对String类的定义: public final class String implements ja ...

spring boot 添加客户端负载均衡

1.pom.xml文件中,添加依赖包 org.springframework.cloud

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值