内网渗透系列:内网隧道之frp

前言

本文研究通过TCP和HTTP出网的一个工具,frp

github:https://github.com/fatedier/frp

一、概述

1、简介

写于2015年,持续更新,用Go编写,经典出网工具

  • 支持TCP和UDP,以及HTTP和HTTPS协议,同时也支持P2P
  • 支持加密和压缩
  • 支持跨平台
  • 有GUI
  • 依赖于配置文件
    在这里插入图片描述

2、原理

在这里插入图片描述

  • 首先,frpc 启动之后,连接 frps,并且发送一个请求 login(),之后保持住这个长连接,如果断开了,就重试
  • frps 收到请求之后,会建立一个 listener 监听来自公网的请求
  • 当 frps 接受到请求之后,会在本地看是否有可用的连接( frp 可以设置连接池),如果没有,就下发一个 msg.StartWorkConn 并且 等待来自 frpc 的请求
  • frpc 收到之后,对 frps 发起请求,请求的最开始会指名这个连接是去向哪个 proxy 的
  • frps 收到来自 frpc 的连接之后,就把新建立的连接与来自公网的连接进行流量互转
  • 如果请求断开了,那么就把另一端的请求也断开
    在这里插入图片描述

3、用法

(1)服务端

frps.ini配置文件

[common]
#frp服务器监听地址,如果是IPV6地址必须用中括号包围
bind_addr = 0.0.0.0 
#frp服务器监听端口
bind_port = 7000
 
#kcp的udp监听端口,如果不设那就不启用
#kcp_bind_port = 7000
#指定使用的协议,默认tcp,可选kcp
#protocol = kcp
 
#如果要使用vitual host,就必须设置
#vhost_http_port = 80
#vhost_https_port = 443
 
#Web后台监听端口
dashboard_port = 7500
 
#Web后台的用户名和密码
dashboard_user = admin
dashboard_pwd = admin
 
#Web后台的静态资源目录,调试用的,一般不设
#assets_dir = ./static
 
#日志输出,可以设置为具体的日志文件或者console
log_file = /var/log/frps.log
 
#日志记录等级,有trace, debug, info, warn, error
log_level = info
#日志保留时间
log_max_days = 3
 
#启用特权模式,从v0.10.0版本开始默认启用特权模式,且目前只能使用特权模式
#privilege_mode = true
 
#特权模式Token,请尽量长点且复杂
privilege_token = 12345678
 
#特权模式允许分配的端口范围
privilege_allow_ports = 2000-3000,3001,3003,4000-50000
 
#心跳超时,不用改
#heartbeat_timeout = 90
 
#每个代理可以设置的连接池上限
#max_pool_count = 5
 
#认证超时时间,一般不用改
#authentication_timeout = 900
 
#如果配置了这个,当你的模式为http或https时,就能设置子域名subdomain
#subdomain_host = frps.com
 
#是否启用tcp多路复用,默认就是true,不用管
#tcp_mux = true

运行

./frps -c ./frps.ini
./frps -c ./frps.ini & # 后台运行
# 如果要运行多个服务端:只需要复制并修改frps.ini配置文件中的端口号

(2)客户端

frpc.ini配置文件

[common]
#frp服务器地址
server_addr = 1.2.3.4
#frp服务器端口
server_port = 7000
#特权模式Token
privilege_token = 12345678
#转发SSH
[ssh]
type = tcp
#可以指定为其它IP,默认是本地
#local_ip = 127.0.0.1
local_port = 22  #代理出去的端口
remote_port = 6000 #出去的端口
#启用加密
use_encryption = true
#启用压缩
use_compression = true
 
#转发Web
[web]
type = http
local_port = 80
custom_domains = www.yourdomain.com
#修改header中的host
#host_header_rewrite = dev.yourdomain.com
#启用简单HTTP认证
#http_user = abc
#http_pwd = abc
#在服务端配置了subdomain_host的情况下用于自定义二级域名
#subdomain = test
#在存在多个相同域名的情况下通过请求的URL路由到不同的配置
#locations = /news,/about
 
#转发DNS请求
[dns]
type = udp
local_ip = 8.8.8.8
local_port = 53
remote_port = 6000
 
#转发Unix域套接字(这儿是Docker)
[unix_domain_socket]
type = tcp
remote_port = 6000
plugin = unix_domain_socket
plugin_unix_path = /var/run/docker.sock
 
#HTTP代理
[http_proxy]
type = tcp
remote_port = 6000
plugin = http_proxy
#配置http代理的简单认证
#plugin_http_user = abc
#plugin_http_passwd = abc

运行

./frpc -c ./frpc.ini
./frpc -c ./frpc.ini & # 后台运行
# 如果要运行多个客户端:只需要复制并修改frpc.ini配置文件中的端口号

二、实践

1、测试场景

攻击机(服务端):kali 192.168.10.128
目标机(客户端):ubuntu 192.168.10.129

都没有限制TCP连接

2、建立隧道

(1)服务端

在这里插入图片描述

./frps -c ./frps.ini

在这里插入图片描述

在这里插入图片描述

(2)客户端

开启Apache
在这里插入图片描述

配置文件

在这里插入图片描述

./frpc -c ./frpc.ini

在这里插入图片描述

(3)隧道建立

在这里插入图片描述
在这里插入图片描述
类似地,可以根据服务来确定端口

3、抓包看看

三次握手建立连接
在这里插入图片描述
调用服务期间
在这里插入图片描述

三、探索

1、源码与分析

frp 的程序代码为了糅合 frpc 和 frps 之间的请求,自己在TCP之上进行协议封装,因此大量使用了 channel, 所以代码被割散到各处,很不容易连贯起来

可参见:https://jiajunhuang.com/articles/2019_06_19-frp_source_code_part2.md.html

2、检测与绕过

(1)配置文件

用配置文件是个大把柄

绕过方法:重构,不用配置文件

(2)特征字符串和特征码

命令和log里的特征字符串可以作为检测特征
然后是代码里的特征码

绕过方法:修改掉相应的特征

(3)端口控制

做好端口控制,只开放必须的端口

绕过方法:端口复用

(4)进程和库调用

通过终端的进程链控制和第三方库的调用情况在做检测

绕过方法:白进程利用,尽可能不调用库,加壳,主要是木马免杀那套

结语

frp太有名太成熟了(也就是说针对frp的检测应该也是很成熟的事儿了),但是源码十分分散

猜你喜欢

转载自blog.csdn.net/weixin_44604541/article/details/119735357