每当我安装并启动Frida-SERVER时,我都会有一款运行异常的银行应用程序.经过一些研究,我发现一些应用程序可能能够在NDK级别上对运行Frida-SERVER的设备进行端口扫描.我试着将S的默认端口改为其他端口,但我仍在重现该应用程序的确切行为.

根据mullerberndt,我已经组合了一个脚本来判断Frida-SERVER的缺省端口和整个端口范围,并发送D-BUS协议探测

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>

struct sockaddr_in sa;

int detect_frida_server(void);
bool check_protocol(int);
bool check_all_ports(int);

int main() {
    int res = detect_frida_server();
    printf("Detection result return value: %d\n", res);
    return 0;
}

int detect_frida_server() {
    const int fs_port = 27047;
    memset(&sa, 0 , sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_port = htons(fs_port);
    inet_aton("127.0.0.1", &(sa.sin_addr));

    int sock = socket(AF_INET, SOCK_STREAM, 0);

    if(connect(sock, (struct sockaddr *) &sa, sizeof sa) != -1) {
        printf("FRIDA DETECTION[1]: Open port: %d\n", fs_port);
        if(check_protocol(sock)) {
            printf("Frida server detected!");
            return 1;
        }
        printf("Suspicious.\n");
        return 2;
    }
    else if(check_all_ports(fs_port)) {
        printf("Frida server detected!");
        return 1;
    }

    if(check_all_ports(fs_port)) {
        printf("Frida server detected!");
        return 1;
    }
    return 0;
}

bool check_all_ports(int port) {
    int i, sock;
    for (i = 0; i <=65535; i++) {
        if(i == port) continue;

        sock = socket(AF_INET, SOCK_STREAM, 0);
        sa.sin_port = htons(i);

        if(connect(sock, (struct sockaddr *) &sa, sizeof sa) != -1)
        {
            printf("FRIDA DETECTION[1]: Open port: %d\n", i);
            if(check_protocol(sock)) return true;
        }
    }

    return false;
}

bool check_protocol(int s) {
    char res[7];
    bool rres = false;

    memset((void*) res, 0, sizeof(res));

    send(s, "\x00", 1, NULL);
    send(s, "AUTH\r\n", 6, NULL);

    usleep(100);

    if(recv(s, res, sizeof(res) - 1, MSG_DONTWAIT) != -1)
        if(strcmp(res, "REJECT") == 0)
            rres = true;

    return rres;
}

用它编译的

\Android\Sdk\ndk\21.4.7075529\toolchains\llvm\prebuilt\windows-x86_64\bin\aarch64-linux-android21-clang detect-fs.c -o detect_frida

并推动着

adb push detect_frida /data/local/tmp/detect-fs-v2

在运行代码时,我能够检测到打开的端口和connect,但D-BUS协议似乎不起作用,因此陷入循环(如果连接,它将打印检测到的Frida):

here

因此,我将代码精简为只连接到端口并返回true/false值:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>

int port_scan(void);

int main() {
    int open = port_scan();
    if(open) printf("Port is open at: %d\n", open);
    else printf("No ports were found to be open. System secure.\n");
    return 0;
}

int port_scan() {
    struct sockaddr_in sa;
    memset(&sa, 0 , sizeof(sa));
    sa.sin_family = AF_INET;
    
    for(int i = 0; i < 65535; i++) {
        int sock = socket(AF_INET, SOCK_STREAM, 0);
        sa.sin_port = htons(i);
        
        if(connect(sock, (struct sockaddr *) &sa, sizeof sa) != -1) {
            close(sock);
            return i;
        }
        
        
    }
    
    return 0;
}

而不使用连接协议.我怀疑这就是我感兴趣的应用程序正在做的事情.公平地说,我给了我的二进制文件根访问权限,并对二进制文件执行了chmod 775次访问.但我确实想知道,Play Store应用程序是否能够在NDK级别的非根基环境中检测到这一点,而不需要费力地构建一个APK来测试我自己.

在非根Android环境中,不允许端口侦听本地主机(甚至不允许端口80上的Web服务器),这合理吗?好吧,因为这个应用程序没有直接抱怨,我知道它在大多数直接的情况下都是有能力的,有理由认为它给了我一个怀疑的好处,但暗示我的环境不安全.

因此,除了Mullerberndt的端口扫描Frida-服务器的方法之外,另一种方法是判断Frida-gadget,我们没有使用它,我们如何编写一个Frida脚本来挂钩连接方法以返回FALSE(即所有端口都已关闭).请记住,我们必须允许合法的连接方法,因为这是具有其自己的后端的应用程序通信方法的基础

此外,在Android设备上扫描所有端口需要多长时间才能作为根/篡改判断的一种独立实用的手段?

推荐答案

在进一步的研究中,我发现我实际上正在运行两个frida-server个实例,一个在默认端口上,另一个在定制端口上.我不得不在我的设备上运行第一个端口扫描程序脚本,并等待它完成.我在Termux上花了大约5到10分钟的时间.

只需在不同的端口上启动服务器,并确保您没有在原始端口上运行任何其他Frida实例就可以解决问题,我的应用程序就不会显示出奇怪的行为

我的结论是,我的目标应用程序实际上只是在判断Frida是否正在使用以下代码监听默认端口27047

 boolean is_frida_server_listening() {
    struct sockaddr_in sa;

    memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_port = htons(27047);
    inet_aton("127.0.0.1", &(sa.sin_addr));

    int sock = socket(AF_INET , SOCK_STREAM , 0);

    if (connect(sock , (struct sockaddr*)&sa , sizeof sa) != -1) {
      /* Frida server detected. Do something… */
    }

}   

来源:The Jiu-Jitsu of Detecting Frida (archived)

这回答了我的问题,即在所有65535个端口上运行完整端口扫描需要多长时间.基本上,在ARM-64 Android设备上只需5-10分钟.对于只需要在几秒钟内完成判断的根检测器来说,这不是一个好的 Select .您只需更改端口即可.Frida的创建者已经改变了他们的握手协议,所以现在不起作用了.

希望这对任何人都有帮助

C++相关问答推荐

如何避免使用相对路径包含在c中

想了解 struct 指针和空指针转换

为什么在Linux(特别是Ubuntu 20.04LTS)上,POSIX共享内存对象在重启后仍然存在,然后突然变成了根用户?

数据包未从DPDK端口传输到内核端口

DPDK-DumpCap不捕获端口上的传入数据包

C编译器是否遵循restrict的正式定义?

当我运行/调试C程序时,Malloc()似乎正在将&q;r\r...&q;赋值给一个指针,我不确定为什么?

为什么我一直收到分段错误?

C:在编译时构建和使用字符串文字的预处理器宏?

覆盖读取函数,但当文件描述符为3或4时,我有问题

试图创建一个基本的Word克隆,但遇到了障碍

为什么电路板被循环删除?

链接器脚本和C程序使用相同的头文件,这可能吗?

为什么argc和argv即使在主函数之外也能工作?

";错误:寄存器的使用无效;当使用-masm=intel;在gcc中,但在AT&;T模式

如何为avr atmega32微控制器构建C代码,通过光电二极管捕获光强度并通过串行通信传输数据

是什么阻止编译器优化手写的 memcmp()?

为什么实现文件中的自由函数默认没有内部链接?

如何在 C 中的 Postgres 函数的表中 for 循环

C 中 struct 体自赋值是否安全?特别是如果一侧是指向 struct 的指针?