基于 Wi-Fi 搭建一个 VoLTE/VoWiFi 环境
2022-3-23 11:50:0 Author: www.4hou.com(查看原文) 阅读量:36 收藏

首先我会通过三个实验来学习VoWifi/VoLTE的工作原理:

使用 fasferraz 的 Python IKEv2/EAP-AKA 实现连接到 VoWifi:失败;

使用 Linphone 连接到 VoLTE:失败;

使用 Wi-Fi 热点、假 DNS 服务器和 VPN 服务器捕获 IMSI:成功;

VoLTE和VoWifi看起来可能很复杂,但要打电话,只需要和两台电脑进行连接就可以了:

1.1.png

VoLTE和VoWifi是基于常见技术的:

在 VoLTE 中,电话通过 SIP 连接到 P-CSCF,这是运营商的 SIP VoIP 服务器。

在VoWifi中,手机首先与运营商的VoWifi VPN服务器ePDG进行IPSec VPN连接。然后通过VPN连接到P-CSCF SIP服务器,比如VoLTE。

然而,VoLTE的实现与我们日常使用的vpn和VoIP软件不兼容。这份来自Sysmocom的报告显示,修改Ubuntu Touch以支持VoLTE需要几个月的时间。

那么,是什么阻止我用普通的VPN软件连接到VoWifi VPN服务器,或者用普通的VoIP软件连接到VoLTE SIP服务器呢?我决定找出答案。

在VMWare Fusion虚拟机上的Ubuntu 21.04上进行的实验,连接到Mint上运行Android 11的Pixel 3 XL上(T-Mobile MVNO)。

连接到VoWifi

为了连接到特殊的VoWifi VPN,我使用了fasferraz的SWu-IKEv2,这是一个IKEv2/IPSec VPN客户端,它使用SIM卡实现了特殊的EAP-AKA认证方法。

在 EAP-AKA 中:

只有运营商和 SIM 卡本身知道密钥 K;

认证时,运营商发送两个值:AUTN 值和 RAND 值;

AUTN 值向 SIM 卡证明它是真正的运营商;

SIM卡用秘钥K对RAND值进行加密,导出两个秘钥:IK、CK和响应值 RES;

它将 RES 值发回给运营商以证明它是真正的 SIM 卡;

手机使用IK 和 CK 加密连接;

运营商使用 K 密钥进行相同的加密以获得预期的 IK、CK 和 RES 值;

运营商在解密连接前将RES值与IK和CK进行比较;

由于没有其他人拥有 K 密钥,因此他们无法窃听或冒充用户/运营商;

综上所述,我需要将AUTN和RAND发送到SIM卡上,并取回RES、IK和CK。

SWu-IKEv2 支持与真正的 SIM 卡进行 EAP-AKA 通信,定义了一个 HTTP API 来与 SIM 卡读卡器通信。

我决定将该API实现为一个Android应用程序,这样我可以在我的手机中使用SIM卡:

Android有一个公共API, TelephonyManager。getIccAuthentication来运行这个身份验证流程;

为 Android 的 Wi-Fi 添加框架,因为存在使用 SIM 卡进行身份验证的 Wi-Fi 热点;

ADB也可以在Android 10及以上版本上使用;

在 Android 8.1 上不可用,我尝试使用其他 SIM 卡 API 来尝试获取此值,但每次都不成功。我构建了一个生成 SIM 身份验证请求的 HTTP 服务器 Android 应用程序:

adb shell sh /sdcard/runsimserver.sh serve 3333

我的应用程序使用http而不是https,因为我不需要处理证书。值得庆幸的是,很容易修补 SWu-IKEv2 以支持纯 http。

如果出现故障,adb logcat -b radio 通常会给出调制解调器的错误消息。

我在网上搜索T-Mobile的ePDG地址,将APN设置为ims,将SWu-IKEv2的SIM读取器地址指向我的手机,并尝试连接:

# python3 swu_emulator.py -m "http://192.168.1.9:3333" -d "ss.epdg.epc.mnc260.mcc310.pub.3gppnetwork.org" -M 310 -N 260 -a "ims"STATE 3:
-------
sending IKE_SA_AUTH (2)
received decoded message:
[[46, [[41, [0, 24, b'', b'']]]]]
received IKE_AUTH (2)
OTHER_ERROR : 24

它会获得大部分握手,包括 SIM 卡凭据,但会在 IKE_SA_AUTH 上返回错误。

