maozhenyu 发表于 2020-4-13 16:53

解决Cisco Anyconnect 客户端不让改路由表的问题

本帖最后由 maozhenyu 于 2020-5-30 13:27 编辑

这个问题的来源是:(1)部分使用Cisco Anyconnect当VPN的网络部署方会设置本地的路由模式为Split Include,只让需要的流量通过VPN,其余部分的继续走本地网络,减轻部署方服务器的负担。然而此时用户需要所有流量全都走这个VPN,或者至少指定的网站走这个VPN(懂的人自然懂这是要干什么)(2)部分VPN部署方强行带走了所有Traffic(Tunneling All Traffic),导致需要访问无关资源的时候访问速度不理想。

上述两个场景都涉及到需要在连接建立后,手动添加/删除路由表。那么我们先来试试直接改路由表行不行

1. netstat -ar
可以当前的路由表,里面能看到一些VPN路由记录
Destination      Gateway            Flags      Refs      Use   Netif Expire
128.97             vpn-whatever.edu   UGSc         0         0   utun2
128.32             vpn-whatever.gov   UGSc         0         0   utun2
192.168.0          link#7             UCS             1      0   en2      !
255.255.255.255/32 link#7             UCS             0      0   en2      !

很明显,Netif指向utun2的记录就是VPN将会带走的流量。如果我们试图增加一条路由记录:
sudo route -nv add -net 172.217.6.4/32 -interface utun1 -static
再查看路由表,发现毫无变化。甚至你多执行几次,他都不会提示你有重复记录。看起来Cisco的客户端很有可能做了什么坏事,把我们对路由表的修改给拦截了。

打开vpnagentd进行分析,搜索了一下route、monitor、hook等关键词运气有点好,直接在Import表里找到了CHostConfigMgr::StartInterfaceAndRouteMonitoring(void)这样一个函数,函数的来源是/opt/cisco/anyconnect/lib/libvpnagentutilities.dylib。PS. 后来在stackoverflow上查到了有先人已经这样做过了,不过那个时候的方法现在有很多已经不好用了,而且没查到Windows版的解决方案,后文中我会提及。
查了一下caller,发现有一个判断,判断返回得是0才能继续执行下去。

Linux和Mac上直接可以在vpnagentd里下手,

直接改函数绑定的地方就行,把整段代码给nop掉问题就能解决。(因为是x86_64的程序,而caller入参rax为0,rax会继续保持0,这样返回值就默认为0了)
Windows下就比较愚蠢了,程序还是32位的。。。得在对应的vpnagentutilities.dll里改,不能简单地用ret,因为此时eax值不为0,程序会报错退出。那么就在前面加一段mov eax, 0不就好了,优雅一点写xor eax, eax可以少改几个字节。


这样就搞定了。Linux/Mac下直接终止vpnagentd重启一次即可,Windows下得重启vpnagent.exe对应的系统服务。然后再连接Cisco Anyconnect,尝试添加路由表

添加两次,发现显示记录重复了。使用netstat -ar可以看到路由表了。使用traceroute也能注意到该IP地址的路由指向.......嗯?为什么连不通?ping一下呢?Hmm,ping不通?直接访问呢?打不开,什么鬼。

发现问题了,Anyconnect的客户端设置了一个类似防火墙的策略,禁止非内置路由表以外的访问。(在Windows下会表现为General Failure/一般错误,稍有经验的人就会意识到这是防火墙的问题)

这个问题的解决方案在Mac和Linux上还是一如既往的straightforward。肯定出现在packet filter里,只要轻轻地:

sudo pfctl -f ohmygod.conf

conf文件内写:

pass out log on utun1 inet from 0.0.0.0/0 to 0.0.0.0/0tag cisco_anyconnect_vpn_pass
pass in log on utun1 inet from 0.0.0.0/0 to 0.0.0.0/0tag cisco_anyconnect_vpn_pass

随着回车键发出的愉悦声音,你会惊讶地发现
traceroute to 172.217.6.4 (172.217.6.4), 64 hops max, 52 byte packets
1omg.myvpn.edu (192.17.88.29)74.064 ms73.639 ms73.663 ms
*****
*****

然后发出内心的感叹:“啊,通了。”

然而在Windows版,客户端的逻辑不太一样,事情变得复杂起来。我大概用了半天的时间,寻找那些调用到底层防火墙/Filter的API,然后回溯试图寻找程序,替换,尝试,失败,替换,尝试,失败。
(省略寻找的过程。大致上是从可能的代码片段找起,然后向上溯源找出来的)
最终发现了两个函数 CHostConfigMgr::ApplyDynamicFilteringOnNewInterfaces 和 CHostConfigMgr::applyFilterConfiguration

patch这两个函数,用之前所说的同样方法干掉这个函数之后,Windows下也通了。


kuan99118 发表于 2020-4-17 14:27

maozhenyu 发表于 2020-4-17 12:22
笑在我不知道你究竟是为了学习交流逆向分析而来。还是单纯地发点“更有意义”的灌水而来。一个希望交流学 ...

不小心弄坏了,就重弄,咋了有错吗!干什么事不是这样!瞎BB啥!

linuxprobe 发表于 2020-4-14 10:27

会不会直接把软件调崩溃了。

kuan99118 发表于 2020-4-16 11:31

maozhenyu 发表于 2020-4-16 09:19
我为什么要浪费这么多时间去重装?搞笑不搞笑

有球的个笑的。屁大点儿的软件。

tpgf 发表于 2020-4-13 17:28

感谢楼主分享经验

winh0 发表于 2020-4-13 20:58

涨知识啦,thanks

lyj17335671675 发表于 2020-4-14 00:22

感谢分享

werner 发表于 2020-4-14 00:52

请问您用的是哪个版本的anyconnect?我用x32dbg调试的时候找不到您说的这两个函数?StartInterfaceAndRouteMonitoring这个函数虽然有,但是是在CInterfaceRouteMonitorCommon下面的。方便的话能分享下修改好的dll吗?

kuan99118 发表于 2020-4-14 07:43

高手!充分利用资源!

dzwindys 发表于 2020-4-14 08:25

非常感谢楼主分享经验

zote 发表于 2020-4-14 10:57

谢谢楼主,收藏了

maozhenyu 发表于 2020-4-14 11:10

linuxprobe 发表于 2020-4-14 10:27
会不会直接把软件调崩溃了。

????你说这话是认真的?
页: [1] 2 3
查看完整版本: 解决Cisco Anyconnect 客户端不让改路由表的问题