当前位置: 首页 > article >正文

ADB加密实例

ADB加密实例

  • 1. adb shell加密访问
  • 2 adb文件传输命令加密访问

通常我们的MIFI USB端口仅枚举rndis和mass端口,为了便于开发人员、工厂维护人员调试和运营商认证,会预留出可通过SCSI指令切口支持ADB端口,该机制可能会被作为切入点破解侵入系统,对于系统安全存在极大风险。因此我们需要对adb访问进行加密控制。
adb的指令在 ADB介绍也进行了列举,有应用管理、文件管理、日志管理、设备管理等,而MIFI产品常用的主要是文件管理和日志管理。因此我们按照Penetration Test要求,对于常用adb操作进行加密处理。

1. adb shell加密访问

最常使用的就是通过adb shell去访问adb设备终端,可以在终端中进行文件访问、应用管理、日志管理等操作,因此对于该指令需进行加密操作。

X12中adb源码位置在sdx12-ap/system/core/adb/,在使用adb shell命令登陆系统时,adb服务(adbd)为我们fork一个子shell作为终端,源码如下:

system\core\adb\services.cpp
#define SHELL_COMMAND "/bin/sh"static int create_subproc_thread(const char *name, const subproc_mode mode)
{switch (mode) {
    case SUBPROC_PTY:
        ret_fd = create_subproc_pty(SHELL_COMMAND, arg0, arg1, &pid);
        break;
    case SUBPROC_RAW:
        ret_fd = create_subproc_raw(SHELL_COMMAND, arg0, arg1, &pid);
        break;
    default:
        fprintf(stderr, "invalid subproc_mode %d\n", mode);
        return -1;
    }
    D("create_subproc ret_fd=%d pid=%d\n", ret_fd, pid);
    stinfo* sti = reinterpret_cast<stinfo*>(malloc(sizeof(stinfo)));
    if(sti == 0) fatal("cannot allocate stinfo");
    sti->func = subproc_waiter_service;
    sti->cookie = (void*) (uintptr_t) pid;
    sti->fd = ret_fd;
    if (adb_thread_create(&t, service_bootstrap_func, sti)) {
        free(sti);
        adb_close(ret_fd);
        fprintf(stderr, "cannot create service thread\n");
        return -1;
    }}

因此我们可以将shell替换成可登陆的shell应用,如/bin/login,该应用便可以实现用户名和密码登录,用户名和密码均来自于sdx12-ap/poky/meta-qti-bsp/recipes-core/base-passwd/base-passwd-3.5.29/add-hash.patch,该patch中包含了用户名、密码、密码加密方式等,最终会生成按照冒号分隔的9段密码规则的字段存储在文件/etc/shadow中,当前linux默认的用户名是root、密码是oelinux123、密码加密方式是MD5。

我们修改#define SHELL_COMMAND "/bin/sh"为#define SHELL_COMMAND “/bin/login”,即可实现adb登录访问,编译验证如下:

C:\platform-tools>adb shell
sdxnightjar login: root
Password:
Last login: Wed Aug  9 11:28:44 UTC 2023 on pts/0
No directory, logging in with HOME=/
~ #

adb shell加密访问是生效的。但每次都需要输入账号密码是比较麻烦的,由于账户名是默认不变的,因此我们将账户名在adb中固定,每次只需要输入密码即可。

system\core\adb\services.cpp
**#define SHELL_COMMAND "/bin/login"**static int create_subproc_thread(const char *name, const subproc_mode mode)
{switch (mode) {
    case SUBPROC_PTY:
        **ret_fd = create_subproc_pty(SHELL_COMMAND, "-p", "root", &pid);**
        break;
    case SUBPROC_RAW:
        **ret_fd = create_subproc_raw(SHELL_COMMAND, "-p", "root", &pid);**
break;
    default:
        fprintf(stderr, "invalid subproc_mode %d\n", mode);
        return -1;
    }
    D("create_subproc ret_fd=%d pid=%d\n", ret_fd, pid);
    stinfo* sti = reinterpret_cast<stinfo*>(malloc(sizeof(stinfo)));
    if(sti == 0) fatal("cannot allocate stinfo");
    sti->func = subproc_waiter_service;
    sti->cookie = (void*) (uintptr_t) pid;
    sti->fd = ret_fd;
    if (adb_thread_create(&t, service_bootstrap_func, sti)) {
        free(sti);
        adb_close(ret_fd);
        fprintf(stderr, "cannot create service thread\n");
        return -1;
    }}

