iptables -t nat -A OUTPUT -d 119.188.245.15 -j DNAT --to-destination 192.168.31.106
没想到这次这个app也学聪明了,在关键功能的地方(so层)调用了清空iptables的指令su -c iptables -Fsu -c iptables -X
如何解决呢?修改app不太现实,这个app签名效验之类的做得很死,而且混淆严重,不太能理清验证逻辑。
hook system调用呢?这个app发挥作用的本身就是一个magisk的riru模块。此外清空iptables在很多地方都做了,不一定能hook干净。我尝试了用magisk模块直接替换掉
/system/bin/iptables
,可是替换后系统就无法正常联网了(原因未知)。最后,我终于找到了一种不修改原来iptables实现劫持调用的方法:利用系统PATH的优先级。在我的安卓11设备上,在adb shell中输入
$PATH
获取的的PATH如下:/product/bin/apex/com.android.runtime/bin/apex/com.android.art/bin/system_ext/bin/system/bin/system/xbin/odm/bin/vendor/bin
需要指出的是,系统在查找可执行文件时是依照PATH顺序从前往后查找的。原本的iptables在/system/bin
目录下,可见/product/bin
,/system_ext/bin
优先级都比它高,而恰恰magisk提供了挂载文件到这两个目录的能力。经过我的测试,确实可以将自己写的iptables挂载到/product/bin
来实现劫持对iptables
的调用。自己写的iptables代码也很简单,在对传入的参数进行审查后再使用绝对路径调用/system/bin/iptables
#include <stdio.h>#include <string.h>#include <stdlib.h>int main(int argc, char *argv[]){ char *cmd = (char *)malloc(1024); memset(cmd, 0, 1024); strcpy(cmd, "/system/bin/iptables"); for (int i = 1; i < argc; i++) { strcat(cmd, " "); strcat(cmd, argv[i]); } if (strstr(cmd, "-F") ||strstr(cmd, "-X") || strstr(cmd, "-t nat -F") ||strstr(cmd, "-t nat -X")) { printf("Permission denied--From fake iptables\n"); return 0; } // printf("%s", cmd); system(cmd); free(cmd); return 0;}
将c程序使用ndk编译即可。另外提一点就是编译好的程序要放在magisk模块的\system\product\bin
路径中,magisk会自动将其挂载到\product\bin
。在安卓11以下,magisk的su存储在最高优先级的/sbin
路径中,而安卓11之后取消了这个路径,所以利用这一点,我们甚至可以劫持magisk的su来实现更多元而相对修改magisk更简单的定制。防范这种劫持的方法也很简单,在调用时使用绝对路径/system/bin/iptables
即可,当然,这不免失去了一些兼容性。
发表评论: