C语言 frida-server被端口扫描锁定?

mzillmmw  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(82)

每当我安装并启动frida-server时,我都有一个行为怪异的银行应用程序。经过一些研究,我发现一些应用程序可能能够在NDK级别上对运行frida-server的设备进行端口扫描。我尝试将frida-server的默认端口更改为其他端口,但我仍然再现了应用程序的确切行为。
根据mullerberndt,我编写了一个脚本,该脚本检查frida服务器的默认端口和整个端口范围,并发送一个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 detected”):
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商店应用程序是否能够在NDK级别的非根环境中检测到这一点,而无需尝试构建apk来测试自己。
在一个没有root权限的Android环境中,没有端口被允许监听本地主机,这是合理的吗?(甚至连端口80上的Web服务器都不允许)?好吧,既然应用程序没有直接抱怨root权限,我知道它在大多数情况下都有能力,合理的假设是它给了我一个怀疑的好处,但暗示我的环境不安全。
因此,除了mullerberndt的方法端口扫描的frida-server,替代将检查frida-gadget,这是我们没有使用,我们怎么能写一个frida脚本挂钩连接方法返回假(即所有端口都关闭)。请记住,我们必须允许合法的连接方法,因为这是应用程序通信方法的基础与自己的后端
另外,在android设备上扫描所有端口需要多长时间才能作为root/篡改检查的一种手段?

mspsb9vt

mspsb9vt1#

在进一步的研究中,我发现实际上正在运行两个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分钟。对于一个只需要在几秒钟内完成检查的根检测器来说,这不是一个好的选择。当你可以简单地改变端口时。而且frida的创建者已经改变了他们的握手协议,所以现在不工作了。
希望这对任何人都有帮助

相关问题