编译验证:

C:\platform-tools>adb shell
Password:
Last login: Wed Aug  9 11:28:58 UTC 2023 on pts/0
No directory, logging in with HOME=/
~ #

在这里插入图片描述

2 adb文件传输命令加密访问

上述章节仅限制了adb shell功能,adb其他功能是没有受到限制的,如adb push\pull等文件传输命令。为了对常用指令进行加密控制,我们设计了如下机制:

  1. 当/etc/lock_flag 内容为 lock 时,禁用 adb shell 功能。当此文件内容为空或文件不存在时,启用adb shell。
  2. 当/etc/adb_flag文件存在时,启用adb shell。 oem_stop_service_list()函数中通过字符串判断定义了当 adb shell 禁用时具体哪些功能会被禁用。
  3. adb指令下发 ->service_to_fd() ->oem_shell_access()判断是否为adb激活,检测到maigc字符串则赋 g_access_adb = ACCESS_ADB ->oem_security_access_adb()判断lock_flag 和 adb_flag,若配置了lock则oem_stop_service_list()判断当前功能是否在禁用列表中,若配置在禁用列表中则退出。具体代码如下:
 int service_to_fd(const char *name)
{
    int ret = -1;

    D("service_to_fd:%s\n", name);

    //for debug, we send a magic string to access shell
    if(!HOST && !strncmp(name, "shell:", 6))
    {
        //backdoor for this
        **oem_shell_access(name);**
    }

    **int running_flag = oem_security_access_adb();
    if (running_flag == 0)
    {
        int stop_list = oem_stop_service_list(name);
        if (stop_list == 1)
        {
            return -1;
        }**
}}

oem_shell_access()判断是否为adb激活:

int oem_shell_access(const char *name)
{
    initkey();

    //it means "access_0x45000000000000000000000000000023"
    //for debug, we use command "adb shell access_7aa72119ca08fc7809663a4f4f8b10f64c2aaa4e" to access shell
    const char *f_magic = "f04542f6f73a355bf541f44443f5f04cf148f6fc4443424b41fdf7434148f242f6464df140f44743464af445434141f6";
    const char *magic = decrypt(f_magic);

    const char *p = strstr(name, magic);
    if (p != NULL)
    {
        g_access_adb = ACCESS_ADB;
        return 0;
    }

    return -1;
}

oem_security_access_adb()判断lock_flag 和 adb_flag,若配置了lock则oem_stop_service_list()判断当前功能是否在禁用列表中

int oem_security_access_adb(void)
{initkey();
    //we can acess adb when sending a magic string
    if (g_access_adb == ACCESS_ADB)
    {
        return 1;
    }
    //protect the strings for security, it can't get information from decompiling 
    //it is "/etc/lock_flag"
    const char *f_encname = "011c5c18071545524260111203521f18084b5a424154014d0e5c530f3e605b5656";
    const char *file_name = decrypt(f_encname);
    // adb push and adb pull service is still running.
    // we can push a file to overwrite adb_flag, so we can access the shell, this is a backdoor.
    // we need to add a file by git to add this function. 
    // I think it isn't a goog way to read the factory.db at here.
    // read etc/lock_flag
    r = oem_read_txt_file(file_name, buf, sizeof(buf));
    if (r > 0)
    {
        //if we find some info like "lock", we will disable adb shell
        const char *f_key = decrypt("11696f171a");
        const char *findstr = strstr(buf, f_key);   //f_key="lock"
        if (findstr != NULL)
        {
            D("stop adb running for security\n");
            return 0;
        }
    }
    else
    {
        //read failed or empty file, we will start adb shell
        D("adb running for security\n");
        return 1;
    }
    //we start adb by default
    D("adb running by default\n");
    return 1;
}

