原创:打码日记(微信公众号ID:codelogs),欢送分享,转载请保留出处。
场景
很多时候,咱们须要批量操作多台机器,业界个别应用Ansible来实现,但应用Ansible来操作多台机器的前提是须要有ssh权限的,可悲的是,对于开发人员来说,个别是没有正式环境机器的ssh权限的,只能通过一个指定的入口登录机器,也能够了解,毕竟正式环境如此重要。
不过,如果你的生产环境能够拜访你的开发机,那么能够通过反向Shell来拜访机器,而后将反向Shell与tmux联合,又可实现同时操作多台机器的成果,这就是本文要介绍的。
正反向Shell
如果你理解过nc命令,肯定据说过nc能够建设正向或反向Shell,这里就不解释正向或反向Shell的概念了,解释不清,间接上nc实现正向Shell与反向Shell的例子。
因为nc命令自身存在模糊性,有些文章介绍的nc命令是ncat,有些文章介绍的nc命令又是netcat,这两个还是有些差异的,故这里的例子,间接应用ncat防止混同。
开发机ip为192.168.0.10
服务器ip为192.168.0.1
#正向Shell,1.服务器上应用ncat监听ncat -l 9999 -e /bin/bash#正向Shell,2.开发机上连贯ncat 192.168.0.1 9999#反向Shell,1.开发机上应用ncat监听ncat -l 9999#反向Shell,2.服务器上连贯ncat 192.168.0.10 9999 -e /bin/bash
成果如下:
- 正向Shell:ncat在服务器上以9999端口监听,当开发机用ncat连贯,连贯胜利后,服务器上的ncat会关上一个bash过程为这个连贯服务。
- 反向Shell:ncat在开发机上以9999端口监听,当服务器用ncat连贯,连贯胜利后,服务器上的ncat会关上一个bash过程为这个连贯服务。
其实正反向Shell的区别只是建设TCP连贯的方向不同而已,如下为ncat提供的Shell大略交互过程:ncat(client) <-> ncat(server) <-> bash
当在开发机的ncat外面输出命令并Enter后,命令会通过ncat(client)走网络,发送给ncat(server),ncat(server)收到命令后,会将命令发送给bash过程执行,bash过程执行后,命令执行的后果,又会返回给ncat(server),而ncat(server)又通过网络连接返回给开发机上的ncat(client)显示进去。
然而,当你真正来应用这个反向Shell时,会发现有诸多不便,比方应用tail -f来查看日志文件,完预先你想Ctrl + C退出tail,却发现连ncat过程也退出了,这是最无法忍受的一点了,另外,像Tab补全
/Up Arrow history
/vim
/Ctrl + d
/Ctrl + z
之类的,也都无奈应用,十分好受。咱们个别称获取到的这种Shell叫Weak Shell,而如果要获取Strong Shell,就须要socat上场了。
通过socat获取Strong Shell
socat与nc命令相似,但它比nc要弱小得多,比方通过socat能够获取一个残缺的Shell,如下:
#正向Shell,1.服务器上应用socat监听socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp-listen:9999,bind=0.0.0.0,reuseaddr,fork#正向Shell,2.开发机上连贯socat file:`tty`,raw,echo=0 tcp:192.168.0.1:9999#反向Shell,1.开发机上应用socat监听socat file:`tty`,raw,echo=0 tcp-listen:9999,bind=0.0.0.0,reuseaddr,fork#反向Shell,2.服务器上连贯socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:192.168.0.10:9999
成果如下:
原理和ncat相似,不过socat能够提供tty和pty,因为像Ctrl + C之类的,自身就是终端tty提供给bash的信号,而不是字符,所以在ncat里,因为没有tty,Ctrl + C信号是无奈传递给服务端的bash程序的。
socat提供的Shell交互过程大略是这样的:tty <-> socat(client) <-> socat(server) <-> pty <-> bash
那什么是tty?这里我也了解得不是很透彻,能够简略认为键盘和屏幕就是tty,键盘敲的内容会作为tty的输出,tty输入的内容,会显示到屏幕上。
tmux实现多机同时操作
tmux是一个终端复用器,最罕用的是实现分屏,既然通过socat曾经能够获取到反向Shell了,那么把各个机器的反向Shell显示到tmux的各个分屏上,就能够看到多个反向Shell的命令执行后果,同时,将某个非凡分屏的tty操作,同时转发给多个反向Shell,就实现了多机同时操作,成果如下:
上面是实现多机操作的命令:
# 1.开发机上监听nohup socat tcp-listen:9999,bind=0.0.0.0,reuseaddr,fork exec:'bash socatscript.sh' &# 2.在多个服务器上连贯nohup socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:192.168.0.10:9999 &# 3.进入tmux分屏界面tmux a -t socatSession
这是脚本socatscript.sh的实现
#!/bin/bashSOCKDIR=$(mktemp -d)SOCKF=${SOCKDIR}/usockSESSION_NAME=${1:-socatSession}WINDOW_NAME=${2:-socatWindown}# create session and windowtmux has-session -t $SESSION_NAMEif [[ $? -eq 1 ]];then tmux new -s $SESSION_NAME -n $WINDOW_NAME -d "socat file:\`tty\`,raw,echo=0 exec:'ncat -lk 9998'"fi# split windown 0tmux split-window -h -t 0 "socat file:\`tty\`,raw,echo=0 UNIX-LISTEN:${SOCKF},umask=0077"tmux select-pane -t 0tmux select-layout -t $WINDOW_NAME main-horizontaltmux resize-pane -t 0 -y 2# Wait for socketwhile test ! -e ${SOCKF} ; do sleep 1 ; donewhile ! $(ncat -z localhost 9998) ;do sleep 1; done;# Use socat to ship data between the unix socket and STDIO.socat -U STDOUT TCP:localhost:9998 &exec socat STDIO UNIX-CONNECT:${SOCKF}
次要性能是,每当有一个反向Shell连贯时,在tmux上新建一个分屏,并将反向Shell显示在这个新建的分屏上,同时,提供一个非凡的分屏(最下面那个),在这个分屏上的输出的命令,会转发到各个反向Shell里。
如果你发现反向Shell里的文字不能满屏显示,须要通过 stty rows 63 columns 204
从新设置一下以后tty的显示宽高。
并且,如果你有ssh机器的权限,同时也想应用这种tmux分屏的形式执行命令,只须要将bash更换成ssh即可,如下:
# 1.开发机上监听nohup socat tcp-listen:9999,bind=0.0.0.0,reuseaddr,fork exec:'bash socatscript.sh' &# 2.开发机上,应用ssh连贯到多个机器nohup socat exec:'sshpass -p "xxx" ssh root@192.168.0.10',pty,stderr,setsid,sigint,sane tcp:localhost:9999 &# 3.进入tmux分屏界面tmux a -t socatSession
是不是很爽,连ansible也能够不必装了!
总结
socat命令十分的弱小,值得好好的钻研一翻,同时当你钻研胜利后,会发现自己对各种概念的了解,又回升了一步。