可能是因为Mint Mobile要求我在打开Wi-Fi通话前注册一个紧急地址,或者SWu-IKEv2没有实现与T-Mobile/Mint兼容的握手。

事实上,当我尝试Verizon的Wi-Fi呼叫服务器时,SWu-IKEv2甚至无法通过握手的第一步,也无法进行SIM卡认证。我尝试了StrongSwan,但无法找出配置文件。

连接到 VoLTE

如果我无法连接到VoWifi VPN,是否可以直接连接到VoLTE SIP服务器?

在Android上,我可以使用dumpsys找到SIP服务器地址:

$ dumpsys telephony.registryPcscfAddresses: [ /fd00:1234:5678:1234::1,/fd00:1234:1:123::1,/fd00:1234:5678:1234::2 ]

这是一个私有的(fd00::) IP地址,所以不能通过互联网访问,但我可以通过Wi-Fi从我的手机访问它。

我首先尝试了SIP测试器sipp,看看它是否可以进行任何SIP连接:

$ sipp -sn uac fd00:1234:1:123::1 -m 1 -auth_uri "sip:[email protected]"
Resolving remote host 'fd00:1234:1:123::1'... Done.
2021-11-14 12:17:42.188810 1636910262.188810: Aborting call on unexpected message for Call-Id '[email protected]:5678:1234:5678:1234:5678:1234:5678': while expecting '100' (index 1), received 'SIP/2.0 403 Forbidden
Via: SIP/2.0/UDP [1234:5678:1234:5678:1234:5678:1234:5678]:5060;branch=<>
To: service ;tag=<>
From: sipp ;tag=<>
Call-ID: [email protected]:5678:1234:5678:1234:5678:1234:5678
CSeq: 1 INVITE
Content-Length: 0
 
'

因为它得到了一个SIP响应,所以我决定尝试一下Linphone,看看是否效果更好。

echo "register sip:[email protected] [fd00:1234:5678:1234::1]" | linphone-daemon --config ./lollinphonerc
daemon-linphone>Status: Ok
 
Id: 2
 
daemon-linphone>Quitting...
查看日志,它似乎失败并显示需要扩展消息:
REGISTER sip:ims.mnc260.mcc310.3gppnetwork.org SIP/2.0
Via: SIP/2.0/UDP [1234:5678:1234:5678:1234:5678:1234:5678:3080]:5060;branch=z9hG4bK.CnnLnAH2c;rport
From: ;tag=by3qRAb72
To: sip:[email protected]
CSeq: 21 REGISTER
Call-ID: BqHzXhfQzf
Max-Forwards: 70
Supported: replaces, outbound, gruu, sec-agree
Accept: application/sdp
Accept: text/plain
Accept: application/vnd.gsma.rcs-ft-http+xml
Contact: ;+sip.instance=""
Expires: 0
User-Agent: Unknown (belle-sip/4.4.0)
 
SIP/2.0 421 Extension Required
Via: SIP/2.0/UDP [1234:5678:1234:5678:1234:5678:1234:5678:3080]:5060;received=1234:5678:1234:5678:1234:5678:1234:5678:3080;rport=5060;branch=z9hG4bK.MEpCNGpx0
To: ;tag=hmpyfr9c6bln4s4tqy698hv3v
From: ;tag=LEotRcq8b
Call-ID: H3P5ZXk7Z2
CSeq: 20 REGISTER
Require: sec-agree
Content-Length: 0

在查看了真正的 SIP 客户端有哪些扩展之后,我尝试将此行添加到 Linphone 配置中。

[sip]
supported=replaces, outbound, gruu, sec-agree

这在标题中设置了 Supported: replaces, outbound, gruu, sec-agree,但我得到了完全相同的 Extension Required 错误。

假的VoWifi ePDG

如上所述,所以连接到运营商是不可能的。

值得庆幸的是,伪装成是运营商来获取 IMSI 很容易,并且有如何做到这一点的指南。

为了伪装成 ePDG Wi-Fi 呼叫 VPN,我创建了一个 StrongSwan VPN 配置:

config setup
    charondebug="ike 4"
conn ikev2-vpn
    auto=add
    type=tunnel
    keyexchange=ikev2
    left=%any
    [email protected]
    right=%any
    rightid=%any
    rightauth=eap-aka
    rightsourceip=10.10.10.0/24
    rightdns=8.8.8.8,8.8.4.4

开始 StrongSwan:

sudo ipsec start --nofork --conf hello.conf

启动了一个 DNS 服务器,将 ePDG VPN 服务器域重定向到我的假 Wi-Fi 呼叫服务器:

sudo dnsmasq -d --no-resolv --no-hosts --log-queries --server 8.8.8.8 --address=/epdg.epc.mnc260.mcc310.pub.3gppnetwork.org/192.168.1.10

然后我更改了手机上的 DNS,激活了 Wi-Fi 呼叫,然后在我的控制台上看到了这个:

07[NET] received packet: from 192.168.1.9[40844] to 192.168.1.10[500] (496 bytes)
07[ENC] parsed IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) ]
07[IKE] 192.168.1.9 is initiating an IKE_SA
07[CFG] selected proposal: IKE:AES_CBC_128/AES_XCBC_96/PRF_AES128_XCBC/MODP_2048
07[ENC] generating IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(CHDLESS_SUP) N(MULT_AUTH) ]
07[NET] sending packet: from 192.168.1.10[500] to 192.168.1.9[40844] (456 bytes)
08[NET] received packet: from 192.168.1.9[40844] to 192.168.1.10[500] (348 bytes)
08[ENC] unknown attribute type (16386)
08[ENC] parsed IKE_AUTH request 1 [ IDi IDr CPRQ((16386) DNS6 DNS6 ADDR6) SA TSi TSr ]
08[CFG] looking for peer configs matching 192.168.1.10[ims]...192.168.1.9[[email protected]]
08[CFG] no matching peer config found
08[ENC] generating IKE_AUTH response 1 [ N(AUTH_FAILED) ]
08[NET] sending packet: from 192.168.1.10[500] to 192.168.1.9[40844] (76 bytes)

还有我的 IMSI,发送给任何控制 Wi-Fi 网络、DNS 和 VPN 服务器的对手。

基于 Wi-Fi 搭建一个 VoLTE/VoWiFi 环境

对VoLTE/VoWiFi 的研究不需要昂贵的设备!通过使用免费软件设置你自己的 Wi-Fi 呼叫服务器,了解 VoLTE/VoWiFi 的工作原理。

2.1.jpg

我会在本文中向你展示如何接管越狱 iPhone 上的 Wi-Fi 通话,并将其集成到本地电话拨号器和短信应用程序中,就像真正的运营商一样。

我的最终目标是发行我自己的 SIM 卡,通过 Wi-Fi 将任何越狱或未越狱的手机连接到我的电话网络。

VoLTE 和 Wi-Fi 通话基于 IPsec/IKEv2 和 SIP 等开放标准,因此我们的电话网络将使用免费软件构建:

iPhone -> 越狱调整以重定向 Wi-Fi 呼叫 -> 我的 Docker 容器 -> StrongSwan -> Kamailio;

检查 VoWiFi

要了解 VoLTE 和 VoWiFi,首先要在你拨打电话或发送 SMS 时捕获手机的流量。

你只需要一部 iPhone 和一台装有 Xcode 和 Wireshark 的 Mac。

Xcode 提供了 rvictl 工具来捕获来自 iPhone 的所有网络流量,无需越狱。

如果你没有 Mac,gh2o 的 rvi_capture 可以在 Linux 和 Windows 上捕获。

所有电话和运营商之间的SIP消息是可见的,完全不加密。你可以看到当你拨打另一个电话时会发生什么:

2.2.png

或者你如何接收短信:

2.3.png

在 VoWiFi 上,你甚至可以转储实际的语音编解码器数据包。

此外,iPhone 还提供来自 VoWiFi ePDG VPN 隧道和 SMS 处理的日志:

在 Mac 上打开控制台应用程序,过滤到 CommCenter,然后启用“操作 -> 包含信息消息/包含调试消息”。然后,过滤 CommCenter 以获取 VoLTE/VoWiFi 消息,例如此 IKEv2 握手:

2.4.png

建立自己的电话网络

如果你不想只查看 VoLTE/VoWiFi 数据包怎么办?如果你想建立自己的网络怎么办?为此,你需要一个越狱的 iPhone 和一个 Docker 容器。

我在 iOS 14.1 上使用带有 Verizon SIM 卡的越狱 iPhone 12。

如果你使用的是 Android,则搭载 Android 10 及更高版本的设备(所有 2020 年或更高版本的设备)可能会在没有 root 的情况下重定向 Wi-Fi 呼叫,但我还没有尝试过。

