CHG: making sure no buffer overflows will occure in ul_send_cmd_raw by adding responseLength parameter to all calls.

CHG: added UL-C configurations details to be printed
This commit is contained in:
iceman1001 2015-05-05 22:15:02 +02:00
commit 8297860e25

View file

@ -102,34 +102,36 @@ static void ul_switch_off_field(void) {
SendCommand(&c); SendCommand(&c);
} }
static int ul_send_cmd_raw( uint8_t *cmd, uint8_t len, uint8_t *response ) { static int ul_send_cmd_raw( uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uint16_t responseLength ) {
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_APPEND_CRC, len, 0}}; UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_APPEND_CRC, cmdlen, 0}};
memcpy(c.d.asBytes, cmd, len); memcpy(c.d.asBytes, cmd, cmdlen);
SendCommand(&c); SendCommand(&c);
UsbCommand resp; UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
uint16_t resplen = (resp.arg[0] < responseLength) ? resp.arg[0] : responseLength;
if (resp.arg[0] > 0) if (resp.arg[0] > 0)
memcpy(response, resp.d.asBytes, resp.arg[0]); memcpy(response, resp.d.asBytes, resplen);
return resp.arg[0]; return resplen;
} }
static int ul_send_cmd_raw_crc( uint8_t *cmd, uint8_t len, uint8_t *response, bool append_crc ) { static int ul_send_cmd_raw_crc( uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uint16_t responseLength, bool append_crc ) {
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT , len, 0}}; UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT , cmdlen, 0}};
if (append_crc) if (append_crc)
c.arg[0] |= ISO14A_APPEND_CRC; c.arg[0] |= ISO14A_APPEND_CRC;
memcpy(c.d.asBytes, cmd, len); memcpy(c.d.asBytes, cmd, cmdlen);
SendCommand(&c); SendCommand(&c);
UsbCommand resp; UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
uint16_t resplen = (resp.arg[0] < responseLength) ? resp.arg[0] : responseLength;
if (resp.arg[0] > 0) if (resp.arg[0] > 0)
memcpy(response, resp.d.asBytes, resp.arg[0]); memcpy(response, resp.d.asBytes, resplen );
return resp.arg[0]; return resplen;
} }
static int ul_select( iso14a_card_select_t *card ){ static int ul_select( iso14a_card_select_t *card ){
@ -149,37 +151,37 @@ static int ul_select( iso14a_card_select_t *card ){
} }
// This read command will at least return 16bytes. // This read command will at least return 16bytes.
static int ul_read( uint8_t page, uint8_t *response ){ static int ul_read( uint8_t page, uint8_t *response, uint16_t responseLength ){
uint8_t cmd[] = {ISO14443A_CMD_READBLOCK, page}; uint8_t cmd[] = {ISO14443A_CMD_READBLOCK, page};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response); int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
if ( len == -1 ) if ( len == -1 )
ul_switch_off_field(); ul_switch_off_field();
return len; return len;
} }
static int ulc_requestAuthentication( uint8_t blockNo, uint8_t *nonce ){ static int ulc_requestAuthentication( uint8_t blockNo, uint8_t *nonce, uint16_t nonceLength ){
uint8_t cmd[] = {MIFARE_ULC_AUTH_1, blockNo}; uint8_t cmd[] = {MIFARE_ULC_AUTH_1, blockNo};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), nonce); int len = ul_send_cmd_raw(cmd, sizeof(cmd), nonce, nonceLength);
if ( len == -1 ) if ( len == -1 )
ul_switch_off_field(); ul_switch_off_field();
return len; return len;
} }
static int ulev1_requestAuthentication( uint8_t *pwd, uint8_t *pack ){ static int ulev1_requestAuthentication( uint8_t *pwd, uint8_t *pack, uint16_t packLength ){
uint8_t cmd[] = {MIFARE_ULEV1_AUTH, pwd[0], pwd[1], pwd[2], pwd[3]}; uint8_t cmd[] = {MIFARE_ULEV1_AUTH, pwd[0], pwd[1], pwd[2], pwd[3]};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), pack); int len = ul_send_cmd_raw(cmd, sizeof(cmd), pack, packLength);
if ( len == -1) if ( len == -1)
ul_switch_off_field(); ul_switch_off_field();
return len; return len;
} }
static int ulev1_getVersion( uint8_t *response ){ static int ulev1_getVersion( uint8_t *response, uint16_t responseLength ){
uint8_t cmd[] = {MIFARE_ULEV1_VERSION}; uint8_t cmd[] = {MIFARE_ULEV1_VERSION};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response); int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
if ( len == -1 ) if ( len == -1 )
ul_switch_off_field(); ul_switch_off_field();
return len; return len;
@ -196,10 +198,10 @@ static int ulev1_getVersion( uint8_t *response ){
// return 0; // return 0;
// } // }
static int ulev1_readCounter( uint8_t counter, uint8_t *response ){ static int ulev1_readCounter( uint8_t counter, uint8_t *response, uint16_t responseLength ){
uint8_t cmd[] = {MIFARE_ULEV1_READ_CNT, counter}; uint8_t cmd[] = {MIFARE_ULEV1_READ_CNT, counter};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response); int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
if (len == -1) if (len == -1)
ul_switch_off_field(); ul_switch_off_field();
return len; return len;
@ -222,14 +224,14 @@ static int ul_print_CC(uint8_t *data) {
} }
static int ul_print_version(uint8_t *data){ static int ul_print_version(uint8_t *data){
PrintAndLog("VERSION COMMAND: %s", sprint_hex(data, 8) ); PrintAndLog("Raw version bytes: %s", sprint_hex(data, 8) );
PrintAndLog(" Vendor ID : 0x%02X, Manufacturer: %s", data[1], getTagInfo(data[1])); PrintAndLog(" Vendor ID : 0x%02X, Manufacturer: %s", data[1], getTagInfo(data[1]));
PrintAndLog(" Product type : %s" , getProductTypeStr(data[2])); PrintAndLog(" Product type : %s" , getProductTypeStr(data[2]));
PrintAndLog("Product subtype : 0x%02X %s" , data[3], (data[3]==1) ?"17 pF":"50pF"); PrintAndLog(" Product subtype : 0x%02X %s" , data[3], (data[3]==1) ?"17 pF":"50pF");
PrintAndLog(" Major version : 0x%02X" , data[4]); PrintAndLog(" Major version : 0x%02X" , data[4]);
PrintAndLog(" Minor version : 0x%02X" , data[5]); PrintAndLog(" Minor version : 0x%02X" , data[5]);
PrintAndLog(" Size : %s", getUlev1CardSizeStr(data[6])); PrintAndLog(" Size : %s", getUlev1CardSizeStr(data[6]));
PrintAndLog(" Protocol type : 0x%02X" , data[7]); PrintAndLog(" Protocol type : 0x%02X" , data[7]);
return 0; return 0;
} }
@ -249,7 +251,7 @@ static int ul_print_type(uint16_t tagtype){
else if ( tagtype & NTAG_216 ) else if ( tagtype & NTAG_216 )
PrintAndLog(" TYPE : MIFARE NTAG 216 888bytes (NT2H1611G0DU)"); PrintAndLog(" TYPE : MIFARE NTAG 216 888bytes (NT2H1611G0DU)");
else else
PrintAndLog(" TYPE : Unknown %x",tagtype); PrintAndLog(" TYPE : Unknown %04x",tagtype);
return 0; return 0;
} }
@ -275,7 +277,7 @@ uint16_t GetHF14AMfU_Type(void){
return UL_ERROR; return UL_ERROR;
} }
len = ulev1_getVersion(version); len = ulev1_getVersion(version, sizeof(version));
switch (len) { switch (len) {
case -1: case -1:
@ -316,15 +318,12 @@ uint16_t GetHF14AMfU_Type(void){
// Magic UL-C, by observation, // Magic UL-C, by observation,
// it seems to have a static nonce response to 0x1A command. // it seems to have a static nonce response to 0x1A command.
status = ul_select(&card); status = ul_select(&card);
status = ulc_requestAuthentication(0, nonce1); status = ulc_requestAuthentication(0, nonce1, sizeof(nonce1));
if ( status > 0 ) { if ( status > 0 ) {
status = ulc_requestAuthentication(0, nonce2);
status = ulc_requestAuthentication(0, nonce2, sizeof(nonce2));
if ( !memcmp(nonce1, nonce2, 11)) { tagtype =( !memcmp(nonce1, nonce2, 11) ) ? UL_C_MAGIC : UL_C;
tagtype = UL_C_MAGIC;
}
else
tagtype = UL_C;
} else { } else {
tagtype = UL; tagtype = UL;
@ -351,7 +350,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
uint8_t *key; uint8_t *key;
int status; int status;
PrintAndLog("\n-- Tag Information ---------"); PrintAndLog("\n--- Tag Information ---------");
PrintAndLog("-------------------------------------------------------------"); PrintAndLog("-------------------------------------------------------------");
TagTypeUL_t tagtype = GetHF14AMfU_Type(); TagTypeUL_t tagtype = GetHF14AMfU_Type();
@ -367,7 +366,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
} }
// read pages 0,1,2,4 (should read 4pages) // read pages 0,1,2,4 (should read 4pages)
status = ul_read(0, data); status = ul_read(0, data, sizeof(data));
if ( status == -1 ){ if ( status == -1 ){
PrintAndLog("Error: tag didn't answer to READ"); PrintAndLog("Error: tag didn't answer to READ");
ul_switch_off_field(); ul_switch_off_field();
@ -395,75 +394,86 @@ int CmdHF14AMfUInfo(const char *Cmd){
else else
PrintAndLog(" BCC1 : 0x%02X - crc should be 0x%02X", data[8], crc1 ); PrintAndLog(" BCC1 : 0x%02X - crc should be 0x%02X", data[8], crc1 );
PrintAndLog(" Internal : %s ", sprint_hex(data + 9, 1)); PrintAndLog(" Internal : 0x%02X - %s", data[9], (data[9]==0x48)?"default":"not default" );
memcpy(datatemp, data+10, 2); memcpy(datatemp, data+10, 2);
PrintAndLog(" Lock : %s - %s", sprint_hex(datatemp, 2),printBits( 2, &datatemp) ); PrintAndLog(" Lock : %s - %s", sprint_hex(datatemp, 2),printBits( 2, &datatemp) );
PrintAndLog("OneTimePad : %s ", sprint_hex(data + 3*4, 4)); PrintAndLog("OneTimePad : %s ", sprint_hex(data + 3*4, 4));
PrintAndLog(""); PrintAndLog("");
if ((tagtype & UL_C)){ if ((tagtype & UL_C)){
PrintAndLog("--- Trying some Ultralight-C stuff");
// read pages 42,43 // read pages 0x28, 0x29, 0x2A, 0x2B
uint8_t ulc_conf[16] = {0x00}; uint8_t ulc_conf[16] = {0x00};
status = ul_read(42, ulc_conf); status = ul_read(0x28, ulc_conf, sizeof(ulc_conf));
if ( status == -1 ){ if ( status == -1 ){
PrintAndLog("Error: tag didn't answer to READ"); PrintAndLog("Error: tag didn't answer to READ");
ul_switch_off_field(); ul_switch_off_field();
return status; return status;
} }
PrintAndLog("read UL-C Configuration bytes at page 42,43"); PrintAndLog("--- UL-C Configuration");
//PrintAndLog(" Lock : %s - %s", sprint_hex(datatemp, 2), printBits( 2, &datatemp) ); PrintAndLog(" Higher Lockbits [40/0x28]: %s %s", sprint_hex(ulc_conf, 4), printBits(2, ulc_conf));
PrintAndLog(" Lock [42]: %s", sprint_hex(ulc_conf, 4) ); PrintAndLog(" Counter [41/0x29]: %s %s", sprint_hex(ulc_conf+4, 4), printBits(2, ulc_conf+4));
PrintAndLog("Config [43]: %s", sprint_hex(ulc_conf+4, 4) );
bool validAuth = (ulc_conf[8] >= 0x03 && ulc_conf[8] <= 0x30);
if ( validAuth )
PrintAndLog(" Auth0 [42/0x2A]: %s - Pages above %d needs authentication", sprint_hex(ulc_conf+8, 4), ulc_conf[8] );
else{
if ( ulc_conf[8] == 0){
PrintAndLog(" Auth0 [42/0x2A]: %s - default", sprint_hex(ulc_conf+8, 4) );
} else {
PrintAndLog(" Auth0 [42/0x2A]: %s - auth byte is out-of-range", sprint_hex(ulc_conf+8, 4) );
}
}
PrintAndLog(" Auth1 [43/0x2B]: %s - %s",
sprint_hex(ulc_conf+12, 4),
(ulc_conf[12] & 1) ? "write access restricted": "read and write access restricted"
);
// if magic, try read passwd?
if ((tagtype & UL_C_MAGIC)){ if ((tagtype & UL_C_MAGIC)){
// read pages 44,45,46,47
uint8_t deskey[16] = {0x00}; uint8_t deskey[16] = {0x00};
status = ul_read(44, deskey); status = ul_read(0x2C, deskey, sizeof(deskey));
if ( status == -1 ){ if ( status == -1 ){
PrintAndLog("Error: tag didn't answer to READ"); PrintAndLog("Error: tag didn't answer to READ");
ul_switch_off_field(); ul_switch_off_field();
return status; return status;
} }
PrintAndLog(" pwd0 [44]: %s", sprint_hex(deskey ,4)); PrintAndLog(" deskey1 [44/0x2C]: %s", sprint_hex(deskey ,4));
PrintAndLog(" pwd1 [45]: %s", sprint_hex(deskey+4 ,4)); PrintAndLog(" deskey1 [45/0x2D]: %s", sprint_hex(deskey+4 ,4));
PrintAndLog(" pwd2 [46]: %s", sprint_hex(deskey+8 ,4)); PrintAndLog(" deskey2 [46/0x2E]: %s", sprint_hex(deskey+8 ,4));
PrintAndLog(" pwd3 [47]: %s", sprint_hex(deskey+12,4)); PrintAndLog(" deskey2 [47/0x2F]: %s", sprint_hex(deskey+12,4));
PrintAndLog(" 3des key : %s", sprint_hex(SwapEndian64(deskey, 16), 16));
} }
else {
PrintAndLog("Trying some default 3des keys"); PrintAndLog("Trying some default 3des keys");
for (uint8_t i = 0; i < 7; ++i ){ for (uint8_t i = 0; i < 7; ++i ){
key = default_3des_keys[i]; key = default_3des_keys[i];
if (try3DesAuthentication(key) == 1){ if (try3DesAuthentication(key) == 1){
PrintAndLog("Found default 3des key: %s", sprint_hex(key,16)); PrintAndLog("Found default 3des key: %s", sprint_hex(key,16));
return 0; return 0;
}
} }
} }
} }
if ((tagtype & (UL_EV1_48 | UL_EV1_128))) { if ((tagtype & (UL_EV1_48 | UL_EV1_128))) {
PrintAndLog("--- UL-EV1 Counters");
uint8_t counter[4] = {0,0,0,0}; uint8_t counter[4] = {0,0,0,0};
ulev1_readCounter(0,counter); for ( uint8_t i = 0; i<3; ++i) {
PrintAndLog("COUNTER: 0 :: %s",sprint_hex(counter,4)); ulev1_readCounter(i,counter, sizeof(counter) );
ulev1_readCounter(1,counter); PrintAndLog("Counter[%d] :: %s", i, sprint_hex(counter,4));
PrintAndLog("COUNTER: 1 :: %s",sprint_hex(counter,4)); }
ulev1_readCounter(2,counter);
PrintAndLog("COUNTER: 2 :: %s",sprint_hex(counter,4));
} }
if ((tagtype & (UL_EV1_48 | UL_EV1_128 | NTAG_213 | NTAG_215 | NTAG_216))) { if ((tagtype & (UL_EV1_48 | UL_EV1_128 | NTAG_213 | NTAG_215 | NTAG_216))) {
PrintAndLog("--- Trying some Ultralight-EV1 / NTAG stuff"); PrintAndLog("\n--- UL-EV1 / NTAG Version");
uint8_t version[10] = {0x00}; uint8_t version[10] = {0x00};
status = ulev1_getVersion(version); status = ulev1_getVersion(version, sizeof(version));
if ( status == -1 ){ if ( status == -1 ){
PrintAndLog("Error: tag didn't answer to GETVERSION"); PrintAndLog("Error: tag didn't answer to GETVERSION");
ul_switch_off_field(); ul_switch_off_field();
@ -473,11 +483,11 @@ int CmdHF14AMfUInfo(const char *Cmd){
//********** TODO ******************************** //********** TODO ********************************
// --problem, there is a failed pwd tries counter in UL-EV1 // --problem, there is a failed pwd tries counter in UL-EV1
PrintAndLog("Trying some known EV1/NTAG passwords."); PrintAndLog("\nTrying some known EV1/NTAG passwords.");
uint8_t password[4] ={0xff,0xff,0xff,0xff}; uint8_t password[4] ={0xff,0xff,0xff,0xff};
uint8_t pack[4] = {0,0,0,0}; uint8_t pack[4] = {0,0,0,0};
status = ulev1_requestAuthentication(password, pack); status = ulev1_requestAuthentication(password, pack, sizeof(pack));
if ( status == -1 ){ if ( status == -1 ){
PrintAndLog("Error: tag didn't answer to AUTHENTICATE"); PrintAndLog("Error: tag didn't answer to AUTHENTICATE");
ul_switch_off_field(); ul_switch_off_field();
@ -489,9 +499,9 @@ int CmdHF14AMfUInfo(const char *Cmd){
if ((tagtype & (NTAG_213 | NTAG_215 | NTAG_216))){ if ((tagtype & (NTAG_213 | NTAG_215 | NTAG_216))){
PrintAndLog("--- Trying some NTAG stuff"); PrintAndLog("\n--- NTAG NDEF Message");
uint8_t cc[16] = {0x00}; uint8_t cc[16] = {0x00};
status = ul_read(2, cc); status = ul_read(2, cc, sizeof(cc));
if ( status == -1 ){ if ( status == -1 ){
PrintAndLog("Error: tag didn't answer to READ"); PrintAndLog("Error: tag didn't answer to READ");
ul_switch_off_field(); ul_switch_off_field();