首页
论坛
课程
招聘
[原创] 某设备CoAP协议漏洞挖掘实战
2022-8-9 21:13 8524

[原创] 某设备CoAP协议漏洞挖掘实战

2022-8-9 21:13
8524

前言

发现看雪等国内安全论坛好像CoAP协议相关内容很少,以及CVE中基本也是CoAP协议库存在的漏洞,所以将最近对某设备CoAP漏洞挖掘的相关分析写一下。

CoAP原理简要介绍(具体可以看rfc文档)

CoAP可以简单的当做基于UDP协议的轻量化HTTP协议。

  • 协议栈:

  • Constrained RESTful Environments (CoRE)

    • 基于REST
    • 应用于受限节点和网络
    • 帮助client对server进行Resource Discovery
  • CoAP Resource Discovery 机制

    • 基于CoRE
    • 使用/.well-known/core 作为 Well-Known URI, 详见 rfc8615
    • 例: CoAP server 提供了2个资源

      1
      2
      3
      4
      5
      6
      REQ: GET coap://server:port/.well-known/core
       
      RES:
        2.05 Content
        </sensors/temp>;if="sensor",
        </sensors/light>;if="sensor"
  • 安全机制

    CoAP 有四种安全机制: NoSec, PreSharedKey ,RawPublicKey,Certificate, 但是只有NoSec和RawPublicKey是强制实现的。

    • NoSec: no protocol-level security (DTLS is disabled)
    • PreSharedKey: DTLS is enabled. 基于pre-shared keys进行认证。
    • Certificate: DTLS is enabled. 基于具有X.509证书的非对称密钥进行认证。
    • RawPublicKey: DTLS is enabled. 基于 raw public key进行认证。

    CoAP 本身没有实现认证和授权机制,而是通过 communication security(IPsec,DTLS)和object security 来完成。

  • 安全考虑

    • 协议解析和URI的处理
      • 传入数据包的处理逻辑可能存在漏洞
    • 代理和缓存
      • 代理会破坏IPsec或DTLS的保护
    • 反射攻击
      • 由于UDP协议无法验证源地址导致的反射攻击
      • 关于这个有一些相关的报告
        • https://www.netscout.com/blog/asert/coap-attacks-wild
        • https://anquan.baidu.com/article/807
    • IP地址欺骗攻击
      • 发送伪造的ACK等消息
    • Cross-Protocol Attacks
      • 通过伪造源地址,导致绕过防火墙规则达成的攻击

实战

CoAP协议默认端口为5683或5684,端口为5683时的安全机制为NoSec, 5684则是开启了DTLS。看了下设备端口开启的5683。

1
udp        0      0 0.0.0.0:5683            0.0.0.0:*

如下,设备实现了基于CoRE 的 Well-Known URI

1
2
3
4
5
if ( *((_BYTE *)v21->hdr + 1) == 1 && !memcmp(key, &unk_A0DC, 4u) )
{
  coap_log_impl(7, "create default response for %s\n", ".well-known/core");
  v22 = wellknown_response(context, node->pdu);
}

所以可以直接进行 Resourse Discovery 过程:

1
2
3
4
5
6
7
8
9
10
import asyncio
from aiocoap import *
 
async def main():
    protocol = await Context.create_client_context()
    msg = Message(code=GET, uri="coap://192.168.1.1:5683/.well-known/core")
    response = await protocol.request(msg).response
    print(response.payload)
 
asyncio.run(main())

可以看到,CoAPserver 提供了以下资源

1
2
3
4
5
b'</>;title="General Info";ct=0,
...
</device/inform/boot>;title=device/inform/boot,</device/inform/syncreq>;title=device/inform/syncreq,</device/inform/off>;title=device/inform/off,</device/inform/hb>;title=device/inform/hb,</device/inform/data>;title=device/inform/data,
</device/cmd/file>;title=device/cmd/file
</async>;ct=0'

逆向对应二进制看到的代码实现,对应的函数名和URI也 可以推测下对应功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void *__fastcall start_coap_server_thread(void *a1)
{
 pthread_t v1; // $v0
 v1 = pthread_self();
 pthread_detach(v1);
 ...
 registerCoapMethod("device/inform/boot", coapboot_handler)
 registerCoapMethod("device/inform/syncreq", coapsync_handler)
 registerCoapMethod("device/inform/off", coapoff_handler)
 registerCoapMethod("device/inform/hb", coaphb_handler )
 registerCoapMethod("device/inform/data", coapdata_handler)
 registerCoadMethod("device/cmd/url", coapdata_url_handler)
 ...
 startCoapService("0.0.0.0", 5683);
 return 0;
}

剩下的就是对这些函数进行进一步漏洞挖掘了。

 

挖掘成果:

  1. coapsync_handler函数会将设备SSID,Pwd等参数返回给client,导致了信息泄露,比较鸡肋的一个洞。

    1
    2
    3
    4
    5
    6
    7
    ...
    cJSON_AddItemToObject(v73, "SSID", v13);
    v14 = cJSON_CreateString(&v83[136]);
    cJSON_AddItemToObject(v73, "SecurityMode", v14);
    v15 = cJSON_CreateString(&v83[72]);
    cJSON_AddItemToObject(v73, "Pwd", v15);
    ...

  2. Url字段数据导致的命令注入。

    recv_cmdfile_handler会调用到cmdupgrade_parse。

    • cmdupgrade_parse会从post的cjson数据中解析出Url的值
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    v17 = cJSON_GetObjectItem(v9, "Url");
        v18 = v17;
        if ( v17 )
        {
          v19 = *(const char **)(v17 + 16);
          v20 = 0;
          if ( v19 )
          {
            v21 = strlen(v19);
            v20 = malloc(v21 + 1);
            v22 = strlen(*(const char **)(v18 + 16));
            memset(v20, 0, v22 + 1);
            strcpy((char *)v20, *(const char **)(v18 + 16));
          }

    最终会调用函数do_upgrade, 而Url字段数据会拼接到system执行的命令中,达成未授权RCE.

    • do_upgrade
    1
    2
    3
    4
    5
    6
    7
    8
    int __fastcall do_upgrade(const char *Url){
    ...
      if ( !strcmp((const char *)v35, "XXXX-XXXXXX") )
        snprintf(cmd, 0x180u, "curl %s -o %s%s -k", Url, "/var/tmp/", uri);
      else
        snprintf(cmd, 0x180u, "wget -q -P %s %s", "/var/tmp/", Url);
      system(cmd);
    }

一些相关工具

  • cotopaxi

    https://github.com/Samsung/cotopaxi

  • libcoap,aiocoap等 coap 协议实现库

攻击路径

判断是否可以进行resource discovry 操作获取CoAP server 的资源

 

判断安全机制是哪种

 

判断是否实现了认证机制

 

对请求解析函数进行逆向分析

引用

https://tools.ietf.org/html/rfc8615

 

https://datatracker.ietf.org/doc/html/rfc6690

 

https://en.wikipedia.org/wiki/Constrained_Application_Protocol

 

https://datatracker.ietf.org/doc/html/rfc7252

 

https://datatracker.ietf.org/doc/html/rfc5785


[2022冬季班]《安卓高级研修班(网课)》月薪三万班招生中~

最后于 2022-8-9 21:15 被风亦映寒编辑 ,原因: 错字
收藏
点赞2
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回