frp是什么

frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议,且支持 P2P 通信。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。

在内网渗透中,由于内网主机没有公网ip,本地无法直接对内网访问或扫描,这时可以搭建代理,frp就是一种常用的代理工具。

frp怎么用

frp分为服务端和客户端,服务端放在本地可以直接访问的服务器上(通常是自己的公网服务器),客户端放在靶机上。简单配置如下:

frps.ini:

[common]
bind_port = 5000
# auth token
token = 可选,防止别人用自己的服务器乱开代理,但会暴露在靶机上

frpc.ini:

[common]
server_addr = 172.28.1.10
server_port = 5000
token = 可选,防止别人用自己的服务器乱开代理,但会暴露在靶机上
[socks5]
type = tcp
plugin = socks5
remote_port = 5001
plugin_user = 可选,防止别人使用自己搭建的代理
plugin_passwd = 可选,防止别人使用自己搭建的代理

实验准备

ubuntu上用docker compose开几个靶机

docker-compose.yml

version: '3.8'
​
services:
  ub1:
    image: ubuntu:20.04
    container_name: ub1
    ports:
      - "5001:5001"
    command: tail -f /dev/null  # 保持容器运行
    networks:
      net1:
        ipv4_address: 172.28.1.10
​
  ub2:
    image: ubuntu:20.04
    container_name: ub2
    command: tail -f /dev/null  # 保持容器运行
    networks:
      net1:
        ipv4_address: 172.28.1.11
      net2:
        ipv4_address: 172.28.2.10
​
  ub3:
    image: ubuntu:20.04
    container_name: ub3
    command: tail -f /dev/null  # 保持容器运行
    networks:
      net2:
        ipv4_address: 172.28.2.11
​
networks:
  net1:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.1.0/24
  net2:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.2.0/24
​

docker compose up -d

然后传frp

docker cp frp_0.51.3_linux_amd64/frps ub1:/
docker cp frp_0.51.3_linux_amd64/frpc ub2:/

然后写配置,因为容器里没有编辑器,只能写好了往里传

一级代理

先搭一级代理,在ub1上开frps,在ub2上开frpc

ub1s.ini

[common]
bind_port = 5000
token = bbbbbbp

ub2c.ini

[common]
server_addr = 172.28.1.10 #frps的ip
server_port = 5000 #frps的端口
token = bbbbbbp #frps的token
[socks5]
type = tcp
plugin = socks5 #代理协议
remote_port = 5001 #要在服务器上开的端口
plugin_user = 8848 #socks5账号
plugin_passwd = tjsj #socks5密码

传进容器

docker cp frp_0.51.3_linux_amd64/ub1s.ini ub1:/
docker cp frp_0.51.3_linux_amd64/ub2c.ini ub2:/

然后开起来

docker exec -d ub1 /frps -c /ub1s.ini
docker exec -d ub2 /frpc -c /ub2c.ini

换到kali,用proxychains连接

vim /etc/proxychains4.conf

修改最后的[ProxyList]

[ProxyList]
# add proxy here ...
# meanwile
# defaults set to "tor"
socks5  192.168.5.130 5001 8848 tjsj

协议 ip 端口 账号 密码,如果frpc.ini里配的什么就写什么,没配就不写

然后proxychains4 要执行的命令

在ubuntu上开一个web服务看请求来源:

python -m http.server 80

然后在kali上访问webproxychains4 curl 192.168.5.130

┌──(root㉿kali)-[~]
└─# proxychains4 curl 192.168.5.130
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17
[proxychains] Strict chain  ...  192.168.5.130:5001  ...  192.168.5.130:80  ...  OK
<h1>hello</h1>

到ubuntu的shell里看日志

root@ubuntu:/var/www/html# python -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
172.28.1.11 - - [18/Oct/2024 02:41:19] "GET / HTTP/1.1" 200 -

可以看到是172.28.1.11来的,也就是ub2,说明代理有效

二级代理

二级代理就是再套一层,在ub2上再开个frps,ub3上开个frpc

传frp

docker cp frp_0.51.3_linux_amd64/frps ub2:/
docker cp frp_0.51.3_linux_amd64/frpc ub3:/

写配置

ub2s.ini

[common]
bind_port = 5000
token = bbbbbbp

ub3c.ini

[common]
server_addr = 172.28.2.10 #frps的ip
server_port = 5000 #frps的端口
token = bbbbbbp #frps的token
[socks5]
type = tcp
plugin = socks5 #代理协议
remote_port = 5001 #要在服务器上开的端口
plugin_user = 8848 #socks5账号
plugin_passwd = tjsj #socks5密码

传进容器

docker cp frp_0.51.3_linux_amd64/ub2s.ini ub2:/
docker cp frp_0.51.3_linux_amd64/ub3c.ini ub3:/

然后开起来

docker exec -d ub2 /frps -c /ub2s.ini
docker exec -d ub3 /frpc -c /ub3c.ini

然后在/etc/proxychains4.conf的最后加一行,结果如下

[ProxyList]
# add proxy here ...
# meanwile
# defaults set to "tor"
socks5 192.168.5.130 5001 8848 tjsj
socks5 127.0.0.1 5001 8848 tjsj
​

然后kali访问web

┌──(root㉿kali)-[~]
└─# proxychains4 curl 192.168.5.130
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17
[proxychains] Strict chain  ...  192.168.5.130:5001  ...  127.0.0.1:5001  ...  192.168.5.130:80  ...  OK
<h1>hello</h1>
​

可以看到[proxychains] Strict chain ... 192.168.5.130:5001 ... 127.0.0.1:5001 ... 192.168.5.130:80,说明走了两级代理到的web

到ubuntu看日志,来源是ub3的ip

root@ubuntu:/var/www/html# python -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
172.28.2.11 - - [18/Oct/2024 03:00:43] "GET / HTTP/1.1" 200 -

流量分析

在ubuntu上开frpc,kali开frps,同时在kali上开wireshark,方便查看frp流量

保存流量包到本机查看

新版本的frp默认开启了TLS加密,所以看不出流量特征

https://gofrp.org/zh-cn/docs/features/common/network/network-tls/

从 v0.50.0 开始,transport.tls.enable 的默认值将会为 true,默认开启 TLS 协议加密。

如果 frps 端没有配置证书,则会使用随机生成的证书来加密流量。

默认情况下,frpc 开启 TLS 加密功能,但是不校验 frps 的证书。

修改frpc.ini,在common里添加tls_enable = false

[common]
server_addr = 192.168.5.130
server_port = 5000
token = bbbbbbp
tls_enable = false
[socks5]
type = tcp
plugin = socks5
remote_port = 5001
plugin_user = 8848
plugin_passwd = tjsj

重新用wireshark抓frp的连接流量,发现frp连接时的流量特征

建立时

其中第一个包是frpc发给frps,的里面包含了靶机的操作系统信息

{"version":"0.51.3","os":"linux","arch":"amd64","privilege_key":"133bc97921bf88b8622d4ac43c12f115","timestamp":1729505753,"pool_count":1}

privilege_key每次连接都不一样,不是token

通信时

在使用socks5代理通信的时候,还会泄露ip和协议:

{"proxy_name":"socks5","src_addr":"127.0.0.1","dst_addr":"127.0.0.1","src_port":55588,"dst_port":5001}

这里都是本地看不出来

socks5的账号密码

socks5代理流量的内容

懒狗一条