重定向 ePDG 连接

我们的目标是 VoWiFi(Wi-Fi 通话),因为运行 VoLTE 网络需要至少 150 美元的收音机, 并获得LTE频率的广播许可。 Wi-Fi 不需要任何特殊的硬件或繁文缛节。

Wi-Fi 通话使用 IPsec/IKEv2 VPN 隧道进行保护,并使用 EAP-AKA 进行身份验证,它使用 SIM 卡上只有运营商知道的密钥。

由于我没有空白 SIM 卡,我编写了一个越狱插件,用简单的预共享密钥(密码)身份验证替换 SIM 卡检查。

要运行调整,你需要:

越狱你的手机并安装 Substrate 或其他方法挂钩平台;

设置 Theos;

复制RedirectVoWiFiTweak;

将服务器地址指向你的 VoWiFi 服务器的地址;

安装包;

将你的手机置于飞行模式,然后启用Wi-Fi通话(设置->蜂窝-> Wi-Fi通话);

最终结果:VoWifi 隧道为你的 IPsec/IKEv2 VPN 服务器创建了一个 VPN,而不是 Verizon 的。

我是如何构建调整的

iPhone 在用户空间中运行整个 VoLTE/VoWiFi 堆栈:通过越狱,我们可以做任何事情。但是,我的最终目标是在未越狱的手机上使用自定义 SIM 卡进行这项工作,所以我只做了最小的更改。

ePDG 只是一个 IPsec/IKEv2 VPN 隧道,在 SIM 卡上具有 EAP-AKA 身份验证。要禁用 EAP-AKA 身份验证并切换到 PSK:

我运行nm CommCenter,看到它正在使用NEIPSecIKECreateSessionWithInterface启动VPN隧道;

我在NetworkExtensions中找到了这个符号,并在Ghidra中分解了它;

它是一个包装器-[NEIKEv2Session

initWithIKEConfig:firstChildConfig:sessionConfig:queue:ipsecInterface:ikeSocketHandler: ssession:packetDelegate:] ';

我钩住了那个方法,并删除了参数;

我用 PSK 在 Mac 上创建了另一个 IPsec/IKEv2 隧道;

我附加到 macOS 的 VPN 实现:

lldb -n NEIKEv2Provider -w
b initWithIKEConfig:firstChildConfig:sessionConfig:queue:ipsecInterface:ikeSocketHandler:saSession:packetDelegate:

我将其参数与VoLTE ePDG隧道进行了比较,以了解macOS如何设置PSK;

我为PSK设置了相同的标志;

这是我第一次调试 iPhone,结果如下:

dlevi309 向我发送拉取请求以自动重启 CommCenter;

hbkirb 将我指向 HearseDev 的 Theos 徽标语言的 clang 格式包装器;

用到的资源如下:

Kanns103 的调整开发指南;

elihwyma 的 commcenterpatch13,它也挂钩了 CommCenter;

拥有StrongSwan 和 Kamailio 的 Wi-Fi 呼叫服务器

用一个电话与两个服务通话来建立VoWifi:

ePDG,一个 IPsec/IKEv2 VPN 服务器,我们使用 StrongSwan;

P-CSCF,一个 SIP VoIP 服务器,我们使用 Kamailio;

我用两个预装做了一个Docker容器。

在 macOS 12.1/Mac Mini 2020 (M1)/Docker for Mac 上测试。

首先,如果你不在 Verizon 上,请在配置中更改 IMS 域。你可以通过使用 rvictl 捕获 SIP REGISTER 请求来查找域。

然后,运行:

docker compose build
docker compose up

等待来自电话的连接:

12[IKE] IKE_SA ikev2-vpn-iphone[4] established between 172.19.0.2[ims]...172.19.0.1
12[IKE] IKE_SA ikev2-vpn-iphone[4] state change: CONNECTING => ESTABLISHED

然后尝试向手机发送短信:

ssh -p 22222 [email protected]
Password: vowifi
$ encodesms 15554443333 19085823275 "hello"

或紧急警报:

$ encodesms_cdma emerg 19085823275 "duck and cover"

或者打个电话:

$ baresip
/uanew sip:[email protected]
/dial sip:[email protected]

甚至尝试在你自己的网络上复制Purdue大学研究人员的 VoLTE/VoWiFi 攻击。

StrongSwan 配置:

PSK 的配置;

P-CSCF(SIP 服务器)的配置。 (21 是 P_CSCF_IP6_ADDRESS);