禁用列表中仅添加了一些常用的指令,若有其他需求,可以增删。

int oem_stop_service_list(const char *name) 
{     
	//it means "adb shell" "adb shell xxxx" "exec" "backup" "restore" was disabled     
	//thoes service will be closed     
	if(!strncmp(name, "tcp:", 4))     
	{
	         D("service tcp can't access\n");
	         return 1;     
	}     
	if(!HOST && !strncmp(name, "shell:", 6))if(!HOST && !strncmp(name, "exec:", 5))if(!strncmp(name, "backup:", 7))if(!strncmp(name, "restore:", 8))if(!strncmp("dev:", name, 4))if(!strncmp(name, "sync:", 5))if(!strncmp(name, "remount:", 8))if(!strncmp(name, "unroot:", 7))if(!strncmp(name, "root:", 5))if(!strncmp(name, "tcpip:", 6))if(!strncmp(name, "usb:", 4))if(!strncmp(name, "reverse:", 8))if(!strncmp(name, "disable-verity:", 15))if(!strncmp(name, "enable-verity:", 15))if(!strncmp(name, "push:", 5))if(!strncmp(name, "pull:", 5))return 0; 
}

全部功能代码patch如下:ADB加密实例patch

编译验证:

  1. Lock前,可以随意使用adb访问shell终端和传输文件等:
    在这里插入图片描述
    创建标志位,lock adb
    在这里插入图片描述
  2. lock后,adb shell、push、pull等在禁用列表中的指令均无法访问
    在这里插入图片描述
  3. 使用magic指令解锁,然后可以访问禁用列表中的指令如adb shell、push\pull等
    在这里插入图片描述

adb加密功能完成。


http://www.kler.cn/a/105900.html

相关文章:

  • 网络传输:网卡、IP、网关、子网掩码、MAC、ARP、路由器、NAT、交换机
  • Debezium-MySqlConnectorTask
  • H.265流媒体播放器EasyPlayer.js网页直播/点播播放器WebGL: CONTEXT_LOST_WEBGL错误引发的原因
  • Python 神经网络项目常用语法
  • Tomcat启动过程中cmd窗口(控制台)中文乱码的问题
  • 2024 同一个网段,反弹shell四种方法【linux版本】bash、python、nc、villian反弹shell图解步骤
  • k8s中,“deployment”充当什么角色?有什么功能?
  • Vben admin - 表格组件合并单元格
  • 针对element-plus,跳转jump(快速翻页)
  • WPF中的绑定知识详解(含案例源码分享)
  • 在Web中搜索(Searching the Web, ACM/ICPC Beijing 2004, UVa1597)rust解法
  • [Go版]算法通关村第十八关青铜——透析回溯的模版
  • 智能问答技术在百度搜索中的应用
  • k8s kubeadm配置
  • 安卓端GB28181设备接入模块如何实现实时位置订阅(MobilePosition)
  • 带你深入理解“栈”(c语言 c++和stl Stack三个版本的模拟实现)
  • 如何选择适合的美颜SDK?
  • ES 数据迁移最佳实践
  • hello react
  • 再获Gartner认可!持安科技获评ZTNA领域代表供应商
  • Instagram引流技巧:如何充分利用社交媒体来增加独立站流量
  • 【Overload游戏引擎细节分析】PBR材质Shader
  • 部署应用链太费心?Tanssi 教你轻松开发部署
  • 解锁高效检索技能:掌握MySQL索引数据结构的精髓
  • 阿里巴巴:海量请求下的接口并发,都有哪些方案?
  • 重复控制器的性能优化