-
-
[原创] 某设备CoAP协议漏洞挖掘实战
-
发表于: 2022-8-9 21:13 20842
-
发现看雪等国内安全论坛好像CoAP协议相关内容很少,以及CVE中基本也是CoAP协议库存在的漏洞,所以将最近对某设备CoAP漏洞挖掘的相关分析写一下。
CoAP可以简单的当做基于UDP协议的轻量化HTTP协议。
协议栈:
Constrained RESTful Environments (CoRE)
CoAP Resource Discovery 机制
例: CoAP server 提供了2个资源
安全机制
CoAP 有四种安全机制: NoSec, PreSharedKey ,RawPublicKey,Certificate, 但是只有NoSec和RawPublicKey是强制实现的。
CoAP 本身没有实现认证和授权机制,而是通过 communication security(IPsec,DTLS)和object security 来完成。
安全考虑
CoAP协议默认端口为5683或5684,端口为5683时的安全机制为NoSec, 5684则是开启了DTLS。看了下设备端口开启的5683。
如下,设备实现了基于CoRE 的 Well-Known URI
所以可以直接进行 Resourse Discovery 过程:
可以看到,CoAPserver 提供了以下资源
逆向对应二进制看到的代码实现,对应的函数名和URI也 可以推测下对应功能。
剩下的就是对这些函数进行进一步漏洞挖掘了。
挖掘成果:
coapsync_handler函数会将设备SSID,Pwd等参数返回给client,导致了信息泄露,比较鸡肋的一个洞。
Url
字段数据导致的命令注入。
recv_cmdfile_handler会调用到cmdupgrade_parse。
最终会调用函数do_upgrade
, 而Url
字段数据会拼接到system执行的命令中,达成未授权RCE.
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
REQ: GET coap:
/
/
server:port
/
.well
-
known
/
core
RES:
2.05
Content
<
/
sensors
/
temp>;
if
=
"sensor"
,
<
/
sensors
/
light>;
if
=
"sensor"
REQ: GET coap:
/
/
server:port
/
.well
-
known
/
core
RES:
2.05
Content
<
/
sensors
/
temp>;
if
=
"sensor"
,
<
/
sensors
/
light>;
if
=
"sensor"
udp
0
0
0.0
.
0.0
:
5683
0.0
.
0.0
:
*
udp
0
0
0.0
.
0.0
:
5683
0.0
.
0.0
:
*
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);
}
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);
}
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())
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())
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
'
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
'
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
;
}
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
;
}
...
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);
...
...
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);
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!