某設備CoAP協議漏洞挖掘實戰
發現看雪等國內安全論壇好像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個資源
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。
udp 0 0 0.0.0.0:5683 0.0.0.0:*
如下,設備實現了基于CoRE 的 Well-Known URI。
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 過程:
import asynciofrom 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 提供了以下資源:
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也 可以推測下對應功能。
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,導致了信息泄露,比較雞肋的一個洞。
...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的值
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
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 的資源;
判斷安全機制是哪種;
判斷是否實現了認證機制;
對請求解析函數進行逆向分析。