配置密码套件,详细情况请参阅 Verizon 的 CarrierBundle

给 iPhone 一个 /64 IPv6 地址范围:

通常,VPN只给出一个/128的地址,但iPhone希望得到一个/64的地址,并且总是用一个随机值覆盖底部的64位。

感谢 Kage Systems的 Alan 记录了如何让 StrongSwan 作为 iPhone 的 ePDG 工作。

Kamailio 资源

我现在只使用存储的 Kamailio 配置,没有身份验证;

配置调整以侦听 IPv6 并接受 vzims.com SIP 域;

[Nick vs Networking]是一个拥有大量关于设置电话网络的资源的网站,包括一个Kamailio教程,它对理解概念很有帮助。

拨打电话

编解码器很难;

手机使用受专利保护的 EVS 或 AMR-WB;

Linphone 做不到——它只支持像 Opus 这样的开放编解码器;

Baresip 说它支持它,但如果我接听,通话就会结束;

解决方案是添加一个额外的服务器进行动态转码;

Kamailio 不支持 iPhone 手机应用程序使用的 tel: url;

所以你不能通过电话拨号;

有补丁,但不在上游;

没试过;

向手机发送短信

普通 SIP 应用程序使用带有 text/plain 的 SIP MESSAGE;

VoLTE/VoWiFi 不支持无效的内容类型;

对于 VoLTE/VoWiFi,需要编码为 GSM 或 CDMA 的 SMS 格式;

有大量在线资源可用于编码 GSM;

对于 GSM,查看了 Wireshark 从我的手机中捕获的短信;

使用 Android Emulator 的 sms pdu 功能进行调试;

adb logcat -b radio 查看错误;

收到手机发来的短信

手机可以接收来自电脑的短信,但不能发送到电脑或私人网络上的任何其他手机;

如果你看一下,它不会直接将 SMS 发送到其他号码,而是发送到德克萨斯州的某个号码?

这是 SMSC ,运营商的 SMS 网关;

短信可以发送到关机的手机上;

SMSC 存储 SMS 并在目标电话在线时发送它;

多个 SMSC 实现,例如 OpenBTS 的 SMQueue、Osmocom 的 OsmoMSC;

我没有尝试集成,但应该很简单。

制作广播消息

你已经可以通过真实的电话网络研究短信;

我想演示一些你只能在你自己的私人电话网络上做的事情;

让我们发送小区广播/紧急警报/总统警报!

过去的研究人员只能使用私人 LTE 设备发送紧急广播;

GSM 小区广播不使用 SMS,它们使用我们无法通过 VoLTE/VoWiFi 发送的单独 SMS-CB 消息;

但是CDMA两者都使用SMS!

Verizon 要求通过 VoLTE 使用 GSM (3GPP) 和 CDMA (3GPP2) SMS 格式;

编码的CDMA格式短信;

通过解码我自己的代码的消息在Android模拟器上测试;

一旦我知道如何发送CDMA格式的短信,我就把短信类型改为广播,并设置为“紧急警报”(或“总统警报”)。

防御措施

添加过滤器、防火墙和身份验证以将真实电话号码/IMSI 映射到我自己的 1-555-xxx-xxxx 号码;

过滤掉手机发送的任何位置;

发送 SIM 卡,以便任何手机都可以使用,而不仅仅是越狱的 iPhone;

弄清楚如何保护网络免受滥用,例如,仅限邀请的系统?

建立一个电话对电话短信系统;

为 VoIP 应用程序设置转码到电话呼叫;

如果你想基于 Wi-Fi 搭建一个 VoLTE/VoWiFi 环境,则必须满足以下条件:

你的设备类型(iPhone、Android、VoIP 电话应用程序或其他)必须支持 Wi-Fi 通话;

你想要的 1-555-xxx-xxxx 电话号码;

知道如何制作一张 SIM 卡;

如果你使用的是已经越狱的手机,需要知道手机的运营商和号码;

总结

你不需要特殊的设备来建立你自己的电话网络;

你可以用你的iPhone和Mac来捕捉你手机的VoLTE/VoWiFi流量;

你只需越狱调整和免费软件即可设置自己的 Wi-Fi 呼叫服务器;

本文翻译自:https://worthdoingbadly.com/vowifi2/如若转载,请注明原文地址


文章来源: https://www.4hou.com/posts/PWV6
如有侵权请联系:admin#unsafe.sh